[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