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

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Wed May 6 18:56:51 CEST 2009


Author: mattm
Date: 2009-05-06 18:56:49 +0200 (Wed, 06 May 2009)
New Revision: 3263

Added:
   trunk/openvas-manager/src/tasks_fs.h
   trunk/openvas-manager/src/tasks_sql.h
Modified:
   trunk/openvas-manager/ChangeLog
   trunk/openvas-manager/src/CMakeLists.txt
   trunk/openvas-manager/src/manage.c
   trunk/openvas-manager/src/manage.h
   trunk/openvas-manager/src/omp.c
   trunk/openvas-manager/src/openvasmd.c
   trunk/openvas-manager/src/otp.c
Log:
	Switch to an embedded database for task storage, keeping file
	system based storage as an alternative.

	* src/tasks_fs.h: New file.

	* src/manage.c: Include tasks file according to TASKS_FS.  Move all
	code specific to the task representation to tasks_fs.h
	(report_task): Move the return to a parameter and return an error status.
	Adjust all callers.
	(print_tasks): Make comment and description const.
	(create_report_file, start_task, stop_task): Use task functions for
	accessing and incrementing values, instead of working with the task
	member.

	* src/tasks_sql.h: New file which implements database equivalents of
	the code moved to tasks_fs.h.

	* src/manage.h (init_manage, cleanup_manage, task_comment): New headers.
	(task_t, task_iterator_t): Add defininitions for database tasks.
	(report_task): Update header.
	(task_name, task_description, task_start_time, task_end_time)
	(task_attack_state): Make returns const.

	* src/omp.c: Always cast the NULL task.
	(init_omp_data): Call init_manage.

	* src/otp.c: Always cast the NULL task.

	* src/openvasmd.c (cleanup): Call cleanup_manage.

	* src/CMakeLists.txt (TASKS_CFLAG, TASKS_LDFLAG): New variables for
	controlling task backend.  Add to targets.
	(C_FILES): Add task include files.


Modified: trunk/openvas-manager/ChangeLog
===================================================================
--- trunk/openvas-manager/ChangeLog	2009-05-06 12:58:15 UTC (rev 3262)
+++ trunk/openvas-manager/ChangeLog	2009-05-06 16:56:49 UTC (rev 3263)
@@ -1,5 +1,41 @@
 2009-04-16  Matthew Mundell <matt at mundell.ukfsn.org>
 
+	Switch to an embedded database for task storage, keeping file
+	system based storage as an alternative.
+
+	* src/tasks_fs.h: New file.
+
+	* src/manage.c: Include tasks file according to TASKS_FS.  Move all
+	code specific to the task representation to tasks_fs.h
+	(report_task): Move the return to a parameter and return an error status.
+	Adjust all callers.
+	(print_tasks): Make comment and description const.
+	(create_report_file, start_task, stop_task): Use task functions for
+	accessing and incrementing values, instead of working with the task
+	member.
+
+	* src/tasks_sql.h: New file which implements database equivalents of
+	the code moved to tasks_fs.h.
+
+	* src/manage.h (init_manage, cleanup_manage, task_comment): New headers.
+	(task_t, task_iterator_t): Add defininitions for database tasks.
+	(report_task): Update header.
+	(task_name, task_description, task_start_time, task_end_time)
+	(task_attack_state): Make returns const.
+
+	* src/omp.c: Always cast the NULL task.
+	(init_omp_data): Call init_manage.
+
+	* src/otp.c: Always cast the NULL task.
+
+	* src/openvasmd.c (cleanup): Call cleanup_manage.
+
+	* src/CMakeLists.txt (TASKS_CFLAG, TASKS_LDFLAG): New variables for
+	controlling task backend.  Add to targets.
+	(C_FILES): Add task include files.
+
+2009-04-16  Matthew Mundell <matt at mundell.ukfsn.org>
+
 	Improve the task abstraction by moving parsing of the task ID into
 	find_task.  Separate out task code specific to the task representation.
 

Modified: trunk/openvas-manager/src/CMakeLists.txt
===================================================================
--- trunk/openvas-manager/src/CMakeLists.txt	2009-05-06 12:58:15 UTC (rev 3262)
+++ trunk/openvas-manager/src/CMakeLists.txt	2009-05-06 16:56:49 UTC (rev 3263)
@@ -24,6 +24,10 @@
 
 ## Config
 
+#set (TASKS_CFLAG "-DTASKS_FS")
+set (TASKS_CFLAG "-DTASKS_SQL")
+set (TASKS_LDFLAG "-lsqlite3")
+
 exec_program (pkg-config
               ARGS --cflags glib-2.0
 			  OUTPUT_VARIABLE GLIB_CFLAGS)
@@ -45,13 +49,13 @@
 set_target_properties (ovas-mngr-comm PROPERTIES COMPILE_FLAGS "${GLIB_CFLAGS}")
 
 add_library (manage manage.c)
-set_target_properties (manage PROPERTIES COMPILE_FLAGS "${GLIB_CFLAGS}")
+set_target_properties (manage PROPERTIES COMPILE_FLAGS "${TASKS_CFLAG} ${GLIB_CFLAGS}")
 
 add_library (omp omp.c)
-set_target_properties (omp PROPERTIES COMPILE_FLAGS "${GLIB_CFLAGS}")
+set_target_properties (omp PROPERTIES COMPILE_FLAGS "${TASKS_CFLAG} ${GLIB_CFLAGS}")
 
 add_library (otp otp.c)
-set_target_properties (otp PROPERTIES COMPILE_FLAGS "${GLIB_CFLAGS}")
+set_target_properties (otp PROPERTIES COMPILE_FLAGS "${TASKS_CFLAG} ${GLIB_CFLAGS}")
 
 ## Program
 
@@ -99,7 +103,7 @@
 endif (OPENVAS_LIB_INSTALL_DIR)
 
 set_target_properties (openvasmd PROPERTIES LINK_FLAGS
-                       "${TEMP} -lpcap -unessus_get_socket_from_connection -lopenvas -lgnutls -lossp-uuid ${GLIB_LDFLAGS}")
+                       "${TEMP} -lpcap -unessus_get_socket_from_connection -lopenvas -lgnutls -lossp-uuid ${GLIB_LDFLAGS} ${TASKS_LDFLAG}")
 
 if (OPENVAS_HEADER_INSTALL_DIR)
   set (TEMP "-I${OPENVAS_HEADER_INSTALL_DIR}")
@@ -108,7 +112,7 @@
 endif (OPENVAS_HEADER_INSTALL_DIR)
 
 set_target_properties (openvasmd PROPERTIES COMPILE_FLAGS
-                       "${TEMP} ${OPENVAS_CFLAGS} ${GLIB_CFLAGS}")
+                       "${TASKS_CFLAG} ${TEMP} ${OPENVAS_CFLAGS} ${GLIB_CFLAGS}")
 
 MARK_AS_ADVANCED (TEMP)
 
@@ -144,7 +148,8 @@
 ## Tag files
 
 set (C_FILES "openvasmd.c" "otpd.c" "ompd.c" "omp.c" "otp.c" "file.c"
-             "manage.c" "ovas-mngr-comm.c" "string.c")
+             "manage.c" "ovas-mngr-comm.c" "string.c" "tasks_fs.h"
+			 "tasks_sql.h")
 add_custom_target (etags COMMENT "Building TAGS..."
                    COMMAND etags ${C_FILES})
 add_custom_target (ctags COMMENT "Building tags..."

Modified: trunk/openvas-manager/src/manage.c
===================================================================
--- trunk/openvas-manager/src/manage.c	2009-05-06 12:58:15 UTC (rev 3262)
+++ trunk/openvas-manager/src/manage.c	2009-05-06 16:56:49 UTC (rev 3263)
@@ -67,6 +67,15 @@
 #endif
 
 
+/* Functions defined in task_*.h and used before the include. */
+
+void
+inc_task_report_count (task_t task);
+
+void
+dec_task_report_count (task_t task);
+
+
 /* Credentials. */
 
 /**
@@ -126,20 +135,6 @@
   append_text (&credentials->password, text, length);
 }
 
-/**
- * @brief Authenticate credentials.
- *
- * @param[in]  credentials  Credentials.
- *
- * @return 1 if credentials are authentic, else 0.
- */
-int
-authenticate (credentials_t credentials)
-{
-  if (credentials.username) return 1;
-  return 0;
-}
-
 
 /* Reports. */
 
@@ -248,12 +243,13 @@
 /**
  * @brief Get the task associated with a report.
  *
- * @param[in]  report_id  ID of report.
+ * @param[in]   report_id  ID of report.
+ * @param[out]  task       The task return.
  *
- * @return Pointer to task on success, else NULL.
+ * @return TRUE on error, else FALSE.
  */
-task_t
-report_task (const char* report_id)
+gboolean
+report_task (const char* report_id, task_t* task_return)
 {
   if (current_credentials.username)
     {
@@ -278,20 +274,30 @@
                        error->message);
               g_error_free (error);
               g_free (report_path);
-              return NULL;
+              return TRUE;
             }
-          gchar* task_name = report_path_task_name (report_path);
-          task_t task;
-          int err = find_task (task_name, &task);
-          g_free (report_path);
-          g_free (task_name);
-          if (err) return NULL;
-          return task;
+          {
+            gchar* task_name = report_path_task_name (report_path);
+            task_t task;
+            int err = find_task (task_name, &task);
+            g_free (report_path);
+            g_free (task_name);
+            if (err)
+              {
+                fprintf (stderr, "Failed to find task %s.\n", task_name);
+                return TRUE;
+              }
+            *task_return = task;
+            return FALSE;
+          }
         }
       else
-        g_free (link_name);
+        {
+          fprintf (stderr, "Failed to access %s.\n", link_name);
+          g_free (link_name);
+        }
     }
-  return NULL;
+  return TRUE;
 }
 
 /**
@@ -307,9 +313,10 @@
 delete_report (const char* report_id)
 {
   gchar* link_name;
-  task_t task = report_task (report_id);
-  if (task == NULL) return -1;
+  task_t task;
 
+  if (report_task (report_id, &task)) return -1;
+
   if (current_credentials.username == NULL) return -5;
 
   link_name = g_build_filename (PREFIX
@@ -358,12 +365,13 @@
                      strerror (errno));
           g_free (name);
           g_free (link_name);
-          task->report_count--;
+          dec_task_report_count (task);
           return 0;
         }
     }
   else
     {
+      fprintf (stderr, "Failed to access %s.\n", link_name);
       g_free (link_name);
       return -2;
     }
@@ -424,7 +432,7 @@
 /**
  * @brief The task currently running on the server.
  */
-/*@null@*/ task_t current_server_task = NULL;
+/*@null@*/ task_t current_server_task = (task_t) NULL;
 
 /**
  * @brief Report stream of the current task.
@@ -440,1241 +448,12 @@
 static void
 print_tasks ();
 
-/**
- * @brief Reallocation increment for the tasks array.
- */
-#define TASKS_INCREMENT 1024
-
-/**
- * @brief The array of all the tasks of the current user.
- */
-task_t tasks = NULL;
-
-/**
- * @brief The size of the \ref tasks array.
- */
-unsigned int tasks_size = 0;
-
-/**
- * @brief The number of defined tasks.
- */
-unsigned int num_tasks = 0;
-
-/**
- * @brief Return the number of tasks associated with the current user.
- *
- * @return The number of tasks associated with the current user.
- */
-unsigned int
-task_count ()
-{
-  return num_tasks;
-}
-
-/**
- * @brief Initialise a task iterator.
- *
- * @param[in]  iterator  Task iterator.
- */
-void
-init_task_iterator (task_iterator_t* iterator)
-{
-  iterator->index = tasks;
-  iterator->end = tasks + tasks_size;
-}
-
-/**
- * @brief Read the next task from an iterator.
- *
- * @param[in]   iterator  Task iterator.
- * @param[out]  task      Task.
- *
- * @return TRUE if there was a next task, else FALSE.
- */
-gboolean
-next_task (task_iterator_t* iterator, task_t* task)
-{
-  while (1)
-    {
-      if (iterator->index == iterator->end) return FALSE;
-      if (iterator->index->name) break;
-      iterator->index++;
-    }
-  if (task) *task = iterator->index;
-  iterator->index++;
-  return TRUE;
-}
-
-/**
- * @brief Return the identifier of a task.
- *
- * @param[in]  task  Task.
- *
- * @return ID of task.
- */
-unsigned int
-task_id (task_t task)
-{
-  return task->id;
-}
-
-/**
- * @brief Return a string version of the ID of a task.
- *
- * @param[in]   task  Task.
- * @param[out]  id    Pointer to a string.  On successful return contains a
- *                    pointer to a static buffer with the task ID as a string.
- *                    The static buffer is overwritten across successive calls.
- *
- * @return 0 success, -1 error.
- */
-int
-task_id_string (task_t task, const char ** id)
-{
-  static char buffer[11]; /* (expt 2 32) => 4294967296 */
-  int length = snprintf (buffer, 11, "%010u", task->id);
-  assert (length < 11);
-  if (length < 1 || length > 10)
-    {
-      *id = NULL;
-      return -1;
-    }
-  *id = buffer;
-  return 0;
-}
-
-/**
- * @brief Return the name of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Task name.
- */
-char*
-task_name (task_t task)
-{
-  return task->name;
-}
-
-/**
- * @brief Return the comment of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Task comment.
- */
-char*
-task_comment (task_t task)
-{
-  return task->comment;
-}
-
-/**
- * @brief Return the description of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Description of task.
- */
-char*
-task_description (task_t task)
-{
-  return task->description;
-}
-
-/**
- * @brief Set the description of a task.
- *
- * @param[in]  task         Task.
- * @param[in]  description  Description.  Used directly, freed by free_task.
- */
-void
-set_task_description (task_t task, char* description, gsize length)
-{
-  if (task->description) free (task->description);
-  task->description = description;
-  task->description_length = length;
-  task->description_size = length;
-}
-
-/**
- * @brief Return the run state of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Task run status.
- */
-task_status_t
-task_run_status (task_t task)
-{
-  return task->run_status;
-}
-
-/**
- * @brief Set the run state of a task.
- *
- * @param[in]  task    Task.
- * @param[in]  status  New run status.
- *
- */
-void
-set_task_run_status (task_t task, task_status_t status)
-{
-  task->run_status = status;
-}
-
-/**
- * @brief Return the most recent start time of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Task start time.
- */
-char*
-task_start_time (task_t task)
-{
-  return task->start_time;
-}
-
-/**
- * @brief Set the start time of a task.
- *
- * @param[in]  task  Task.
- * @param[in]  time  New time.  Used directly, freed by free_task.
- */
-void
-set_task_start_time (task_t task, char* time)
-{
-  if (task->start_time) free (task->start_time);
-  task->start_time = time;
-}
-
-/**
- * @brief Return the most recent end time of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Task end time.
- */
-char*
-task_end_time (task_t task)
-{
-  return task->end_time;
-}
-
-/**
- * @brief Set the end time of a task.
- *
- * @param[in]  task  Task.
- * @param[in]  time  New time.  Used directly, freed by free_task.
- */
-void
-set_task_end_time (task_t task, char* time)
-{
-  if (task->end_time) free (task->end_time);
-  task->end_time = time;
-}
-
-/**
- * @brief Return the number of reports associated with a task.
- *
- * @param[in]  task  Task.
- *
- * @return Number of reports.
- */
-unsigned int
-task_report_count (task_t task)
-{
-  return task->report_count;
-}
-
-/**
- * @brief Return the attack state of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Task attack state.
- */
-char*
-task_attack_state (task_t task)
-{
-  return task->attack_state;
-}
-
-/**
- * @brief Set the attack state of a task.
- *
- * @param[in]  task   Task.
- * @param[in]  state  New state.
- */
-void
-set_task_attack_state (task_t task, char* state)
-{
-  if (task->attack_state) free (task->attack_state);
-  task->attack_state = state;
-}
-
-/**
- * @brief Return the number of debug messages in the current report of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Number of debug messages.
- */
-int
-task_debugs_size (task_t task)
-{
-  return task->debugs_size;
-}
-
-/**
- * @brief Increment number of debug messages in the current report of a task.
- *
- * @param[in]  task  Task.
- */
-void
-inc_task_debugs_size (task_t task)
-{
-  task->debugs_size++;
-}
-
-/**
- * @brief Return the number of hole messages in the current report of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Number of hole messages.
- */
-int
-task_holes_size (task_t task)
-{
-  return task->holes_size;
-}
-
-/**
- * @brief Increment number of hole messages in the current report of a task.
- *
- * @param[in]  task  Task.
- */
-void
-inc_task_holes_size (task_t task)
-{
-  task->holes_size++;
-}
-
-/**
- * @brief Return the number of info messages in the current report of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Number of info messages.
- */
-int
-task_infos_size (task_t task)
-{
-  return task->infos_size;
-}
-
-/**
- * @brief Increment number of info messages in the current report of a task.
- *
- * @param[in]  task  Task.
- */
-void
-inc_task_infos_size (task_t task)
-{
-  task->infos_size++;
-}
-
-/**
- * @brief Return the number of log messages in the current report of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Number of log messages.
- */
-int
-task_logs_size (task_t task)
-{
-  return task->logs_size;
-}
-
-/**
- * @brief Increment number of log messages in the current report of a task.
- *
- * @param[in]  task  Task.
- */
-void
-inc_task_logs_size (task_t task)
-{
-  task->logs_size++;
-}
-
-/**
- * @brief Return the number of note messages in the current report of a task.
- *
- * @param[in]  task  Task.
- *
- * @return Number of note messages.
- */
-int
-task_notes_size (task_t task)
-{
-  return task->notes_size;
-}
-
-/**
- * @brief Increment number of note messages in the current report of a task.
- *
- * @param[in]  task  Task.
- */
-void
-inc_task_notes_size (task_t task)
-{
-  task->notes_size++;
-}
-
-/**
- * @brief Grow the array of tasks.
- *
- * @return TRUE on success, FALSE on error (out of memory).
- */
-static gboolean
-grow_tasks ()
-{
-  task_t new;
-  tracef ("   task_t size: %i\n", (int) sizeof (fs_task_t));
-/*@-compdestroy@*/
-/*@-sharedtrans@*/
-  /* RATS: ignore *//* Memory cleared below. */
-  new = realloc (tasks,
-                 (tasks_size + TASKS_INCREMENT) * sizeof (fs_task_t));
-/*@=sharedtrans@*/
-/*@=compdestroy@*/
-/*@-globstate@*/
-  if (new == NULL) return FALSE;
-/*@=globstate@*/
-  tasks = new;
-
-  /* Clear the new part of the memory. */
-  new = tasks + tasks_size;
-  memset (new, 0, TASKS_INCREMENT * sizeof (fs_task_t));
-
-  tasks_size += TASKS_INCREMENT;
-  tracef ("   tasks grown to %u\n", tasks_size);
-#if TRACE
-  print_tasks ();
+#ifdef TASKS_FS
+#include "tasks_fs.h"
+#else
+#include "tasks_sql.h"
 #endif
-  return TRUE;
-}
 
-/**
- * @brief Free a task.
- *
- * Free all the members of a task.
- *
- * @param[in]  task  The task to free.
- */
-static void
-free_task (/*@special@*/ /*@dependent@*/ task_t task)
-  /*@ensures isnull task->name@*/
-  /*@releases task->comment, task->open_ports@*/
-{
-  tracef ("   Freeing task %u: \"%s\" %s (%i) %.*s[...]\n\n",
-          task->id,
-          task->name,
-          task->comment,
-          (int) task->description_length,
-          (task->description_length > 20) ? 20 : task->description_length,
-          task->description ? task->description : "(null)");
-  free (task->name);
-  task->name = NULL;
-  free (task->comment);
-  if (task->description) free (task->description);
-  if (task->start_time) free (task->start_time);
-  if (task->end_time) free (task->end_time);
-  if (task->attack_state) free (task->attack_state);
-  if (current_report)
-    {
-      (void) fclose (current_report); // FIX check for error
-      current_report = NULL;
-    }
-  if (task->open_ports) (void) g_array_free (task->open_ports, TRUE);
-}
-
-/**
- * @brief Free all tasks and the array of tasks.
- */
-void
-free_tasks ()
-{
-  if (tasks == NULL) return;
-
-  {
-    task_t index = tasks;
-    task_t end = tasks + tasks_size;
-    while (index < end)
-      {
-        /* This indicates that the state of the task depends on which
-         * branch of the `if' is taken. */
-        /*@-branchstate@*/
-        if (index->name) free_task (index);
-        /*@=branchstate@*/
-        index++;
-      }
-    tasks_size = 0;
-    free (tasks);
-    tasks = NULL;
-  }
-}
-
-/**
- * @brief Make a task.
- *
- * The char* parameters name and comment are used directly and freed
- * when the task is freed.
- *
- * @param[in]  name     The name of the task.
- * @param[in]  time     The period of the task, in seconds.
- * @param[in]  comment  A comment associated the task.
- *
- * @return A pointer to the new task or NULL when out of memory (in which
- *         case caller must free name and comment).
- */
-task_t
-make_task (char* name, unsigned int time, char* comment)
-{
-  task_t index;
-  task_t end;
-  tracef ("   make_task %s %u %s\n", name, time, comment);
-  if (tasks == NULL && grow_tasks () == FALSE)
-    {
-      g_free (name);
-      g_free (comment);
-      return NULL;
-    }
-  if (tasks == NULL) abort ();
-  index = tasks;
-  end = tasks + tasks_size;
-  while (1)
-    {
-      while (index < end)
-        {
-          if (index->name == NULL)
-            {
-              index->id = (unsigned int) (index - tasks);
-              index->name = name;
-              index->time = time;
-              /* The annotation is because these are all freed with name. */
-              /*@-mustfreeonly@*/
-              index->comment = comment;
-              index->description = NULL;
-              index->description_size = 0;
-              index->run_status = TASK_STATUS_NEW;
-              index->start_time = NULL;
-              index->end_time = NULL;
-              index->report_count = 0;
-              index->attack_state = NULL;
-              index->open_ports = NULL;
-              /*@=mustfreeonly@*/
-              tracef ("   Made task %u at %p\n", index->id, index);
-              num_tasks++;
-              return index;
-            }
-          index++;
-        }
-      index = (task_t) tasks_size;
-      /* grow_tasks updates tasks_size. */
-      if (grow_tasks ())
-        {
-          g_free (name);
-          g_free (comment);
-          return NULL;
-        }
-      index = index + (int) tasks;
-    }
-}
-
-typedef /*@only@*/ struct dirent * only_dirent_pointer;
-
-static void
-load_tasks_free (/*@only@*/ gchar* dir_name, /*@only@*/ gchar* file_name,
-                 int index, int count, /*@only@*/ only_dirent_pointer* names)
-{
-  g_free (dir_name);
-  g_free (file_name);
-  for (; index < count; index++) free (names[index]);
-  free (names);
-  free_tasks ();
-}
-
-/**
- * @brief Load the tasks from disk.
- *
- * @return 0 success, -1 error.
- */
-int
-load_tasks ()
-{
-  GError* error;
-  gchar* dir_name;
-  gchar* file_name;
-  struct dirent ** names = NULL;
-  int count, index;
-
-  if (tasks) return -1;
-
-  if (current_credentials.username == NULL) return -1;
-
-  tracef ("   Loading tasks...\n");
-
-  error = NULL;
-  dir_name = g_build_filename (PREFIX
-                               "/var/lib/openvas/mgr/users/",
-                               current_credentials.username,
-                               "tasks",
-                               NULL);
-
-  count = scandir (dir_name, &names, NULL, alphasort);
-  if (count < 0 || names == NULL)
-    {
-      if (errno == ENOENT)
-        {
-          free (dir_name);
-          tracef ("   Loading tasks... done\n");
-          return 0;
-        }
-      fprintf (stderr, "Failed to open dir %s: %s\n",
-               dir_name,
-               strerror (errno));
-      g_free (dir_name);
-      return -1;
-    }
-
-  file_name = NULL;
-  for (index = 0; index < count; index++)
-    {
-      gchar *name, *comment, *description;
-      unsigned int time;
-      /*@dependent@*/ const char* task_name = names[index]->d_name;
-      task_t task;
-      gboolean success;
-
-      if (task_name[0] == '.')
-        {
-          free (names[index]);
-          continue;
-        }
-
-      tracef ("     %s\n", task_name);
-
-      file_name = g_build_filename (dir_name, task_name, "name", NULL);
-      success = g_file_get_contents (file_name, &name, NULL, &error);
-      if (success == FALSE)
-        {
-          if (error)
-            {
-              fprintf (stderr, "Failed to get contents of %s: %s\n",
-                       file_name,
-                       error->message);
-              g_error_free (error);
-            }
-          load_tasks_free (dir_name, file_name, index, count, names);
-          return -1;
-        }
-
-      g_free (file_name);
-      file_name = g_build_filename (dir_name, task_name, "time", NULL);
-      success = g_file_get_contents (file_name, &comment, NULL, &error);
-      if (success == FALSE)
-        {
-          g_free (name);
-          if (error)
-            {
-              fprintf (stderr, "Failed to get contents of %s: %s\n",
-                       file_name,
-                       error->message);
-              g_error_free (error);
-            }
-          load_tasks_free (dir_name, file_name, index, count, names);
-          return -1;
-        }
-      if (sscanf (comment, "%u", &time) != 1)
-        {
-          fprintf (stderr, "Failed to scan time: %s\n", comment);
-          g_free (comment);
-          g_free (name);
-          if (error) g_error_free (error);
-          load_tasks_free (dir_name, file_name, index, count, names);
-          return -1;
-        }
-      g_free (comment);
-
-      g_free (file_name);
-      file_name = g_build_filename (dir_name, task_name, "comment", NULL);
-      comment = NULL;
-      success = g_file_get_contents (file_name, &comment, NULL, &error);
-      if (success == FALSE)
-        {
-          g_free (name);
-          if (error)
-            {
-              fprintf (stderr, "Failed to get contents of %s: %s\n",
-                       file_name,
-                       error->message);
-              g_error_free (error);
-            }
-          load_tasks_free (dir_name, file_name, index, count, names);
-          return -1;
-        }
-      g_free (file_name);
-
-      task = make_task (name, time, comment);
-      if (task == NULL)
-        {
-          g_free (dir_name);
-          for (; index < count; index++) free (names[index]);
-          free (names);
-          free_tasks ();
-          return -1;
-        }
-      /* name and comment are freed with the new task. */
-
-      {
-        gsize description_length;
-
-        file_name = g_build_filename (dir_name, task_name, "description", NULL);
-        success = g_file_get_contents (file_name,
-                                       &description,
-                                       &description_length,
-                                       &error);
-        if (success == FALSE)
-          {
-            if (error)
-              {
-                fprintf (stderr, "Failed to get contents of %s: %s\n",
-                         file_name,
-                         error->message);
-                g_error_free (error);
-              }
-            load_tasks_free (dir_name, file_name, index, count, names);
-            return -1;
-          }
-
-        task->description = description;
-        task->description_size = task->description_length = description_length;
-      }
-
-      g_free (file_name);
-      file_name = g_build_filename (dir_name, task_name, "report_count", NULL);
-      comment = NULL;
-      success = g_file_get_contents (file_name, &comment, NULL, &error);
-      if (success == FALSE)
-        {
-          if (error)
-            {
-              fprintf (stderr, "Failed to get contents of %s: %s\n",
-                       file_name,
-                       error->message);
-              g_error_free (error);
-            }
-          load_tasks_free (dir_name, file_name, index, count, names);
-          return -1;
-        }
-      if (sscanf (comment, "%u", &task->report_count) != 1)
-        {
-          fprintf (stderr, "Failed to scan report count: %s\n", comment);
-          if (error) g_error_free (error);
-          load_tasks_free (dir_name, file_name, index, count, names);
-          return -1;
-        }
-
-      g_free (file_name);
-      free (names[index]);
-    }
-
-  g_free (dir_name);
-  free (names);
-
-  tracef ("   Loading tasks... done\n");
-  return 0;
-}
-
-static void
-save_task_error (/*@only@*/ gchar* file_name, /*@only@*/ GError* error)
-{
-  if (error)
-    {
-      fprintf (stderr, "Failed to set contents of %s: %s\n",
-               file_name,
-               error->message);
-      g_error_free (error);
-    }
-  g_free (file_name);
-}
-
-/**
- * @brief Save a task to a directory.
- *
- * Save a task to a given directory, ensuring that the directory exists
- * before saving the task.
- *
- * @param[in]  task      The task.
- * @param[in]  dir_name  The directory.
- *
- * @return 0 success, -1 error.
- */
-static int
-save_task (task_t task, gchar* dir_name)
-{
-  gboolean success;
-  gchar* file_name;
-  GError* error = NULL;
-
-  /* Ensure directory exists. */
-
-  if (g_mkdir_with_parents (dir_name, 33216 /* -rwx------ */) == -1)
-    {
-      fprintf (stderr, "Failed to create task dir %s: %s\n",
-               dir_name,
-               strerror (errno));
-      return -1;
-    }
-
-  /* Save each component of the task. */
-
-  file_name = g_build_filename (dir_name, "name", NULL);
-
-  success = g_file_set_contents (file_name, task->name, -1, &error);
-  if (success == FALSE)
-    {
-      save_task_error (file_name, error);
-      return -1;
-    }
-  g_free (file_name);
-
-  file_name = g_build_filename (dir_name, "comment", NULL);
-  success = g_file_set_contents (file_name, task->comment, -1, &error);
-  if (success == FALSE)
-    {
-      save_task_error (file_name, error);
-      return -1;
-    }
-  g_free (file_name);
-
-  file_name = g_build_filename (dir_name, "description", NULL);
-  if (task->description == NULL)
-    success = g_file_set_contents (file_name, "", 0, &error);
-  else
-    success = g_file_set_contents (file_name,
-                                   task->description,
-                                   task->description_length,
-                                   &error);
-  if (success == FALSE)
-    {
-      save_task_error (file_name, error);
-      return -1;
-    }
-  g_free (file_name);
-
-  file_name = g_build_filename (dir_name, "time", NULL);
-  {
-    static char buffer[11]; /* (expt 2 32) => 4294967296 */
-    int length = snprintf (buffer, 11, "%u", task->time);
-    assert (length < 11);
-
-    if (length < 1 || length > 10)
-      {
-        save_task_error (file_name, error);
-        return -1;
-      }
-    success = g_file_set_contents (file_name, buffer, -1, &error);
-    if (success == FALSE)
-      {
-        save_task_error (file_name, error);
-        return -1;
-      }
-    g_free (file_name);
-
-    file_name = g_build_filename (dir_name, "report_count", NULL);
-    length = snprintf (buffer, 11, "%u", task->report_count);
-    assert (length < 11);
-    if (length < 1 || length > 10)
-      {
-        save_task_error (file_name, error);
-        return -1;
-      }
-    success = g_file_set_contents (file_name, buffer, -1, &error);
-    if (success == FALSE)
-      {
-        save_task_error (file_name, error);
-        return -1;
-      }
-  }
-  g_free (file_name);
-
-  return 0;
-}
-
-/**
- * @brief Save all tasks to disk.
- *
- * @return 0 success, -1 error.
- */
-int
-save_tasks ()
-{
-  gchar* dir_name;
-  task_t index;
-  task_t end;
-
-  if (tasks == NULL) return 0;
-  if (current_credentials.username == NULL) return -1;
-
-  tracef ("   Saving tasks...\n");
-
-  // FIX Could check if up to date already.
-
-  dir_name = g_build_filename (PREFIX
-                               "/var/lib/openvas/mgr/users/",
-                               current_credentials.username,
-                               "tasks",
-                               NULL);
-
-  /* Write each task in the tasks array to disk. */
-
-  index = tasks;
-  end = tasks + tasks_size;
-  while (index < end)
-    {
-      if (index->name)
-        {
-          const char* id;
-          gchar* file_name;
-          tracef ("     %u\n", index->id);
-
-          if (task_id_string (index, &id))
-            {
-              g_free (dir_name);
-              return -1;
-            }
-
-          file_name = g_build_filename (dir_name,
-                                        id,
-                                        NULL);
-          if (save_task (index, file_name))
-            {
-              g_free (dir_name);
-              g_free (file_name);
-              return -1;
-            }
-          g_free (file_name);
-        }
-      index++;
-    }
-
-  g_free (dir_name);
-  tracef ("   Saving tasks... done.\n");
-  return 0;
-}
-
-/**
- * @brief Find a task from a task identifier string.
- *
- * @param[in]   id_string  A task identifier string.
- * @param[out]  task       The task, if found.
- *
- * @return 0 if task found, else -1.
- */
-int
-find_task (const char* id_string, task_t* task)
-{
-  if (tasks)
-    {
-      unsigned int id;
-
-      if (sscanf (id_string, "%u", &id) == 1)
-        {
-          task_t index = tasks;
-          task_t end = tasks + tasks_size;
-          while (index < end)
-            {
-              if (index->name) tracef ("   %u vs %u\n", index->id, id);
-
-              if (index->name == NULL)
-                index++;
-              else if (index->id == id)
-                {
-                  tracef ("Found task %s at %p\n", id_string, index);
-                  *task = index;
-                  return 0;
-                }
-              else
-                index++;
-            }
-        }
-    }
-  return -1;
-}
-
-/**
- * @brief Set a task parameter.
- *
- * The "value" parameter is used directly and freed either immediately or
- * when the task is freed.
- *
- * @param[in]  task       A pointer to a task.
- * @param[in]  parameter  The name of the parameter (in any case): TASK_FILE,
- *                        IDENTIFIER or COMMENT.
- * @param[in]  value      The value of the parameter, in base64 if parameter
- *                        is "TASK_FILE".
- *
- * @return 0 on success, -1 when out of memory, -2 if parameter name error,
- *         -3 value error (NULL).
- */
-int
-set_task_parameter (task_t task, const char* parameter, /*@only@*/ char* value)
-{
-  tracef ("   set_task_parameter %u %s\n",
-          task->id,
-          parameter ? parameter : "(null)");
-  if (value == NULL) return -3;
-  if (parameter == NULL)
-    {
-      free (value);
-      return -2;
-    }
-  if (strncasecmp ("TASK_FILE", parameter, 9) == 0)
-    {
-      gsize out_len;
-      guchar* out;
-      out = g_base64_decode (value, &out_len);
-      free (value);
-      if (task->description) free (task->description);
-      task->description = (char*) out;
-      task->description_length = task->description_size = out_len;
-    }
-  else if (strncasecmp ("NAME", parameter, 4) == 0)
-    {
-      free (task->name);
-      task->name = value;
-    }
-  else if (strncasecmp ("COMMENT", parameter, 7) == 0)
-    {
-      free (task->comment);
-      task->comment = value;
-    }
-  else
-    {
-      free (value);
-      return -2;
-    }
-  return 0;
-}
-
-/**
- * @brief Delete a task.
- *
- * Stop the task beforehand with \ref stop_task, if it is running.
- *
- * @param[in]  task  A pointer to the task.
- *
- * @return 0 on success, -1 if out of space in \ref to_server buffer.
- */
-int
-delete_task (task_t* task_pointer)
-{
-  gboolean success;
-  const char* id;
-  gchar* name;
-  GError* error;
-  task_t task = *task_pointer;
-
-  tracef ("   delete task %u\n", task->id);
-
-  if (task_id_string (task, &id)) return -1;
-
-  if (current_credentials.username == NULL) return -1;
-
-  if (stop_task (task) == -1) return -1;
-
-  // FIX may be atomic problems here
-
-  if (delete_reports (task)) return -1;
-
-  name = g_build_filename (PREFIX
-                           "/var/lib/openvas/mgr/users/",
-                           current_credentials.username,
-                           "tasks",
-                           id,
-                           NULL);
-  error = NULL;
-  success = rmdir_recursively (name, &error);
-  if (success == FALSE)
-    {
-      if (error)
-        {
-          fprintf (stderr, "Failed to remove task dir %s: %s\n",
-                   name,
-                   error->message);
-          g_error_free (error);
-        }
-      g_free (name);
-      return -1;
-    }
-  g_free (name);
-
-  free_task (task);
-  *task_pointer = NULL;
-
-  return 0;
-}
-
-/**
- * @brief Append text to the comment associated with a task.
- *
- * @param[in]  task    A pointer to the task.
- * @param[in]  text    The text to append.
- * @param[in]  length  Length of the text.
- *
- * @return 0 on success, -1 if out of memory.
- */
-int
-append_to_task_comment (task_t task, const char* text, /*@unused@*/ int length)
-{
-  char* new;
-  if (task->comment)
-    {
-      // FIX
-      new = g_strconcat (task->comment, text, NULL);
-      free (task->comment);
-      task->comment = new;
-      return 0;
-    }
-  new = strdup (text);
-  if (new == NULL) return -1;
-  task->comment = new;
-  return 0;
-}
-
-/**
- * @brief Append text to the identifier associated with a task.
- *
- * @param[in]  task    A pointer to the task.
- * @param[in]  text    The text to append.
- * @param[in]  length  Length of the text.
- *
- * @return 0 on success, -1 if out of memory.
- */
-int
-append_to_task_identifier (task_t task, const char* text,
-                           /*@unused@*/ int length)
-{
-  char* new;
-  if (task->name)
-    {
-      new = g_strconcat (task->name, text, NULL);
-      g_free (task->name);
-      task->name = new;
-      return 0;
-    }
-  new = strdup (text);
-  if (new == NULL) return -1;
-  task->name = new;
-  return 0;
-}
-
-/**
- * @brief Reallocation increment for a task description.
- */
-#define DESCRIPTION_INCREMENT 4096
-
-/**
- * @brief Increase the memory allocated for a task description.
- *
- * @param[in]  task       A pointer to the task.
- * @param[in]  increment  Minimum number of bytes to increase memory.
- *
- * @return 0 on success, -1 if out of memory.
- */
-static int
-grow_description (task_t task, size_t increment)
-{
-  size_t new_size = task->description_size
-                    + (increment < DESCRIPTION_INCREMENT
-                       ? DESCRIPTION_INCREMENT : increment);
-  /* RATS: ignore *//* Memory cleared below. */
-  char* new = realloc (task->description, new_size);
-  if (new == NULL) return -1;
-  memset (new, (int) '\0', new_size - task->description_size);
-  task->description = new;
-  task->description_size = new_size;
-  return 0;
-}
-
-/**
- * @brief Add a line to a task description.
- *
- * @param[in]  task         A pointer to the task.
- * @param[in]  line         The line.
- * @param[in]  line_length  The length of the line.
- */
-int
-add_task_description_line (task_t task, const char* line, size_t line_length)
-{
-  char* description;
-  if (task->description_size - task->description_length < line_length
-      && grow_description (task, line_length) < 0)
-    return -1;
-  description = task->description;
-  description += task->description_length;
-  strncpy (description, line, line_length);
-  task->description_length += line_length;
-  return 0;
-}
-
-/**
- * @brief Set the ports of a task.
- *
- * @param[in]  task     The task.
- * @param[in]  current  New value for port currently being scanned.
- * @param[in]  max      New value for last port to be scanned.
- */
-void
-set_task_ports (task_t task, unsigned int current, unsigned int max)
-{
-  task->current_port = current;
-  task->max_port = max;
-}
-
-/**
- * @brief Add an open port to a task.
- *
- * @param[in]  task       The task.
- * @param[in]  number     The port number.
- * @param[in]  protocol   The port protocol.
- */
-void
-append_task_open_port (task_t task, unsigned int number, char* protocol)
-{
-  assert (task->open_ports != NULL);
-  if (task->open_ports)
-    {
-      port_t port;
-
-      port.number = number;
-      if (strncasecmp ("udp", protocol, 3) == 0)
-        port.protocol = PORT_PROTOCOL_UDP;
-      else if (strncasecmp ("tcp", protocol, 3) == 0)
-        port.protocol = PORT_PROTOCOL_TCP;
-      else
-        port.protocol = PORT_PROTOCOL_OTHER;
-
-      (void) g_array_append_val (task->open_ports, port);
-      task->open_ports_size++;
-    }
-}
-
 
 /* General task facilities. */
 
@@ -1693,8 +472,8 @@
     {
       do
         {
-          char* comment = task_comment (index);
-          char* description = task_description (index);
+          const char* comment = task_comment (index);
+          const char* description = task_description (index);
           tracef ("   Task %u: \"%s\" %s\n%s\n\n",
                   task_id (index),
                   task_name (index),
@@ -1733,7 +512,8 @@
   assert (current_report == NULL);
   if (current_report) return -6;
 
-  tracef ("   Saving report (%s) on task %u\n", task->start_time, task->id);
+  tracef ("   Saving report (%s) on task %u\n",
+          task_start_time (task), task_id (task));
 
   if (task_id_string (task, &id)) return -2;
 
@@ -1819,7 +599,7 @@
     }
 
   current_report = file;
-  task->report_count++;
+  inc_task_report_count (task);
 
   g_free (dir_name);
   g_free (name);
@@ -1839,12 +619,13 @@
 int
 start_task (task_t task)
 {
-  tracef ("   start task %u\n", task->id);
+  tracef ("   start task %u\n", task_id (task));
 
   // FIX atomic
 
-  if (task->run_status == TASK_STATUS_REQUESTED
-      || task->run_status == TASK_STATUS_RUNNING)
+  task_status_t run_status = task_run_status (task);
+  if (run_status == TASK_STATUS_REQUESTED
+      || run_status == TASK_STATUS_RUNNING)
     return 0;
 
   /* Create the report file. */
@@ -1890,11 +671,15 @@
     return -1;
 #endif
 
-  task->run_status = TASK_STATUS_REQUESTED;
+  set_task_run_status (task, TASK_STATUS_REQUESTED);
 
+#if TASKS_FS
   if (task->open_ports) (void) g_array_free (task->open_ports, TRUE);
   task->open_ports = g_array_new (FALSE, FALSE, (guint) sizeof (port_t));
   task->open_ports_size = 0;
+#else
+  // FIX
+#endif
 
   current_server_task = task;
 
@@ -1914,15 +699,16 @@
 int
 stop_task (task_t task)
 {
-  tracef ("   stop task %u\n", task->id);
-  if (task->run_status == TASK_STATUS_REQUESTED
-      || task->run_status == TASK_STATUS_RUNNING)
+  tracef ("   stop task %u\n", task_id (task));
+  task_status_t run_status = task_run_status (task);
+  if (run_status == TASK_STATUS_REQUESTED
+      || run_status == TASK_STATUS_RUNNING)
     {
       // FIX dik
       if (send_to_server ("CLIENT <|> STOP_ATTACK <|> dik <|> CLIENT\n"))
         return -1;
       // FIX TASK_STATUS_STOP_REQUESTED?
-      task->run_status = TASK_STATUS_DONE;
+      set_task_run_status (task, TASK_STATUS_DONE);
     }
   return 0;
 }

Modified: trunk/openvas-manager/src/manage.h
===================================================================
--- trunk/openvas-manager/src/manage.h	2009-05-06 12:58:15 UTC (rev 3262)
+++ trunk/openvas-manager/src/manage.h	2009-05-06 16:56:49 UTC (rev 3263)
@@ -30,6 +30,12 @@
 #include <glib.h>
 #include <ossp/uuid.h>
 
+void
+init_manage ();
+
+void
+cleanup_manage ();
+
 
 /* Credentials. */
 
@@ -99,6 +105,7 @@
   TASK_STATUS_DONE
 } task_status_t;
 
+#ifdef TASKS_FS
 /**
  * @brief A task.
  */
@@ -132,14 +139,24 @@
 } fs_task_t;
 
 typedef fs_task_t* task_t;
-//typedef long long int task_t;
 
 typedef struct
 {
   task_t index;
   task_t end;
 } task_iterator_t;
+#else
+typedef long long int task_t;
 
+#include <sqlite3.h>
+
+typedef struct
+{
+  sqlite3_stmt* stmt;
+  gboolean done;
+} task_iterator_t;
+#endif
+
 
 /* Task global variables. */
 
@@ -168,10 +185,13 @@
 int
 task_id_string (task_t, /*@out@*/ const char **);
 
-char*
+const char*
 task_name (task_t);
 
-char*
+const char*
+task_comment (task_t);
+
+const char*
 task_description (task_t);
 
 void
@@ -183,13 +203,13 @@
 void
 set_task_run_status (task_t, task_status_t);
 
-char*
+const char*
 task_start_time (task_t);
 
 void
 set_task_start_time (task_t task, char* time);
 
-char*
+const char*
 task_end_time (task_t);
 
 void
@@ -198,7 +218,7 @@
 unsigned int
 task_report_count (task_t);
 
-char*
+const char*
 task_attack_state (task_t);
 
 void
@@ -299,9 +319,8 @@
 gchar*
 report_path_task_name (gchar*);
 
-/*@shared@*/ /*@null@*/
-task_t
-report_task (const char*);
+gboolean
+report_task (const char*, task_t* task);
 /*@=exportlocal@*/
 
 int

Modified: trunk/openvas-manager/src/omp.c
===================================================================
--- trunk/openvas-manager/src/omp.c	2009-05-06 12:58:15 UTC (rev 3262)
+++ trunk/openvas-manager/src/omp.c	2009-05-06 16:56:49 UTC (rev 3263)
@@ -76,7 +76,7 @@
  * @brief Current client task during OMP commands like NEW_TASK and MODIFY_TASK.
  */
 /*@null@*/ /*@dependent@*/
-static task_t current_client_task = NULL;
+static task_t current_client_task = (task_t) NULL;
 
 /**
  * @brief Task ID during OMP MODIFY_TASK and START_TASK.
@@ -299,9 +299,9 @@
           set_client_state (CLIENT_MODIFY_TASK);
         else if (strncasecmp ("NEW_TASK", element_name, 8) == 0)
           {
-            assert (current_client_task == NULL);
+            assert (current_client_task == (task_t) NULL);
             current_client_task = make_task (NULL, 0, NULL);
-            if (current_client_task == NULL) abort (); // FIX
+            if (current_client_task == (task_t) NULL) abort (); // FIX
             set_client_state (CLIENT_NEW_TASK);
           }
         else if (strncasecmp ("OMP_VERSION", element_name, 11) == 0)
@@ -948,7 +948,7 @@
       case CLIENT_ABORT_TASK:
         if (current_task_task_id)
           {
-            assert (current_client_task == NULL);
+            assert (current_client_task == (task_t) NULL);
             task_t task;
             if (find_task (current_task_task_id, &task))
               SEND_TO_CLIENT_OR_FAIL ("<abort_task_response>"
@@ -1281,7 +1281,7 @@
       case CLIENT_DELETE_TASK:
         if (current_task_task_id)
           {
-            assert (current_client_task == NULL);
+            assert (current_client_task == (task_t) NULL);
             task_t task;
             if (find_task (current_task_task_id, &task))
               SEND_TO_CLIENT_OR_FAIL ("<delete_task_response>"
@@ -1366,7 +1366,7 @@
       case CLIENT_MODIFY_TASK:
         if (current_task_task_id)
           {
-            assert (current_client_task == NULL);
+            assert (current_client_task == (task_t) NULL);
             task_t task;
             if (find_task (current_task_task_id, &task))
               SEND_TO_CLIENT_OR_FAIL ("<modify_task_response>"
@@ -1418,7 +1418,7 @@
         {
           gchar* msg;
           assert (strncasecmp ("NEW_TASK", element_name, 7) == 0);
-          assert (current_client_task != NULL);
+          assert (current_client_task != (task_t) NULL);
           // FIX if all rqrd fields given then ok, else respond fail
           // FIX only here should the task be added to tasks
           //       eg on err half task could be saved (or saved with base64 file)
@@ -1434,7 +1434,7 @@
               return;
             }
           g_free (msg);
-          current_client_task = NULL;
+          current_client_task = (task_t) NULL;
           set_client_state (CLIENT_AUTHENTIC);
           break;
         }
@@ -1462,7 +1462,7 @@
       case CLIENT_START_TASK:
         if (current_task_task_id)
           {
-            assert (current_client_task == NULL);
+            assert (current_client_task == (task_t) NULL);
             task_t task;
             if (find_task (current_task_task_id, &task))
               SEND_TO_CLIENT_OR_FAIL ("<start_task_response>"
@@ -1696,11 +1696,13 @@
 /**
  * @brief Initialise OMP library data.
  *
- * This should run once, before the first call to \ref process_omp_client_input.
+ * This should run once per process, before the first call to \ref
+ * process_omp_client_input.
  */
 void
 init_omp_data ()
 {
+  init_manage ();
   /* Create the XML parser. */
   xml_parser.start_element = omp_xml_handle_start_element;
   xml_parser.end_element = omp_xml_handle_end_element;

Modified: trunk/openvas-manager/src/openvasmd.c
===================================================================
--- trunk/openvas-manager/src/openvasmd.c	2009-05-06 12:58:15 UTC (rev 3262)
+++ trunk/openvas-manager/src/openvasmd.c	2009-05-06 16:56:49 UTC (rev 3263)
@@ -538,6 +538,8 @@
 cleanup ()
 {
   tracef ("   Cleaning up.\n");
+  // FIX should be via omp, maybe cleanup_omp ();
+  cleanup_manage ();
   if (manager_socket > -1) close (manager_socket);
 #if LOG
   if (fclose (log_stream)) perror ("Failed to close log stream");

Modified: trunk/openvas-manager/src/otp.c
===================================================================
--- trunk/openvas-manager/src/otp.c	2009-05-06 12:58:15 UTC (rev 3262)
+++ trunk/openvas-manager/src/otp.c	2009-05-06 16:56:49 UTC (rev 3263)
@@ -1228,7 +1228,8 @@
                 }
               case SERVER_DEBUG_OID:
                 {
-                  if (current_message != NULL && current_server_task != NULL)
+                  if (current_message != NULL
+                      && current_server_task != (task_t) NULL)
                     {
                       char* oid = g_strdup (field);
                       set_message_oid (current_message, oid);
@@ -1295,7 +1296,8 @@
                 }
               case SERVER_HOLE_OID:
                 {
-                  if (current_message != NULL && current_server_task != NULL)
+                  if (current_message != NULL
+                      && current_server_task != (task_t) NULL)
                     {
                       char* oid = g_strdup (field);
                       set_message_oid (current_message, oid);
@@ -1362,7 +1364,8 @@
                 }
               case SERVER_INFO_OID:
                 {
-                  if (current_message != NULL && current_server_task != NULL)
+                  if (current_message != NULL
+                      && current_server_task != (task_t) NULL)
                     {
                       char* oid = g_strdup (field);
                       set_message_oid (current_message, oid);
@@ -1429,7 +1432,8 @@
                 }
               case SERVER_LOG_OID:
                 {
-                  if (current_message != NULL && current_server_task != NULL)
+                  if (current_message != NULL
+                      && current_server_task != (task_t) NULL)
                     {
                       char* oid = g_strdup (field);
                       set_message_oid (current_message, oid);
@@ -1496,7 +1500,8 @@
                 }
               case SERVER_NOTE_OID:
                 {
-                  if (current_message != NULL && current_server_task != NULL)
+                  if (current_message != NULL
+                      && current_server_task != (task_t) NULL)
                     {
                       char* oid = g_strdup (field);
                       set_message_oid (current_message, oid);
@@ -1857,7 +1862,7 @@
                                         field);
                     }
                   if (save_report (current_server_task)) return -1;
-                  current_server_task = NULL;
+                  current_server_task = (task_t) NULL;
                   set_server_state (SERVER_DONE);
                   switch (parse_server_done (&messages))
                     {

Added: trunk/openvas-manager/src/tasks_fs.h
===================================================================
--- trunk/openvas-manager/src/tasks_fs.h	2009-05-06 12:58:15 UTC (rev 3262)
+++ trunk/openvas-manager/src/tasks_fs.h	2009-05-06 16:56:49 UTC (rev 3263)
@@ -0,0 +1,1336 @@
+/* OpenVAS Manager
+ * $Id$
+ * Description: Manager Manage library: file system based tasks.
+ *
+ * Authors:
+ * Matthew Mundell <matt at mundell.ukfsn.org>
+ *
+ * Copyright:
+ * Copyright (C) 2009 Greenbone Networks GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or, at your option, any later version as published by the Free
+ * Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+/* Variables. */
+
+/**
+ * @brief Reallocation increment for the tasks array.
+ */
+#define TASKS_INCREMENT 1024
+
+/**
+ * @brief The array of all the tasks of the current user.
+ */
+task_t tasks = NULL;
+
+/**
+ * @brief The size of the \ref tasks array.
+ */
+unsigned int tasks_size = 0;
+
+/**
+ * @brief The number of defined tasks.
+ */
+unsigned int num_tasks = 0;
+
+
+/* Functions. */
+
+/**
+ * @brief Initialize the manage library.
+ */
+void
+init_manage ()
+{
+  /* Empty. */
+}
+
+/**
+ * @brief Cleanup the manage library.
+ */
+void
+cleanup_manage ()
+{
+  /* Empty. */
+}
+
+/**
+ * @brief Authenticate credentials.
+ *
+ * @param[in]  credentials  Credentials.
+ *
+ * @return 1 if credentials are authentic, else 0.
+ */
+int
+authenticate (credentials_t credentials)
+{
+  if (credentials.username) return 1;
+  return 0;
+}
+
+/**
+ * @brief Return the number of tasks associated with the current user.
+ *
+ * @return The number of tasks associated with the current user.
+ */
+unsigned int
+task_count ()
+{
+  return num_tasks;
+}
+
+/**
+ * @brief Initialise a task iterator.
+ *
+ * @param[in]  iterator  Task iterator.
+ */
+void
+init_task_iterator (task_iterator_t* iterator)
+{
+  iterator->index = tasks;
+  iterator->end = tasks + tasks_size;
+}
+
+/**
+ * @brief Read the next task from an iterator.
+ *
+ * @param[in]   iterator  Task iterator.
+ * @param[out]  task      Task.
+ *
+ * @return TRUE if there was a next task, else FALSE.
+ */
+gboolean
+next_task (task_iterator_t* iterator, task_t* task)
+{
+  while (1)
+    {
+      if (iterator->index == iterator->end) return FALSE;
+      if (iterator->index->name) break;
+      iterator->index++;
+    }
+  if (task) *task = iterator->index;
+  iterator->index++;
+  return TRUE;
+}
+
+/**
+ * @brief Return the identifier of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return ID of task.
+ */
+unsigned int
+task_id (task_t task)
+{
+  return task->id;
+}
+
+/**
+ * @brief Return a string version of the ID of a task.
+ *
+ * @param[in]   task  Task.
+ * @param[out]  id    Pointer to a string.  On successful return contains a
+ *                    pointer to a static buffer with the task ID as a string.
+ *                    The static buffer is overwritten across successive calls.
+ *
+ * @return 0 success, -1 error.
+ */
+int
+task_id_string (task_t task, const char ** id)
+{
+  static char buffer[11]; /* (expt 2 32) => 4294967296 */
+  int length = snprintf (buffer, 11, "%010u", task->id);
+  assert (length < 11);
+  if (length < 1 || length > 10)
+    {
+      *id = NULL;
+      return -1;
+    }
+  *id = buffer;
+  return 0;
+}
+
+/**
+ * @brief Return the name of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task name.
+ */
+const char*
+task_name (task_t task)
+{
+  return task->name;
+}
+
+/**
+ * @brief Return the description of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Description of task.
+ */
+char*
+task_description (task_t task)
+{
+  return task->description;
+}
+
+/**
+ * @brief Set the description of a task.
+ *
+ * @param[in]  task         Task.
+ * @param[in]  description  Description.  Used directly, freed by free_task.
+ */
+void
+set_task_description (task_t task, char* description, gsize length)
+{
+  if (task->description) free (task->description);
+  task->description = description;
+  task->description_length = length;
+  task->description_size = length;
+}
+
+/**
+ * @brief Return the run state of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task run status.
+ */
+task_status_t
+task_run_status (task_t task)
+{
+  return task->run_status;
+}
+
+/**
+ * @brief Set the run state of a task.
+ *
+ * @param[in]  task    Task.
+ * @param[in]  status  New run status.
+ *
+ */
+void
+set_task_run_status (task_t task, task_status_t status)
+{
+  task->run_status = status;
+}
+
+/**
+ * @brief Return the most recent start time of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task start time.
+ */
+char*
+task_start_time (task_t task)
+{
+  return task->start_time;
+}
+
+/**
+ * @brief Set the start time of a task.
+ *
+ * @param[in]  task  Task.
+ * @param[in]  time  New time.  Used directly, freed by free_task.
+ */
+void
+set_task_start_time (task_t task, char* time)
+{
+  if (task->start_time) free (task->start_time);
+  task->start_time = time;
+}
+
+/**
+ * @brief Return the most recent end time of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task end time.
+ */
+char*
+task_end_time (task_t task)
+{
+  return task->end_time;
+}
+
+/**
+ * @brief Set the end time of a task.
+ *
+ * @param[in]  task  Task.
+ * @param[in]  time  New time.  Used directly, freed by free_task.
+ */
+void
+set_task_end_time (task_t task, char* time)
+{
+  if (task->end_time) free (task->end_time);
+  task->end_time = time;
+}
+
+/**
+ * @brief Return the number of reports associated with a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of reports.
+ */
+unsigned int
+task_report_count (task_t task)
+{
+  return task->report_count;
+}
+
+/**
+ * @brief Return the attack state of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task attack state.
+ */
+char*
+task_attack_state (task_t task)
+{
+  return task->attack_state;
+}
+
+/**
+ * @brief Set the attack state of a task.
+ *
+ * @param[in]  task   Task.
+ * @param[in]  state  New state.
+ */
+void
+set_task_attack_state (task_t task, char* state)
+{
+  if (task->attack_state) free (task->attack_state);
+  task->attack_state = state;
+}
+
+/**
+ * @brief Return the number of debug messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of debug messages.
+ */
+int
+task_debugs_size (task_t task)
+{
+  return task->debugs_size;
+}
+
+/**
+ * @brief Increment number of debug messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_debugs_size (task_t task)
+{
+  task->debugs_size++;
+}
+
+/**
+ * @brief Return the number of hole messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of hole messages.
+ */
+int
+task_holes_size (task_t task)
+{
+  return task->holes_size;
+}
+
+/**
+ * @brief Increment number of hole messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_holes_size (task_t task)
+{
+  task->holes_size++;
+}
+
+/**
+ * @brief Return the number of info messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of info messages.
+ */
+int
+task_infos_size (task_t task)
+{
+  return task->infos_size;
+}
+
+/**
+ * @brief Increment number of info messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_infos_size (task_t task)
+{
+  task->infos_size++;
+}
+
+/**
+ * @brief Return the number of log messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of log messages.
+ */
+int
+task_logs_size (task_t task)
+{
+  return task->logs_size;
+}
+
+/**
+ * @brief Increment number of log messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_logs_size (task_t task)
+{
+  task->logs_size++;
+}
+
+/**
+ * @brief Return the number of note messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of note messages.
+ */
+int
+task_notes_size (task_t task)
+{
+  return task->notes_size;
+}
+
+/**
+ * @brief Increment number of note messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_notes_size (task_t task)
+{
+  task->notes_size++;
+}
+
+/**
+ * @brief Increment report count.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_report_count (task_t task)
+{
+  task->report_count++;
+}
+
+/**
+ * @brief Decrement report count.
+ *
+ * @param[in]  task  Task.
+ */
+void
+dec_task_report_count (task_t task)
+{
+  task->report_count--;
+}
+
+#if 0
+#if TRACE
+/**
+ * @brief Print the server tasks.
+ */
+static void
+print_tasks ()
+{
+  task_t index = tasks;
+
+  if (index == NULL)
+    tracef ("   Task array still to be created.\n\n");
+  else
+    {
+      tracef ("   tasks: %p\n", tasks);
+      tracef ("   tasks end: %p\n", tasks + tasks_size);
+      while (index < tasks + tasks_size)
+        {
+          //tracef ("   index: %p\n", index);
+          if (index->name)
+            {
+              tracef ("   Task %u: \"%s\" %s\n%s\n\n",
+                      index->id,
+                      index->name,
+                      index->comment ? index->comment : "",
+                      index->description ? index->description : "");
+            }
+          index++;
+        }
+    }
+}
+#endif
+#endif
+
+/**
+ * @brief Grow the array of tasks.
+ *
+ * @return TRUE on success, FALSE on error (out of memory).
+ */
+static gboolean
+grow_tasks ()
+{
+  task_t new;
+  tracef ("   task_t size: %i\n", (int) sizeof (fs_task_t));
+/*@-compdestroy@*/
+/*@-sharedtrans@*/
+  /* RATS: ignore *//* Memory cleared below. */
+  new = realloc (tasks,
+                 (tasks_size + TASKS_INCREMENT) * sizeof (fs_task_t));
+/*@=sharedtrans@*/
+/*@=compdestroy@*/
+/*@-globstate@*/
+  if (new == NULL) return FALSE;
+/*@=globstate@*/
+  tasks = new;
+
+  /* Clear the new part of the memory. */
+  new = tasks + tasks_size;
+  memset (new, 0, TASKS_INCREMENT * sizeof (fs_task_t));
+
+  tasks_size += TASKS_INCREMENT;
+  tracef ("   tasks grown to %u\n", tasks_size);
+#if TRACE
+  print_tasks ();
+#endif
+  return TRUE;
+}
+
+/**
+ * @brief Free a task.
+ *
+ * Free all the members of a task.
+ *
+ * @param[in]  task  The task to free.
+ */
+static void
+free_task (/*@special@*/ /*@dependent@*/ task_t task)
+  /*@ensures isnull task->name@*/
+  /*@releases task->comment, task->open_ports@*/
+{
+  tracef ("   Freeing task %u: \"%s\" %s (%i) %.*s[...]\n\n",
+          task->id,
+          task->name,
+          task->comment,
+          (int) task->description_length,
+          (task->description_length > 20) ? 20 : task->description_length,
+          task->description ? task->description : "(null)");
+  free (task->name);
+  task->name = NULL;
+  free (task->comment);
+  if (task->description) free (task->description);
+  if (task->start_time) free (task->start_time);
+  if (task->end_time) free (task->end_time);
+  if (current_report)
+    {
+      (void) fclose (current_report); // FIX check for error
+      current_report = NULL;
+    }
+  if (task->open_ports) (void) g_array_free (task->open_ports, TRUE);
+}
+
+/**
+ * @brief Free all tasks and the array of tasks.
+ */
+void
+free_tasks ()
+{
+  if (tasks == NULL) return;
+
+  {
+    task_t index = tasks;
+    task_t end = tasks + tasks_size;
+    while (index < end)
+      {
+        /* This indicates that the state of the task depends on which
+         * branch of the `if' is taken. */
+        /*@-branchstate@*/
+        if (index->name) free_task (index);
+        /*@=branchstate@*/
+        index++;
+      }
+    tasks_size = 0;
+    free (tasks);
+    tasks = NULL;
+  }
+}
+
+/**
+ * @brief Make a task.
+ *
+ * The char* parameters name and comment are used directly and freed
+ * when the task is freed.
+ *
+ * @param[in]  name     The name of the task.
+ * @param[in]  time     The period of the task, in seconds.
+ * @param[in]  comment  A comment associated the task.
+ *
+ * @return A pointer to the new task or NULL when out of memory (in which
+ *         case caller must free name and comment).
+ */
+task_t
+make_task (char* name, unsigned int time, char* comment)
+{
+  task_t index;
+  task_t end;
+  tracef ("   make_task %s %u %s\n", name, time, comment);
+  if (tasks == NULL && grow_tasks () == FALSE)
+    {
+      g_free (name);
+      g_free (comment);
+      return NULL;
+    }
+  if (tasks == NULL) abort ();
+  index = tasks;
+  end = tasks + tasks_size;
+  while (1)
+    {
+      while (index < end)
+        {
+          if (index->name == NULL)
+            {
+              index->id = (unsigned int) (index - tasks);
+              index->name = name;
+              index->time = time;
+              /* The annotation is because these are all freed with name. */
+              /*@-mustfreeonly@*/
+              index->comment = comment;
+              index->description = NULL;
+              index->description_size = 0;
+              index->run_status = TASK_STATUS_NEW;
+              index->report_count = 0;
+              index->open_ports = NULL;
+              /*@=mustfreeonly@*/
+              tracef ("   Made task %u at %p\n", index->id, index);
+              num_tasks++;
+              return index;
+            }
+          index++;
+        }
+      index = (task_t) tasks_size;
+      /* grow_tasks updates tasks_size. */
+      if (grow_tasks ())
+        {
+          g_free (name);
+          g_free (comment);
+          return NULL;
+        }
+      index = index + (int) tasks;
+    }
+}
+
+typedef /*@only@*/ struct dirent * only_dirent_pointer;
+
+static void
+load_tasks_free (/*@only@*/ gchar* dir_name, /*@only@*/ gchar* file_name,
+                 int index, int count, /*@only@*/ only_dirent_pointer* names)
+{
+  g_free (dir_name);
+  g_free (file_name);
+  for (; index < count; index++) free (names[index]);
+  free (names);
+  free_tasks ();
+}
+
+/**
+ * @brief Load the tasks from disk.
+ *
+ * @return 0 success, -1 error.
+ */
+int
+load_tasks ()
+{
+  GError* error;
+  gchar* dir_name;
+  gchar* file_name;
+  struct dirent ** names = NULL;
+  int count, index;
+
+  if (tasks) return -1;
+
+  if (current_credentials.username == NULL) return -1;
+
+  tracef ("   Loading tasks...\n");
+
+  error = NULL;
+  dir_name = g_build_filename (PREFIX
+                               "/var/lib/openvas/mgr/users/",
+                               current_credentials.username,
+                               "tasks",
+                               NULL);
+
+  count = scandir (dir_name, &names, NULL, alphasort);
+  if (count < 0 || names == NULL)
+    {
+      if (errno == ENOENT)
+        {
+          free (dir_name);
+          tracef ("   Loading tasks... done\n");
+          return 0;
+        }
+      fprintf (stderr, "Failed to open dir %s: %s\n",
+               dir_name,
+               strerror (errno));
+      g_free (dir_name);
+      return -1;
+    }
+
+  file_name = NULL;
+  for (index = 0; index < count; index++)
+    {
+      gchar *name, *comment, *description;
+      unsigned int time;
+      /*@dependent@*/ const char* task_name = names[index]->d_name;
+      task_t task;
+      gboolean success;
+
+      if (task_name[0] == '.')
+        {
+          free (names[index]);
+          continue;
+        }
+
+      tracef ("     %s\n", task_name);
+
+      file_name = g_build_filename (dir_name, task_name, "name", NULL);
+      success = g_file_get_contents (file_name, &name, NULL, &error);
+      if (success == FALSE)
+        {
+          if (error)
+            {
+              fprintf (stderr, "Failed to get contents of %s: %s\n",
+                       file_name,
+                       error->message);
+              g_error_free (error);
+            }
+          load_tasks_free (dir_name, file_name, index, count, names);
+          return -1;
+        }
+
+      g_free (file_name);
+      file_name = g_build_filename (dir_name, task_name, "time", NULL);
+      success = g_file_get_contents (file_name, &comment, NULL, &error);
+      if (success == FALSE)
+        {
+          g_free (name);
+          if (error)
+            {
+              fprintf (stderr, "Failed to get contents of %s: %s\n",
+                       file_name,
+                       error->message);
+              g_error_free (error);
+            }
+          load_tasks_free (dir_name, file_name, index, count, names);
+          return -1;
+        }
+      if (sscanf (comment, "%u", &time) != 1)
+        {
+          fprintf (stderr, "Failed to scan time: %s\n", comment);
+          g_free (comment);
+          g_free (name);
+          if (error) g_error_free (error);
+          load_tasks_free (dir_name, file_name, index, count, names);
+          return -1;
+        }
+      g_free (comment);
+
+      g_free (file_name);
+      file_name = g_build_filename (dir_name, task_name, "comment", NULL);
+      comment = NULL;
+      success = g_file_get_contents (file_name, &comment, NULL, &error);
+      if (success == FALSE)
+        {
+          g_free (name);
+          if (error)
+            {
+              fprintf (stderr, "Failed to get contents of %s: %s\n",
+                       file_name,
+                       error->message);
+              g_error_free (error);
+            }
+          load_tasks_free (dir_name, file_name, index, count, names);
+          return -1;
+        }
+      g_free (file_name);
+
+      task = make_task (name, time, comment);
+      if (task == NULL)
+        {
+          g_free (dir_name);
+          for (; index < count; index++) free (names[index]);
+          free (names);
+          free_tasks ();
+          return -1;
+        }
+      /* name and comment are freed with the new task. */
+
+      {
+        gsize description_length;
+
+        file_name = g_build_filename (dir_name, task_name, "description", NULL);
+        success = g_file_get_contents (file_name,
+                                       &description,
+                                       &description_length,
+                                       &error);
+        if (success == FALSE)
+          {
+            if (error)
+              {
+                fprintf (stderr, "Failed to get contents of %s: %s\n",
+                         file_name,
+                         error->message);
+                g_error_free (error);
+              }
+            load_tasks_free (dir_name, file_name, index, count, names);
+            return -1;
+          }
+
+        task->description = description;
+        task->description_size = task->description_length = description_length;
+      }
+
+      g_free (file_name);
+      file_name = g_build_filename (dir_name, task_name, "report_count", NULL);
+      comment = NULL;
+      success = g_file_get_contents (file_name, &comment, NULL, &error);
+      if (success == FALSE)
+        {
+          if (error)
+            {
+              fprintf (stderr, "Failed to get contents of %s: %s\n",
+                       file_name,
+                       error->message);
+              g_error_free (error);
+            }
+          load_tasks_free (dir_name, file_name, index, count, names);
+          return -1;
+        }
+      if (sscanf (comment, "%u", &task->report_count) != 1)
+        {
+          fprintf (stderr, "Failed to scan report count: %s\n", comment);
+          if (error) g_error_free (error);
+          load_tasks_free (dir_name, file_name, index, count, names);
+          return -1;
+        }
+
+      g_free (file_name);
+      free (names[index]);
+    }
+
+  g_free (dir_name);
+  free (names);
+
+  tracef ("   Loading tasks... done\n");
+  return 0;
+}
+
+static void
+save_task_error (/*@only@*/ gchar* file_name, /*@only@*/ GError* error)
+{
+  if (error)
+    {
+      fprintf (stderr, "Failed to set contents of %s: %s\n",
+               file_name,
+               error->message);
+      g_error_free (error);
+    }
+  g_free (file_name);
+}
+
+/**
+ * @brief Save a task to a directory.
+ *
+ * Save a task to a given directory, ensuring that the directory exists
+ * before saving the task.
+ *
+ * @param[in]  task      The task.
+ * @param[in]  dir_name  The directory.
+ *
+ * @return 0 success, -1 error.
+ */
+static int
+save_task (task_t task, gchar* dir_name)
+{
+  gboolean success;
+  gchar* file_name;
+  GError* error = NULL;
+
+  /* Ensure directory exists. */
+
+  if (g_mkdir_with_parents (dir_name, 33216 /* -rwx------ */) == -1)
+    {
+      fprintf (stderr, "Failed to create task dir %s: %s\n",
+               dir_name,
+               strerror (errno));
+      return -1;
+    }
+
+  /* Save each component of the task. */
+
+  file_name = g_build_filename (dir_name, "name", NULL);
+
+  success = g_file_set_contents (file_name, task->name, -1, &error);
+  if (success == FALSE)
+    {
+      save_task_error (file_name, error);
+      return -1;
+    }
+  g_free (file_name);
+
+  file_name = g_build_filename (dir_name, "comment", NULL);
+  success = g_file_set_contents (file_name, task->comment, -1, &error);
+  if (success == FALSE)
+    {
+      save_task_error (file_name, error);
+      return -1;
+    }
+  g_free (file_name);
+
+  file_name = g_build_filename (dir_name, "description", NULL);
+  if (task->description == NULL)
+    success = g_file_set_contents (file_name, "", 0, &error);
+  else
+    success = g_file_set_contents (file_name,
+                                   task->description,
+                                   task->description_length,
+                                   &error);
+  if (success == FALSE)
+    {
+      save_task_error (file_name, error);
+      return -1;
+    }
+  g_free (file_name);
+
+  file_name = g_build_filename (dir_name, "time", NULL);
+  {
+    static char buffer[11]; /* (expt 2 32) => 4294967296 */
+    int length = snprintf (buffer, 11, "%u", task->time);
+    assert (length < 11);
+
+    if (length < 1 || length > 10)
+      {
+        save_task_error (file_name, error);
+        return -1;
+      }
+    success = g_file_set_contents (file_name, buffer, -1, &error);
+    if (success == FALSE)
+      {
+        save_task_error (file_name, error);
+        return -1;
+      }
+    g_free (file_name);
+
+    file_name = g_build_filename (dir_name, "report_count", NULL);
+    length = snprintf (buffer, 11, "%u", task->report_count);
+    assert (length < 11);
+    if (length < 1 || length > 10)
+      {
+        save_task_error (file_name, error);
+        return -1;
+      }
+    success = g_file_set_contents (file_name, buffer, -1, &error);
+    if (success == FALSE)
+      {
+        save_task_error (file_name, error);
+        return -1;
+      }
+  }
+  g_free (file_name);
+
+  return 0;
+}
+
+/**
+ * @brief Save all tasks to disk.
+ *
+ * @return 0 success, -1 error.
+ */
+int
+save_tasks ()
+{
+  gchar* dir_name;
+  task_t index;
+  task_t end;
+
+  if (tasks == NULL) return 0;
+  if (current_credentials.username == NULL) return -1;
+
+  tracef ("   Saving tasks...\n");
+
+  // FIX Could check if up to date already.
+
+  dir_name = g_build_filename (PREFIX
+                               "/var/lib/openvas/mgr/users/",
+                               current_credentials.username,
+                               "tasks",
+                               NULL);
+
+  /* Write each task in the tasks array to disk. */
+
+  index = tasks;
+  end = tasks + tasks_size;
+  while (index < end)
+    {
+      if (index->name)
+        {
+          const char* id;
+          gchar* file_name;
+          tracef ("     %u\n", index->id);
+
+          if (task_id_string (index, &id))
+            {
+              g_free (dir_name);
+              return -1;
+            }
+
+          file_name = g_build_filename (dir_name,
+                                        id,
+                                        NULL);
+          if (save_task (index, file_name))
+            {
+              g_free (dir_name);
+              g_free (file_name);
+              return -1;
+            }
+          g_free (file_name);
+        }
+      index++;
+    }
+
+  g_free (dir_name);
+  tracef ("   Saving tasks... done.\n");
+  return 0;
+}
+
+/**
+ * @brief Set a task parameter.
+ *
+ * The "value" parameter is used directly and freed either immediately or
+ * when the task is freed or when the parameter is next updated.
+ *
+ * @param[in]  task       A pointer to a task.
+ * @param[in]  parameter  The name of the parameter (in any case): TASK_FILE,
+ *                        NAME or COMMENT.
+ * @param[in]  value      The value of the parameter, in base64 if parameter
+ *                        is "TASK_FILE".
+ *
+ * @return 0 on success, -1 when out of memory, -2 if parameter name error,
+ *         -3 value error (NULL).
+ */
+int
+set_task_parameter (task_t task, const char* parameter, /*@only@*/ char* value)
+{
+  tracef ("   set_task_parameter %u %s\n",
+          task->id,
+          parameter ? parameter : "(null)");
+  if (value == NULL) return -3;
+  if (parameter == NULL)
+    {
+      free (value);
+      return -2;
+    }
+  if (strncasecmp ("TASK_FILE", parameter, 9) == 0)
+    {
+      gsize out_len;
+      guchar* out;
+      out = g_base64_decode (value, &out_len);
+      free (value);
+      if (task->description) free (task->description);
+      task->description = (char*) out;
+      task->description_length = task->description_size = out_len;
+    }
+  else if (strncasecmp ("NAME", parameter, 4) == 0)
+    {
+      free (task->name);
+      task->name = value;
+    }
+  else if (strncasecmp ("COMMENT", parameter, 7) == 0)
+    {
+      free (task->comment);
+      task->comment = value;
+    }
+  else
+    {
+      free (value);
+      return -2;
+    }
+  return 0;
+}
+
+/**
+ * @brief Delete a task.
+ *
+ * Stop the task beforehand with \ref stop_task, if it is running.
+ *
+ * @param[in]  task  A pointer to the task.
+ *
+ * @return 0 on success, -1 if out of space in \ref to_server buffer.
+ */
+int
+delete_task (task_t* task_pointer)
+{
+  gboolean success;
+  const char* id;
+  gchar* name;
+  GError* error;
+  task_t task = *task_pointer;
+
+  tracef ("   delete task %u\n", task->id);
+
+  if (task_id_string (task, &id)) return -1;
+
+  if (current_credentials.username == NULL) return -1;
+
+  if (stop_task (task) == -1) return -1;
+
+  // FIX may be atomic problems here
+
+  if (delete_reports (task)) return -1;
+
+  name = g_build_filename (PREFIX
+                           "/var/lib/openvas/mgr/users/",
+                           current_credentials.username,
+                           "tasks",
+                           id,
+                           NULL);
+  error = NULL;
+  success = rmdir_recursively (name, &error);
+  if (success == FALSE)
+    {
+      if (error)
+        {
+          fprintf (stderr, "Failed to remove task dir %s: %s\n",
+                   name,
+                   error->message);
+          g_error_free (error);
+        }
+      g_free (name);
+      return -1;
+    }
+  g_free (name);
+
+  free_task (task);
+  *task_pointer = NULL;
+
+  return 0;
+}
+
+/**
+ * @brief Append text to the comment associated with a task.
+ *
+ * @param[in]  task    A pointer to the task.
+ * @param[in]  text    The text to append.
+ * @param[in]  length  Length of the text.
+ *
+ * @return 0 on success, -1 if out of memory.
+ */
+int
+append_to_task_comment (task_t task, const char* text, /*@unused@*/ int length)
+{
+  char* new;
+  if (task->comment)
+    {
+      // FIX
+      new = g_strconcat (task->comment, text, NULL);
+      free (task->comment);
+      task->comment = new;
+      return 0;
+    }
+  new = strdup (text);
+  if (new == NULL) return -1;
+  task->comment = new;
+  return 0;
+}
+
+/**
+ * @brief Append text to the identifier associated with a task.
+ *
+ * @param[in]  task    A pointer to the task.
+ * @param[in]  text    The text to append.
+ * @param[in]  length  Length of the text.
+ *
+ * @return 0 on success, -1 if out of memory.
+ */
+int
+append_to_task_identifier (task_t task, const char* text,
+                           /*@unused@*/ int length)
+{
+  char* new;
+  if (task->name)
+    {
+      new = g_strconcat (task->name, text, NULL);
+      g_free (task->name);
+      task->name = new;
+      return 0;
+    }
+  new = strdup (text);
+  if (new == NULL) return -1;
+  task->name = new;
+  return 0;
+}
+
+/**
+ * @brief Reallocation increment for a task description.
+ */
+#define DESCRIPTION_INCREMENT 4096
+
+/**
+ * @brief Increase the memory allocated for a task description.
+ *
+ * @param[in]  task       A pointer to the task.
+ * @param[in]  increment  Minimum number of bytes to increase memory.
+ *
+ * @return 0 on success, -1 if out of memory.
+ */
+static int
+grow_description (task_t task, size_t increment)
+{
+  size_t new_size = task->description_size
+                    + (increment < DESCRIPTION_INCREMENT
+                       ? DESCRIPTION_INCREMENT : increment);
+  /* RATS: ignore *//* Memory cleared below. */
+  char* new = realloc (task->description, new_size);
+  if (new == NULL) return -1;
+  memset (new, (int) '\0', new_size - task->description_size);
+  task->description = new;
+  task->description_size = new_size;
+  return 0;
+}
+
+/**
+ * @brief Add a line to a task description.
+ *
+ * @param[in]  task         A pointer to the task.
+ * @param[in]  line         The line.
+ * @param[in]  line_length  The length of the line.
+ */
+int
+add_task_description_line (task_t task, const char* line, size_t line_length)
+{
+  char* description;
+  if (task->description_size - task->description_length < line_length
+      && grow_description (task, line_length) < 0)
+    return -1;
+  description = task->description;
+  description += task->description_length;
+  strncpy (description, line, line_length);
+  task->description_length += line_length;
+  return 0;
+}
+
+/**
+ * @brief Set the ports of a task.
+ *
+ * @param[in]  task     The task.
+ * @param[in]  current  New value for port currently being scanned.
+ * @param[in]  max      New value for last port to be scanned.
+ */
+void
+set_task_ports (task_t task, unsigned int current, unsigned int max)
+{
+  task->current_port = current;
+  task->max_port = max;
+}
+
+/**
+ * @brief Add an open port to a task.
+ *
+ * @param[in]  task       The task.
+ * @param[in]  number     The port number.
+ * @param[in]  protocol   The port protocol.
+ */
+void
+append_task_open_port (task_t task, unsigned int number, char* protocol)
+{
+  assert (task->open_ports != NULL);
+  if (task->open_ports)
+    {
+      port_t port;
+
+      port.number = number;
+      if (strncasecmp ("udp", protocol, 3) == 0)
+        port.protocol = PORT_PROTOCOL_UDP;
+      else if (strncasecmp ("tcp", protocol, 3) == 0)
+        port.protocol = PORT_PROTOCOL_TCP;
+      else
+        port.protocol = PORT_PROTOCOL_OTHER;
+
+      (void) g_array_append_val (task->open_ports, port);
+      task->open_ports_size++;
+    }
+}
+
+/**
+ * @brief Find a task from a task identifier string.
+ *
+ * @param[in]   id_string  A task identifier string.
+ * @param[out]  task       The task, if found.
+ *
+ * @return 0 if task found, else -1.
+ */
+int
+find_task (const char* id_string, task_t* task)
+{
+  if (tasks)
+    {
+      unsigned int id;
+
+      if (sscanf (id_string, "%u", &id) == 1)
+        {
+          task_t index = tasks;
+          task_t end = tasks + tasks_size;
+          while (index < end)
+            {
+              if (index->name) tracef ("   %u vs %u\n", index->id, id);
+
+              if (index->name == NULL)
+                index++;
+              else if (index->id == id)
+                {
+                  tracef ("Found task %s at %p\n", id_string, index);
+                  *task = index;
+                  return 0;
+                }
+              else
+                index++;
+            }
+        }
+    }
+  return -1;
+}

Added: trunk/openvas-manager/src/tasks_sql.h
===================================================================
--- trunk/openvas-manager/src/tasks_sql.h	2009-05-06 12:58:15 UTC (rev 3262)
+++ trunk/openvas-manager/src/tasks_sql.h	2009-05-06 16:56:49 UTC (rev 3263)
@@ -0,0 +1,1103 @@
+/* OpenVAS Manager
+ * $Id$
+ * Description: Manager Manage library: SQL based tasks.
+ *
+ * Authors:
+ * Matthew Mundell <matt at mundell.ukfsn.org>
+ *
+ * Copyright:
+ * Copyright (C) 2009 Greenbone Networks GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or, at your option, any later version as published by the Free
+ * Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <sqlite3.h>
+
+
+/* Variables. */
+
+sqlite3* task_db = NULL;
+
+
+/* SQL helpers. */
+
+gchar*
+sql_quote (const char* string, size_t length)
+{
+  gchar *new, *new_start;
+  const gchar *start, *end;
+  int count = 0;
+
+  /* Count number of apostrophes. */
+
+  start = string;
+  while ((start = strchr (start, '\''))) count++;
+
+  /* Allocate new string. */
+
+  new = new_start = g_malloc0 (length + count + 1);
+
+  /* Copy string, replacing apostrophes with double apostrophes. */
+
+  start = string;
+  end = string + length;
+  for (; start < end; start++, new++)
+    {
+      char ch = *start;
+      if (ch == '\'')
+        {
+          *new = '\'';
+          new++;
+          *new = '\'';
+        }
+      else
+        *new = ch;
+    }
+
+  return new_start;
+}
+
+void
+sql (char* sql, ...)
+{
+  const char* tail;
+  int ret;
+  sqlite3_stmt* stmt;
+  va_list args;
+  gchar* formatted;
+
+  va_start (args, sql);
+  formatted = g_strdup_vprintf (sql, args);
+  va_end (args);
+
+  tracef ("   sql: %s\n", formatted);
+
+  ret = sqlite3_prepare (task_db, (char*) formatted, -1, &stmt, &tail);
+  g_free (formatted);
+  if (ret != SQLITE_OK || stmt == NULL)
+    {
+      fprintf (stderr, "sqlite3_prepare failed: %s\n",
+               sqlite3_errmsg (task_db));
+      abort ();
+    }
+  while (1)
+    {
+      ret = sqlite3_step (stmt);
+      if (ret == SQLITE_BUSY) continue;
+      if (ret == SQLITE_DONE) break;
+      if (ret == SQLITE_ERROR || ret == SQLITE_MISUSE)
+        {
+          if (ret == SQLITE_ERROR) ret = sqlite3_reset (stmt);
+          fprintf (stderr, "sqlite3_step failed: %s\n",
+                   sqlite3_errmsg (task_db));
+          abort ();
+        }
+    }
+  sqlite3_finalize (stmt);
+}
+
+void
+sql_x (unsigned int col, unsigned int row, char* sql, va_list args,
+       sqlite3_stmt** stmt_return)
+{
+  const char* tail;
+  int ret;
+  sqlite3_stmt* stmt;
+  gchar* formatted;
+
+  //va_start (args, sql);
+  formatted = g_strdup_vprintf (sql, args);
+  //va_end (args);
+
+  tracef ("   sql_x: %s\n", formatted);
+
+  ret = sqlite3_prepare (task_db, (char*) formatted, -1, &stmt, &tail);
+  g_free (formatted);
+  *stmt_return = stmt;
+  if (ret != SQLITE_OK || stmt == NULL)
+    {
+      fprintf (stderr, "sqlite3_prepare failed: %s\n",
+               sqlite3_errmsg (task_db));
+      abort ();
+    }
+  while (1)
+    {
+      ret = sqlite3_step (stmt);
+      if (ret == SQLITE_BUSY) continue;
+      if (ret == SQLITE_DONE)
+        {
+          fprintf (stderr, "sqlite3_step finished too soon\n");
+          abort ();
+        }
+      if (ret == SQLITE_ERROR || ret == SQLITE_MISUSE)
+        {
+          if (ret == SQLITE_ERROR) ret = sqlite3_reset (stmt);
+          fprintf (stderr, "sqlite3_step failed: %s\n",
+                   sqlite3_errmsg (task_db));
+          abort ();
+        }
+      if (row == 0) break;
+      row--;
+      tracef ("   sql_x row %i\n", row);
+    }
+
+  tracef ("   sql_x end\n");
+}
+
+int
+sql_int (unsigned int col, unsigned int row, char* sql, ...)
+{
+  sqlite3_stmt* stmt;
+  va_list args;
+  va_start (args, sql);
+  sql_x (col, row, sql, args, &stmt);
+  va_end (args);
+  int ret = sqlite3_column_int (stmt, col);
+  sqlite3_finalize (stmt);
+  return ret;
+}
+
+const unsigned char*
+sql_string (unsigned int col, unsigned int row, char* sql, ...)
+{
+  sqlite3_stmt* stmt;
+  va_list args;
+  va_start (args, sql);
+  sql_x (col, row, sql, args, &stmt);
+  va_end (args);
+  const unsigned char* ret2 = sqlite3_column_text (stmt, col);
+  // FIX probably need to dup ret before finalize
+  // FIX leak
+  const unsigned char* ret = g_strdup (ret2);
+  sqlite3_finalize (stmt);
+  return ret;
+}
+
+long long int
+sql_int64 (unsigned int col, unsigned int row, char* sql, ...)
+{
+  sqlite3_stmt* stmt;
+  va_list args;
+  va_start (args, sql);
+  sql_x (col, row, sql, args, &stmt);
+  va_end (args);
+  long long int ret = sqlite3_column_int64 (stmt, col);
+  sqlite3_finalize (stmt);
+  return ret;
+}
+
+
+/* Task functions. */
+
+void
+inc_task_int (task_t task, const char* field)
+{
+  int current = sql_int (0, 0,
+                         "SELECT %s FROM tasks_%s WHERE ROWID = %llu;",
+                         field,
+                         current_credentials.username,
+                         task);
+  sql ("UPDATE tasks_%s SET %s = %i WHERE ROWID = %llu;",
+       current_credentials.username,
+       field,
+       current + 1,
+       task);
+}
+
+void
+dec_task_int (task_t task, const char* field)
+{
+  int current = sql_int (0, 0,
+                         "SELECT %s FROM tasks_%s WHERE ROWID = %llu;",
+                         field,
+                         current_credentials.username,
+                         task);
+  sql ("UPDATE tasks_%s SET %s = %i WHERE ROWID = %llu;",
+       current_credentials.username,
+       field,
+       current - 1,
+       task);
+}
+
+void
+append_to_task_string (task_t task, const char* field, const char* value)
+{
+  const unsigned char* current;
+  current = sql_string (0, 0,
+                        "SELECT %s FROM tasks_%s WHERE ROWID = %llu;",
+                        field,
+                        current_credentials.username,
+                        task);
+  gchar* quote;
+  if (current)
+    {
+      gchar* new = g_strconcat ((const gchar*) current, value, NULL);
+      quote = sql_quote (new, strlen (new));
+      g_free (new);
+    }
+  else
+    quote = sql_quote (value, strlen (value));
+  sql ("UPDATE tasks_%s SET %s = '%s' WHERE ROWID = %llu;",
+       current_credentials.username,
+       field,
+       quote,
+       task);
+  g_free (quote);
+}
+
+
+
+/**
+ * @brief Initialize the manage library.
+ */
+void
+init_manage ()
+{
+  /* Open the database. */
+  int ret = sqlite3_open (PREFIX "/var/lib/openvas/mgr/tasks.db", &task_db);
+  if (ret)
+    {
+      fprintf (stderr, "sqlite3_open failed: %s\n",
+               sqlite3_errmsg (task_db));
+      abort ();
+    }
+}
+
+/**
+ * @brief Cleanup the manage library.
+ */
+void
+cleanup_manage ()
+{
+  if (task_db)
+    {
+      sqlite3_close (task_db);
+      task_db = NULL;
+    }
+}
+
+/**
+ * @brief Authenticate credentials.
+ *
+ * @param[in]  credentials  Credentials.
+ *
+ * @return 1 if credentials are authentic, else 0.
+ */
+int
+authenticate (credentials_t credentials)
+{
+  if (credentials.username)
+    {
+      sql ("CREATE TABLE IF NOT EXISTS tasks_%s (uuid, name, time, comment, description, run_status, start_time, end_time, report_count, attack_state, current_port, max_port, debugs_size, holes_size, infos_size, logs_size, notes_size)",
+           current_credentials.username);
+      return 1;
+    }
+  return 0;
+}
+
+/**
+ * @brief Return the number of tasks associated with the current user.
+ *
+ * @return The number of tasks associated with the current user.
+ */
+unsigned int
+task_count ()
+{
+  return (unsigned int) sql_int (0, 0,
+                                 "SELECT count(*) FROM tasks_%s;",
+                                 current_credentials.username);
+}
+
+/**
+ * @brief Initialise a task iterator.
+ *
+ * @param[in]  iterator  Task iterator.
+ */
+void
+init_task_iterator (task_iterator_t* iterator)
+{
+  int ret;
+  const char* tail;
+  gchar* formatted;
+  sqlite3_stmt* stmt;
+
+  iterator->done = FALSE;
+  formatted = g_strdup_printf ("SELECT ROWID FROM tasks_%s",
+                                current_credentials.username);
+  tracef ("   sql (iterator): %s\n", formatted);
+  ret = sqlite3_prepare (task_db, (char*) formatted, -1, &stmt, &tail);
+  g_free (formatted);
+  iterator->stmt = stmt;
+  if (ret != SQLITE_OK || stmt == NULL)
+    {
+      fprintf (stderr, "sqlite3_prepare failed: %s\n",
+               sqlite3_errmsg (task_db));
+      abort ();
+    }
+}
+
+/**
+ * @brief Cleanup a task iterator.
+ *
+ * @param[in]  iterator  Task iterator.
+ */
+void
+cleanup_task_iterator (task_iterator_t* iterator)
+{
+  sqlite3_finalize (iterator->stmt);
+}
+
+/**
+ * @brief Read the next task from an iterator.
+ *
+ * @param[in]   iterator  Task iterator.
+ * @param[out]  task      Task.
+ *
+ * @return TRUE if there was a next task, else FALSE.
+ */
+gboolean
+next_task (task_iterator_t* iterator, task_t* task)
+{
+  int ret;
+
+  tracef ("next_task (%s)\n", iterator->done ? "done" : "");
+
+  if (iterator->done) return FALSE;
+
+  while ((ret = sqlite3_step (iterator->stmt)) == SQLITE_BUSY);
+  if (ret == SQLITE_DONE)
+    {
+      tracef ("  reached done\n");
+      iterator->done = TRUE;
+      return FALSE;
+    }
+  if (ret == SQLITE_ERROR || ret == SQLITE_MISUSE)
+    {
+      if (ret == SQLITE_ERROR) ret = sqlite3_reset (iterator->stmt);
+      fprintf (stderr, "sqlite3_step failed: %s\n",
+               sqlite3_errmsg (task_db));
+      abort ();
+    }
+  *task = sqlite3_column_int64 (iterator->stmt, 0);
+  tracef ("  ret %llu", *task);
+  return TRUE;
+}
+
+/**
+ * @brief Return the identifier of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return ID of task.
+ */
+unsigned int
+task_id (task_t task)
+{
+  // FIX cast hack for tasks_fs compat, task is long long int
+  return (unsigned int) task;
+}
+
+/**
+ * @brief Return a string version of the ID of a task.
+ *
+ * @param[in]   task  Task.
+ * @param[out]  id    Pointer to a string.
+ *
+ * @return 0.
+ */
+int
+task_id_string (task_t task, const char ** id)
+{
+#if 0
+  const unsigned char* str;
+  str = sql_string (0, 0,
+                    "SELECT uuid FROM tasks_%s WHERE ROWID = %llu;",
+                    current_credentials.username,
+                    task);
+  *id = (const char*) str;
+#else
+  *id = g_strdup_printf ("%llu", task);
+#endif
+  return 0;
+}
+
+/**
+ * @brief Return the name of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task name.
+ */
+const char*
+task_name (task_t task)
+{
+  return sql_string (0, 0,
+                     "SELECT name FROM tasks_%s WHERE ROWID = %llu;",
+                     current_credentials.username,
+                     task);
+}
+
+/**
+ * @brief Return the comment of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Comment of task.
+ */
+const char*
+task_comment (task_t task)
+{
+  return sql_string (0, 0,
+                     "SELECT comment FROM tasks_%s WHERE ROWID = %llu;",
+                     current_credentials.username,
+                     task);
+}
+
+/**
+ * @brief Return the description of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Description of task.
+ */
+const char*
+task_description (task_t task)
+{
+  return sql_string (0, 0,
+                     "SELECT description FROM tasks_%s WHERE ROWID = %llu;",
+                     current_credentials.username,
+                     task);
+}
+
+/**
+ * @brief Set the description of a task.
+ *
+ * @param[in]  task         Task.
+ * @param[in]  description  Description.  Used directly, freed by free_task.
+ */
+void
+set_task_description (task_t task, char* description, gsize length)
+{
+  gchar* quote = sql_quote (description, strlen (description));
+  sql ("UPDATE tasks_%s SET description = '%s' WHERE ROWID = %llu;",
+       current_credentials.username,
+       quote,
+       task);
+  g_free (quote);
+}
+
+/**
+ * @brief Return the run state of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task run status.
+ */
+task_status_t
+task_run_status (task_t task)
+{
+  return (unsigned int) sql_int (0, 0,
+                                 "SELECT run_status FROM tasks_%s WHERE ROWID = %llu;",
+                                 current_credentials.username,
+                                 task);
+}
+
+/**
+ * @brief Set the run state of a task.
+ *
+ * @param[in]  task    Task.
+ * @param[in]  status  New run status.
+ *
+ */
+void
+set_task_run_status (task_t task, task_status_t status)
+{
+  sql ("UPDATE tasks_%s SET run_status = %u WHERE ROWID = %llu;",
+       current_credentials.username,
+       status,
+       task);
+}
+
+/**
+ * @brief Return the most recent start time of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task start time.
+ */
+const char*
+task_start_time (task_t task)
+{
+  return sql_string (0, 0,
+                     "SELECT start_time FROM tasks_%s WHERE ROWID = %llu;",
+                     current_credentials.username,
+                     task);
+}
+
+/**
+ * @brief Set the start time of a task.
+ *
+ * @param[in]  task  Task.
+ * @param[in]  time  New time.  Used directly, freed by free_task.
+ */
+void
+set_task_start_time (task_t task, char* time)
+{
+  sql ("UPDATE tasks_%s SET start_time = '%.*s' WHERE ROWID = %llu;",
+       current_credentials.username,
+       strlen (time),
+       time,
+       task);
+}
+
+/**
+ * @brief Return the most recent end time of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task end time.
+ */
+const char*
+task_end_time (task_t task)
+{
+  return sql_string (0, 0,
+                     "SELECT end_time FROM tasks_%s WHERE ROWID = %llu;",
+                     current_credentials.username,
+                     task);
+}
+
+/**
+ * @brief Set the end time of a task.
+ *
+ * @param[in]  task  Task.
+ * @param[in]  time  New time.  Used directly, freed by free_task.
+ */
+void
+set_task_end_time (task_t task, char* time)
+{
+  sql ("UPDATE tasks_%s SET end_time = '%.*s' WHERE ROWID = %llu;",
+       current_credentials.username,
+       strlen (time),
+       time,
+       task);
+}
+
+/**
+ * @brief Return the number of reports associated with a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of reports.
+ */
+unsigned int
+task_report_count (task_t task)
+{
+  return (unsigned int) sql_int (0, 0,
+                                 "SELECT report_count FROM tasks_%s WHERE ROWID = %llu;",
+                                 current_credentials.username,
+                                 task);
+}
+
+/**
+ * @brief Return the attack state of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Task attack state.
+ */
+const char*
+task_attack_state (task_t task)
+{
+  return sql_string (0, 0,
+                     "SELECT attack_state FROM tasks_%s WHERE ROWID = %llu;",
+                     current_credentials.username,
+                     task);
+}
+
+/**
+ * @brief Set the attack state of a task.
+ *
+ * @param[in]  task   Task.
+ * @param[in]  state  New state.
+ */
+void
+set_task_attack_state (task_t task, char* state)
+{
+  sql ("UPDATE tasks_%s SET attack_state = '%.*s' WHERE ROWID = %llu;",
+       current_credentials.username,
+       strlen (state),
+       state,
+       task);
+}
+
+/**
+ * @brief Return the number of debug messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of debug messages.
+ */
+int
+task_debugs_size (task_t task)
+{
+  return sql_int (0, 0,
+                  "SELECT debugs_size FROM tasks_%s WHERE ROWID = %llu;",
+                  current_credentials.username,
+                  task);
+}
+
+/**
+ * @brief Increment number of debug messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_debugs_size (task_t task)
+{
+  inc_task_int (task, "debugs_size");
+}
+
+/**
+ * @brief Return the number of hole messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of hole messages.
+ */
+int
+task_holes_size (task_t task)
+{
+  return sql_int (0, 0,
+                  "SELECT holes_size FROM tasks_%s WHERE ROWID = %llu;",
+                  current_credentials.username,
+                  task);
+}
+
+/**
+ * @brief Increment number of hole messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_holes_size (task_t task)
+{
+  inc_task_int (task, "holes_size");
+}
+
+/**
+ * @brief Return the number of info messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of info messages.
+ */
+int
+task_infos_size (task_t task)
+{
+  return sql_int (0, 0,
+                  "SELECT infos_size FROM tasks_%s WHERE ROWID = %llu;",
+                  current_credentials.username,
+                  task);
+}
+
+/**
+ * @brief Increment number of info messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_infos_size (task_t task)
+{
+  inc_task_int (task, "holes_size");
+}
+
+/**
+ * @brief Return the number of log messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of log messages.
+ */
+int
+task_logs_size (task_t task)
+{
+  return sql_int (0, 0,
+                  "SELECT logs_size FROM tasks_%s WHERE ROWID = %llu;",
+                  current_credentials.username,
+                  task);
+}
+
+/**
+ * @brief Increment number of log messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_logs_size (task_t task)
+{
+  inc_task_int (task, "logs_size");
+}
+
+/**
+ * @brief Return the number of note messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Number of note messages.
+ */
+int
+task_notes_size (task_t task)
+{
+  return sql_int (0, 0,
+                  "SELECT notes_size FROM tasks_%s WHERE ROWID = %llu;",
+                  current_credentials.username,
+                  task);
+}
+
+/**
+ * @brief Increment number of note messages in the current report of a task.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_notes_size (task_t task)
+{
+  inc_task_int (task, "notes_size");
+}
+
+
+/**
+ * @brief Increment report count.
+ *
+ * @param[in]  task  Task.
+ */
+void
+inc_task_report_count (task_t task)
+{
+  inc_task_int (task, "report_count");
+}
+
+/**
+ * @brief Decrement report count.
+ *
+ * @param[in]  task  Task.
+ */
+void
+dec_task_report_count (task_t task)
+{
+  dec_task_int (task, "report_count");
+}
+
+/**
+ * @brief Dummy function.
+ */
+static void
+free_task (task_t task)
+{
+  /* Empty. */
+}
+
+/**
+ * @brief Dummy function.
+ */
+void
+free_tasks ()
+{
+  /* Empty. */
+}
+
+/**
+ * @brief Make a task.
+ *
+ * The char* parameters name and comment are used directly and freed
+ * when the task is freed.
+ *
+ * @param[in]  name     The name of the task.
+ * @param[in]  time     The period of the task, in seconds.
+ * @param[in]  comment  A comment associated the task.
+ *
+ * @return A pointer to the new task or NULL when out of memory (in which
+ *         case caller must free name and comment).
+ */
+task_t
+make_task (char* name, unsigned int time, char* comment)
+{
+  sql ("INSERT into tasks_%s (name, time, comment) VALUES (%s, %u, %s);",
+       current_credentials.username, name, time, comment);
+  free (name);
+  free (comment);
+  return sqlite3_last_insert_rowid (task_db);
+}
+
+typedef /*@only@*/ struct dirent * only_dirent_pointer;
+
+/**
+ * @brief Dummy function.
+ *
+ * @return 0.
+ */
+int
+load_tasks ()
+{
+  return 0;
+}
+
+/**
+ * @brief Dummy function.
+ *
+ * @return 0.
+ */
+int
+save_tasks ()
+{
+  return 0;
+}
+
+/**
+ * @brief Set a task parameter.
+ *
+ * The "value" parameter is used directly and freed either immediately or
+ * when the task is freed.
+ *
+ * @param[in]  task       A pointer to a task.
+ * @param[in]  parameter  The name of the parameter (in any case): TASK_FILE,
+ *                        IDENTIFIER or COMMENT.
+ * @param[in]  value      The value of the parameter, in base64 if parameter
+ *                        is "TASK_FILE".
+ *
+ * @return 0 on success, -1 when out of memory, -2 if parameter name error,
+ *         -3 value error (NULL).
+ */
+int
+set_task_parameter (task_t task, const char* parameter, /*@only@*/ char* value)
+{
+  tracef ("   set_task_parameter %u %s\n",
+          task_id (task),
+          parameter ? parameter : "(null)");
+  if (value == NULL) return -3;
+  if (parameter == NULL)
+    {
+      free (value);
+      return -2;
+    }
+  if (strncasecmp ("TASK_FILE", parameter, 9) == 0)
+    {
+      gchar* quote = sql_quote (value, strlen (value));
+      sql ("UPDATE tasks_%s SET description = '%s' WHERE ROWID = %llu;",
+           current_credentials.username,
+           quote,
+           task);
+      g_free (quote);
+    }
+  else if (strncasecmp ("NAME", parameter, 4) == 0)
+    {
+      gchar* quote = sql_quote (value, strlen (value));
+      sql ("UPDATE tasks_%s SET name = '%s' WHERE ROWID = %llu;",
+           current_credentials.username,
+           value,
+           task);
+      g_free (quote);
+    }
+  else if (strncasecmp ("COMMENT", parameter, 7) == 0)
+    {
+      gchar* quote = sql_quote (value, strlen (value));
+      sql ("UPDATE tasks_%s SET comment = '%s' WHERE ROWID = %llu;",
+           current_credentials.username,
+           value,
+           task);
+      g_free (quote);
+    }
+  else
+    {
+      free (value);
+      return -2;
+    }
+  return 0;
+}
+
+/**
+ * @brief Delete a task.
+ *
+ * Stop the task beforehand with \ref stop_task, if it is running.
+ *
+ * @param[in]  task  A pointer to the task.
+ *
+ * @return 0 on success, -1 if out of space in \ref to_server buffer.
+ */
+int
+delete_task (task_t* task_pointer)
+{
+  gboolean success;
+  const char* id;
+  gchar* name;
+  GError* error;
+  task_t task = *task_pointer;
+
+  tracef ("   delete task %u\n", task_id (task));
+
+  if (task_id_string (task, &id)) return -1;
+
+  if (current_credentials.username == NULL) return -1;
+
+  if (stop_task (task) == -1) return -1;
+
+  // FIX may be atomic problems here
+
+  if (delete_reports (task)) return -1;
+
+  /* Remove the task directory, which contained the reports. */
+
+  name = g_build_filename (PREFIX
+                           "/var/lib/openvas/mgr/users/",
+                           current_credentials.username,
+                           "tasks",
+                           id,
+                           NULL);
+  error = NULL;
+  success = rmdir_recursively (name, &error);
+  if (success == FALSE)
+    {
+      if (error)
+        {
+          fprintf (stderr, "Failed to remove task dir %s: %s\n",
+                   name,
+                   error->message);
+          g_error_free (error);
+        }
+      g_free (name);
+      return -1;
+    }
+  g_free (name);
+
+  sql ("DELETE FROM tasks_%s WHERE ROWID = %llu;",
+       current_credentials.username,
+       task);
+
+  return 0;
+}
+
+/**
+ * @brief Append text to the comment associated with a task.
+ *
+ * @param[in]  task    A pointer to the task.
+ * @param[in]  text    The text to append.
+ * @param[in]  length  Length of the text.
+ *
+ * @return 0 on success, -1 if out of memory.
+ */
+int
+append_to_task_comment (task_t task, const char* text, /*@unused@*/ int length)
+{
+  append_to_task_string (task, "comment", text);
+  return 0;
+}
+
+/**
+ * @brief Append text to the identifier associated with a task.
+ *
+ * @param[in]  task    A pointer to the task.
+ * @param[in]  text    The text to append.
+ * @param[in]  length  Length of the text.
+ *
+ * @return 0 on success, -1 if out of memory.
+ */
+int
+append_to_task_identifier (task_t task, const char* text,
+                           /*@unused@*/ int length)
+{
+  append_to_task_string (task, "name", text);
+  return 0;
+}
+
+/**
+ * @brief Add a line to a task description.
+ *
+ * @param[in]  task         A pointer to the task.
+ * @param[in]  line         The line.
+ * @param[in]  line_length  The length of the line.
+ */
+int
+add_task_description_line (task_t task, const char* line,
+                           /*@unused@*/ size_t line_length)
+{
+  append_to_task_string (task, "description", line);
+  return 0;
+}
+
+/**
+ * @brief Set the ports of a task.
+ *
+ * @param[in]  task     The task.
+ * @param[in]  current  New value for port currently being scanned.
+ * @param[in]  max      New value for last port to be scanned.
+ */
+void
+set_task_ports (task_t task, unsigned int current, unsigned int max)
+{
+  sql ("UPDATE tasks_%s SET current_port = %i, max_port = %i WHERE ROWID = %llu;",
+       current_credentials.username,
+       current,
+       max,
+       task);
+}
+
+/**
+ * @brief Add an open port to a task.
+ *
+ * @param[in]  task       The task.
+ * @param[in]  number     The port number.
+ * @param[in]  protocol   The port protocol.
+ */
+void
+append_task_open_port (task_t task, unsigned int number, char* protocol)
+{
+  // FIX
+}
+
+/**
+ * @brief Find a task given an identifier.
+ *
+ * @param[in]  id  A task identifier.
+ *
+ * @return A pointer to the task with the given ID.
+ */
+gboolean
+find_task (const char* uuid, task_t* task)
+{
+#if 0
+  *task = sql_int64 (0, 0,
+                     "SELECT ROWID FROM tasks_%s WHERE uuid = %llu;",
+                     current_credentials.username,
+                     uuid);
+  return TRUE;
+#else
+  int count;
+  unsigned long long int result;
+  errno = 0;
+  result = strtoull (uuid, NULL, 10);
+  if (errno) return TRUE;
+
+  count = sql_int (0, 0,
+                   "SELECT count(*) FROM tasks_%s where ROWID = %llu",
+                   current_credentials.username,
+                   result);
+  if (count == 1)
+    {
+      *task = result;
+      return FALSE;
+    }
+  return TRUE;
+#endif
+}



More information about the Openvas-commits mailing list