/* Greenbone Security Assistant
 * $Id$
 * Description: OMP communication module.
 *
 * Authors:
 * Matthew Mundell <matthew.mundell@greenbone.net>
 * Jan-Oliver Wagner <jan-oliver.wagner@greenbone.net>
 * Michael Wiegand <michael.wiegand@greenbone.net>
 *
 * Copyright:
 * Copyright (C) 2009, 2014 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
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * 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.
 */

/**
 * @file gsad_omp.c
 * @brief OMP communication module of Greenbone Security Assistant daemon.
 *
 * This file implements an API for OMP.  The functions call the OpenVAS Manager
 * via OMP properly, and apply XSL-Transforms to deliver HTML results.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>

#include <microhttpd.h>

#include "gsad_base.h"
#include "gsad_omp.h"
#include "xslt_i18n.h"

#include <openvas/misc/openvas_server.h>
#include <openvas/base/openvas_file.h>
#include <openvas/base/cvss.h>
#include <openvas/omp/omp.h>
#include <openvas/omp/xml.h>

/*
 * XSLT includes
 */
#include <libxml2/libxml/xmlmemory.h>
#include <libxml2/libxml/HTMLtree.h>
#include <libxml2/libxml/xmlIO.h>
#include <libxml2/libxml/xinclude.h>
#include <libxslt/xslt.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>

#undef G_LOG_DOMAIN
/**
 * @brief GLib log domain.
 */
#define G_LOG_DOMAIN "gsad  omp"

/**
 * @brief Manager (openvasmd) address.
 */
#define OPENVASMD_ADDRESS "127.0.0.1"

/**
 * @brief Whether to use TLS for Manager connections.
 */
int manager_use_tls = 0;

/**
 * @brief The address the manager is on.
 */
gchar *manager_address = NULL;

/**
 * @brief The port the manager is on.
 */
int manager_port = 9390;


/* Headers. */

static int
omp (openvas_connection_t *, credentials_t *, gchar **, entity_t *,
     cmd_response_data_t*, const char *);

static int
ompf (openvas_connection_t *, credentials_t *, gchar **, entity_t *,
      cmd_response_data_t*, const char *, ...);

static char *edit_role (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *edit_task (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *get_alert (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *get_alerts (openvas_connection_t *, credentials_t *, params_t *,
                         const char *, cmd_response_data_t*);

static char *get_agent (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *get_agents (openvas_connection_t *, credentials_t *, params_t *,
                         const char *, cmd_response_data_t*);

static char *get_asset (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *get_assets (openvas_connection_t *, credentials_t *, params_t *,
                         const char *, cmd_response_data_t*);

static char *get_assets_chart (openvas_connection_t *, credentials_t *,
                               params_t *, const char *, cmd_response_data_t*);


static char *get_task (openvas_connection_t *, credentials_t *, params_t *,
                       const char *, cmd_response_data_t*);

static char *get_tasks (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *get_tasks_chart (openvas_connection_t *, credentials_t *,
                              params_t *, const char *, cmd_response_data_t*);

static char *get_trash (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *get_config_family (openvas_connection_t *, credentials_t *,
                                params_t *, int, cmd_response_data_t*);

static char *get_config (openvas_connection_t *, credentials_t *, params_t *,
                         const char *, int, cmd_response_data_t*);

static char *get_configs (openvas_connection_t *, credentials_t *, params_t *,
                          const char *, cmd_response_data_t*);

static char *get_filter (openvas_connection_t *, credentials_t *, params_t *,
                         const char *, cmd_response_data_t*);

static char *get_filters (openvas_connection_t *, credentials_t *, params_t *,
                          const char *, cmd_response_data_t*);

static char *get_group (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *get_groups (openvas_connection_t *, credentials_t *, params_t *,
                         const char *, cmd_response_data_t*);

static char *get_credential (openvas_connection_t *, credentials_t *,
                             params_t *, const char *, cmd_response_data_t*);

static char *get_credentials (openvas_connection_t *, credentials_t *,
                              params_t *, const char *, cmd_response_data_t*);

static char *get_notes (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *get_note (openvas_connection_t *, credentials_t *, params_t *,
                       const char *, cmd_response_data_t*);

static char *get_nvts (openvas_connection_t *, credentials_t *credentials,
                       params_t *, const char *, const char *,
                       cmd_response_data_t*);

static char *get_overrides (openvas_connection_t *, credentials_t *, params_t *,
                            const char *, cmd_response_data_t*);

static char *get_override (openvas_connection_t *, credentials_t *, params_t *,
                           const char *, cmd_response_data_t*);

static char *get_permission (openvas_connection_t *, credentials_t *,
                             params_t *, const char *, cmd_response_data_t*);

static char *get_permissions (openvas_connection_t *, credentials_t *,
                              params_t *, const char *, cmd_response_data_t*);

static char *get_port_list (openvas_connection_t *, credentials_t *, params_t *,
                            const char *, cmd_response_data_t*);

static char *get_port_lists (openvas_connection_t *, credentials_t *,
                             params_t *, const char *, cmd_response_data_t*);

static char *edit_port_list (openvas_connection_t *, credentials_t *,
                             params_t *, const char *, cmd_response_data_t*);

static char *get_tag (openvas_connection_t *, credentials_t *, params_t *,
                      const char *, cmd_response_data_t*);

static char *get_tags (openvas_connection_t *, credentials_t *, params_t *,
                       const char *, cmd_response_data_t*);

static char *get_target (openvas_connection_t *, credentials_t *, params_t *,
                         const char *, cmd_response_data_t*);

static char *get_targets (openvas_connection_t *, credentials_t *, params_t *,
                          const char *, cmd_response_data_t*);

static char *get_report (openvas_connection_t *, credentials_t *, params_t *,
                         const char *, gsize *, gchar **, char **, const char *,
                         int *, cmd_response_data_t*);

static char *get_report_format (openvas_connection_t *, credentials_t *,
                                params_t *, const char *, cmd_response_data_t*);

static char *get_report_formats (openvas_connection_t *, credentials_t *,
                                 params_t *, const char *,
                                 cmd_response_data_t*);

static char *get_report_section (openvas_connection_t *, credentials_t *,
                                 params_t *, const char *,
                                 cmd_response_data_t*);

static char *get_reports (openvas_connection_t *, credentials_t *, params_t *,
                          const char *, cmd_response_data_t*);

static char *get_result_page (openvas_connection_t *, credentials_t *,
                              params_t *, const char *, cmd_response_data_t*);

static char *get_results (openvas_connection_t *, credentials_t *, params_t *,
                          const char *, cmd_response_data_t*);

static char *get_role (openvas_connection_t *, credentials_t *, params_t *,
                       const char *, cmd_response_data_t*);

static char *get_roles (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *get_scanner (openvas_connection_t *, credentials_t *, params_t *,
                          const char *, cmd_response_data_t*);

static char *get_scanners (openvas_connection_t *, credentials_t *, params_t *,
                           const char *, cmd_response_data_t*);

static char *get_schedule (openvas_connection_t *, credentials_t *, params_t *,
                           const char *, cmd_response_data_t*);

static char *get_schedules (openvas_connection_t *, credentials_t *, params_t *,
                            const char *, cmd_response_data_t*);

static char *get_user (openvas_connection_t *, credentials_t *, params_t *,
                       const char *, cmd_response_data_t*);

static char *get_users (openvas_connection_t *, credentials_t *, params_t *,
                        const char *, cmd_response_data_t*);

static char *wizard (openvas_connection_t *, credentials_t *, params_t *,
                     const char *, cmd_response_data_t*);

static char *wizard_get (openvas_connection_t *, credentials_t *, params_t *,
                         const char *, cmd_response_data_t*);

int token_user_remove (const char *);

static int omp_success (entity_t entity);

static gchar *next_page_url (credentials_t *, params_t *, const char *,
                             const char *, const char *, const char *,
                             const char *);

static gchar *action_result_page (openvas_connection_t *, credentials_t *,
                                  params_t *, cmd_response_data_t *,
                                  const char*, const char*, const char*,
                                  const char*, const char*);

static gchar* response_from_entity (openvas_connection_t *, credentials_t*,
                                    params_t *, entity_t, int, const char*,
                                    const char *, const char*, const char*,
                                    const char *, cmd_response_data_t *);

/* Helpers. */

/**
 * @brief Init the GSA OMP library.
 *
 * @param[in]  credentials   Credentials.
 * @param[in]  name          Command name.
 */
int
command_enabled (credentials_t *credentials, const gchar *name)
{
  /* TODO Hack.  Fails if command named in summary of another command. */
  return strstr (credentials->capabilities, name) ? 1 : 0;
}

/**
 * @brief Init the GSA OMP library.
 *
 * @param[in]  manager_address_unix  Manager address when using UNIX socket.
 * @param[in]  manager_address_tls   Manager address when using TLS-TCP.
 * @param[in]  port_manager          Manager port.
 */
void
omp_init (const gchar *manager_address_unix, const gchar *manager_address_tls,
          int port_manager)
{
  if (manager_address_unix)
    {
      manager_address = g_strdup (manager_address_unix);
      manager_use_tls = 0;
    }
  else if (manager_address_tls)
    {
      manager_address = g_strdup (manager_address_tls);
      manager_use_tls = 1;
    }
  else
    {
      manager_address = g_build_filename (OPENVAS_RUN_DIR,
                                          "openvasmd.sock",
                                          NULL);
      manager_use_tls = 0;
    }
  manager_port = port_manager;
}

/**
 * @brief Initializes a cmd_response_data_t struct.
 *
 * @param[in]  data  The cmd_response_data_t struct to initialize
 */
void
cmd_response_data_init (cmd_response_data_t* data)
{
  data->http_status_code = MHD_HTTP_OK;
  data->redirect = NULL;
}

/**
 * @brief Clears a cmd_response_data_t struct.
 *
 * @param[in]  data  Struct to reset.
 */
void
cmd_response_data_reset (cmd_response_data_t* data)
{
  memset (data, 0, sizeof (cmd_response_data_t));
}

/**
 * @brief Traverse a chart preference tree and output xml elements.
 *
 * @param id     ID of the preference.
 * @param value  Preference value.
 * @param buffer GString buffer to output elements to.
 *
 * @return always 0
 */
static gboolean
print_chart_pref (gchar *id, gchar *value, GString* buffer)
{
  g_string_append_printf (buffer,
                          "<chart_preference id=\"%s\">"
                          "<value>%s</value>"
                          "</chart_preference>",
                          id,
                          value);
  return 0;
}

/**
 *  @brief Structure to search a key by value
 */
typedef struct
{
  gchar *value;
  GList *keys;
} find_by_value_t;

void
init_find_by_value (find_by_value_t *find, gchar *value)
{
  find->keys = NULL;
  find->value = value;
}

void
free_find_by_value (find_by_value_t *find)
{
  g_list_free (find->keys);
}

/**
 * @brief Traverse a g_tree until the first value is found
 *
 * @param[in]  key current key in the iteraton
 * @param[in]  value current value in the iteration
 * @param[out] data data->value contains the value to seach for. data->keys will
 *                  contain all found keys for the passed value
 *
 * @return FALSE to iterrate over all items in the tree
 */
static gboolean
find_by_value (gchar *key, gchar *value,  find_by_value_t *data)
{
  if (strcmp (value, data->value) == 0)
    {
      g_debug ("%s found key %s for value %s\n",
               __FUNCTION__, key, value);
      data->keys = g_list_append (data->keys, key);
    }
  return FALSE;
}

/**
 * @brief Check whether a filter exists
 *
 * @param[in] connection  Connection to manager.
 * @param[in] entity      Response entity.
 *
 * @return 1 success, 0 fail, -1 error, -2 could not send command to server,
 *         -3 could not read entity from server.
 */
static int
filter_exists (openvas_connection_t *connection, const char *filt_id)
{
  entity_t entity;

  if (filt_id == NULL
      || strcmp (filt_id, "0")
      || strcmp (filt_id, "-2"))
    return 1;

  /* check if filter still exists */
  if (openvas_connection_sendf (connection, "<get_filters filter_id='%s'/>",
                                filt_id))
    {
      return -2;
    }

  if (read_entity_c (connection, &entity))
    {
      return -3;
    }

  return omp_success (entity);
}

/**
 * @brief Wrap some XML in an envelope and XSL transform the envelope.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         HTTP request params
 * @param[in]  xml            XML string.  Freed before exit.
 *
 * @return Result of XSL transformation.
 */
static char *
xsl_transform_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params, gchar * xml,
                   cmd_response_data_t *response_data)
{
  time_t now;
  gchar *res, *name;
  GString *string;
  char *html;
  char ctime_now[200];
  params_iterator_t iter;
  param_t *param;
  const char *refresh_interval, *xml_flag;
  struct timeval tv;

  assert (credentials);

  now = time (NULL);
  ctime_r_strip_newline (&now, ctime_now);

  string = g_string_new ("");

  gettimeofday (&tv, NULL);
  res = g_markup_printf_escaped ("<envelope>"
                                 "<version>%s</version>"
                                 "<vendor_version>%s</vendor_version>"
                                 "<token>%s</token>"
                                 "<caller>%s</caller>"
                                 "<current_page>%s</current_page>"
                                 "<time>%s</time>"
                                 "<timezone>%s</timezone>"
                                 "<login>%s</login>"
                                 "<role>%s</role>"
                                 "<severity>%s</severity>"
                                 "<i18n>%s</i18n>"
                                 "<charts>%d</charts>"
                                 "<guest>%d</guest>"
                                 "<client_address>%s</client_address>"
                                 "<backend_operation>%.2f</backend_operation>",
                                 GSAD_VERSION,
                                 vendor_version_get (),
                                 credentials->token,
                                 credentials->caller ? credentials->caller : "",
                                 credentials->current_page
                                   ? credentials->current_page
                                   : (credentials->caller
                                       ? credentials->caller
                                       : ""),
                                 ctime_now,
                                 credentials->timezone
                                   ? credentials->timezone : "",
                                 credentials->username,
                                 credentials->role,
                                 credentials->severity,
                                 credentials->language,
                                 credentials->charts,
                                 credentials->guest,
                                 credentials->client_address,
                                 (double) ((tv.tv_sec
                                            - credentials->cmd_start.tv_sec)
                                           * 1000000L
                                           + tv.tv_usec
                                           - credentials->cmd_start.tv_usec)
                                 / 1000000.0);
  g_string_append (string, res);
  g_free (res);

  g_string_append (string, "<chart_preferences>");
  g_tree_foreach (credentials->chart_prefs,
                  (GTraverseFunc)print_chart_pref,
                  string);
  g_string_append (string, "</chart_preferences>");

  if (credentials->pw_warning)
    {
      gchar *warning_elem;
      warning_elem = g_markup_printf_escaped ("<password_warning>"
                                              "%s"
                                              "</password_warning>",
                                              credentials->pw_warning);
      g_string_append (string, warning_elem);
      g_free (warning_elem);
    }

  refresh_interval = params_value (credentials->params, "refresh_interval");
  if ((refresh_interval == NULL) || (strcmp (refresh_interval, "") == 0))
    g_string_append_printf (string,
                            "<autorefresh interval=\"%s\"/>",
                            credentials->autorefresh);
  else
    {
      int ret;
      gchar *interval_64, *response;
      entity_t entity;

      interval_64 = (refresh_interval
                     ? g_base64_encode ((guchar*) refresh_interval,
                                        strlen (refresh_interval))
                     : g_strdup (""));
      ret = ompf (connection, credentials, &response, &entity, response_data,
                  "<modify_setting"
                  " setting_id=\"578a1c14-e2dc-45ef-a591-89d31391d007\">"
                  "<value>%s</value>"
                  "</modify_setting>",
                  interval_64);
      g_free (interval_64);
      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while modifying the"
                                " autorefresh setting for the settings. "
                                "Diagnostics: Failure to send command to"
                                " manager daemon.",
                                "/omp?cmd=get_my_settings", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while modifying the"
                                " autorefresh setting for the settings. "
                                "Diagnostics: Failure to receive response from"
                                " manager daemon.",
                                "/omp?cmd=get_my_settings", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while modifying the"
                                " autorefresh setting for the settings. "
                                "Diagnostics: Internal Error.",
                                "/omp?cmd=get_my_settings", response_data);
        }

      free_entity (entity);
      g_free (credentials->autorefresh);
      credentials->autorefresh = g_strdup (refresh_interval);
      user_set_autorefresh (credentials->token, refresh_interval);

      g_string_append_printf (string,
                              "<autorefresh interval=\"%s\"/>",
                              credentials->autorefresh);
    }

  g_string_append (string, "<params>");
  params_iterator_init (&iter, credentials->params);
  while (params_iterator_next (&iter, &name, &param))
    {
      if (name && strcmp (name, ""))
        {
          if ((name[strlen (name) - 1] == ':') && param->values)
            {
              gchar *child_name;
              params_iterator_t children_iter;
              param_t *child_param;

              params_iterator_init (&children_iter, param->values);
              while (params_iterator_next (&children_iter, &child_name,
                                           &child_param))
                if (child_param->value
                    && child_param->valid
                    && child_param->valid_utf8)
                  xml_string_append (string,
                                     "<_param>"
                                     "<name>%s%s</name><value>%s</value>"
                                     "</_param>",
                                     name, child_name, child_param->value);
            }

          if (param->value && param->valid && param->valid_utf8
              && strcmp (name, "xml_file") && strcmp (name, "installer"))
            xml_string_append (string, "<%s>%s</%s>", name, param->value, name);
        }
      else
        g_warning ("%s: Param without name found", __FUNCTION__);
    }
  g_string_append (string, "</params>");

  g_string_append_printf (string,
                          "<capabilities>%s</capabilities>"
                          "%s"
                          "</envelope>",
                          credentials->capabilities,
                          xml);
  g_free (xml);

  xml_flag = params_value (credentials->params, "xml");
  if (xml_flag && strcmp (xml_flag, "0"))
    return g_string_free (string, FALSE);

  html = xsl_transform (string->str, response_data);
  g_string_free (string, TRUE);
  if (html == NULL)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      res = g_strdup_printf ("<gsad_response>"
                             "<title>Internal Error</title>"
                             "<message>"
                             "An internal server error has occurred during XSL"
                             " transformation."
                             "</message>"
                             "<backurl>/omp?cmd=get_tasks</backurl>"
                             "</gsad_response>");
      html = xsl_transform (res, response_data);
      if (html == NULL)
        html = g_strdup ("<html>"
                         "<body>"
                         "An internal server error has occurred during XSL"
                         " transformation."
                         "</body>"
                         "</html>");
      g_free (res);
    }
  return html;
}

/**
 * @brief Look for a param with name equal to a given string.
 *
 * @param[in]  params  Params.
 * @param[in]  string  String.
 *
 * @return 1 if param with name \arg string exists in \arg params, else 0.
 */
static int
member (params_t *params, const char *string)
{
  params_iterator_t iter;
  param_t *param;
  char *name;

  params_iterator_init (&iter, params);
  while (params_iterator_next (&iter, &name, &param))
    if (strcmp (name, string) == 0) return 1;
  return 0;
}

/**
 * @brief Look for param with value 1 and name equal to given string.
 *
 * @param[in]  params  Params.
 * @param[in]  string  String.
 *
 * @return 1 if param with name \arg string exists in \arg params, else 0.
 */
int
member1 (params_t *params, const char *string)
{
  params_iterator_t iter;
  param_t *param;
  char *name;

  params_iterator_init (&iter, params);
  while (params_iterator_next (&iter, &name, &param))
    if (param->value_size
        && param->value[0] == '1'
        && strcmp (name, string) == 0)
      return 1;
  return 0;
}

/**
 * @brief Check a modify_config response.
 *
 * @param[in]  credentials  Credentials of user issuing the action.
 * @param[in]  connection   Connection with manager.
 * @param[in]  params       HTTP request parameters.
 * @param[in]  next         Next page command on success.
 * @param[in]  fail_next    Next page command on failure.
 * @param[out] success      Whether the command returned a success response.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return XSL transformed error message on failure, NULL on success.
 */
static char *
check_modify_config (credentials_t *credentials,
                     openvas_connection_t *connection, params_t *params,
                     const char* next, const char* fail_next, int* success,
                     cmd_response_data_t *response_data)
{
  entity_t entity;
  gchar *response;
  const char *no_redirect, *status_text;

  no_redirect = params_value (params, "no_redirect");

  if (success)
    *success = 0;

  /** @todo This would be much easier with real error codes. */

  /* Read the response. */

  if (read_entity_c (connection, &entity))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while saving a config. "
                           "It is unclear whether the entire config has been saved. "
                           "Diagnostics: Failure to read command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  /* Check the response. */

  status_text = entity_attribute (entity, "status_text");
  if (status_text == NULL)
    {
      free_entity (entity);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while saving a config. "
                           "It is unclear whether the entire config has been saved. "
                           "Diagnostics: Failure to parse status_text from response.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (strcmp (status_text, "Config is in use") == 0)
    {
      const char* message = "The config is now in use by a task,"
                            " so only name and comment can be modified.";
      gchar *next_url = next_page_url (credentials, params,
                                       NULL, fail_next,
                                       "Save Config",
                                       entity_attribute (entity, "status"),
                                       message);

      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      response
        = action_result_page (connection, credentials, params, response_data,
                              "Save Config",
                              entity_attribute (entity, "status"),
                              message, NULL, next_url);

      g_free (next_url);
      free_entity (entity);
      return response;
    }
  else if (strcmp (status_text, "MODIFY_CONFIG name must be unique") == 0)
    {
      const char* message = "A config with the given name exists already.";
      gchar *next_url = next_page_url (credentials, params,
                                       NULL, fail_next,
                                       "Save Config",
                                       entity_attribute (entity, "status"),
                                       message);

      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      response
        = action_result_page (connection, credentials, params, response_data,
                              "Save Config",
                              entity_attribute (entity, "status"),
                              message, NULL, next_url);

      g_free (next_url);
      free_entity (entity);
      return response;
    }
  else if (success && omp_success (entity))
    {
      *success = 1;
    }

  response
    = response_from_entity (connection, credentials, params, entity,
                            (no_redirect && strcmp (no_redirect, "0")),
                            NULL, next,
                            NULL, fail_next,
                            "Save Config", response_data);
  free_entity (entity);

  return response;
}

/**
 * @brief Check whether an OMP command failed.
 *
 * @param[in] entity  Response entity.
 *
 * @return 1 success, 0 fail, -1 error.
 */
static int
omp_success (entity_t entity)
{
  const char *status;

  if (entity == NULL)
    return 0;

  status = entity_attribute (entity, "status");
  if ((status == NULL)
      || (strlen (status) == 0))
    return -1;

  return status[0] == '2';
}

/**
 * @brief Set the HTTP status according to OMP response entity.
 *
 * @param[in]  entity         The OMP response entity.
 * @param[in]  response_data  Response data.
 */
void
set_http_status_from_entity (entity_t entity,
                             cmd_response_data_t *response_data)
{
  if (entity == NULL)
    response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
  else if (strcmp (entity_attribute (entity, "status_text"),
              "Permission denied")
           == 0)
    response_data->http_status_code = MHD_HTTP_FORBIDDEN;
  else if (strcmp (entity_attribute (entity, "status"), "404") == 0)
    response_data->http_status_code = MHD_HTTP_NOT_FOUND;
  else
    response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
}

/**
 * @brief Run a single OMP command.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[out] response       Response.
 * @param[out] entity_return  Response entity.
 * @param[out] response_data  Extra data return for the HTTP response.
 * @param[in]  command        Command.
 *
 * @return 0 success, -1 failed to connect (response set), 1 send error, 2 read
 *         error.
 */
static int
omp (openvas_connection_t *connection, credentials_t *credentials,
     gchar **response, entity_t *entity_return,
     cmd_response_data_t *response_data, const char *command)
{
  int ret;
  entity_t entity;

  if (entity_return)
    *entity_return = NULL;

  ret = openvas_connection_sendf (connection, "%s", command);
  if (ret == -1)
    {
      return 1;
    }

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, response))
    {
      return 2;
    }
  if (entity_return)
    *entity_return = entity;
  else
    free_entity (entity);
  return 0;
}

/**
 * @brief Run a single OMP command, preparing a response even on error.
 *
 * @param[in]  connection         Connection to manager
 * @param[out] message_operation  Operation for error message
 * @param[in]  credentials        Username and password for authentication.
 * @param[out] response           Response.
 * @param[out] response_data      Extra data return for the HTTP response.
 * @param[in]  format             Command.
 * @param[in]  ...                Arguments for format string.
 *
 * @return 0 success, -1 internal error, 1 send error, 2 read error,
 *         3 command failed, 4 connect error.
 */
static int
simple_ompf (openvas_connection_t *connection, const gchar *message_operation,
             credentials_t *credentials, gchar **response,
             cmd_response_data_t *response_data, const char *format, ...)
{
  int ret;
  gchar *command;
  va_list args;
  entity_t entity;

  va_start (args, format);
  command = g_markup_vprintf_escaped (format, args);
  va_end (args);

  ret = omp (connection, credentials, response, &entity, response_data,
             command);
  g_free (command);
  switch (ret)
    {
      case 0:
        break;
      case -1:
        /* 'omp' set response. */
        return 4;
      case 1:
        if (response_data)
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        if (response)
          {
            gchar *message;
            message = g_strdup_printf
                       ("An internal error occurred while %s. "
                        " The operation was not started."
                        " Diagnostics: Failure to send command to manager"
                        " daemon.",
                        message_operation
                         ? message_operation
                         : "performing an operation");
            *response = gsad_message (credentials, "Internal error",
                                      __FUNCTION__, __LINE__,
                                      message, "/omp?cmd=get_tasks",
                                      response_data);
            g_free (message);
          }
        return 1;
      case 2:
        if (response_data)
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        if (response)
          {
            gchar *message;
            message = g_strdup_printf
                       ("An internal error occurred while %s."
                        " It is unclear whether the operation succeeded."
                        " Diagnostics: Failure to receive response from manager"
                        " daemon.",
                        message_operation
                         ? message_operation
                         : "performing an operation");
            *response = gsad_message (credentials, "Internal error",
                                      __FUNCTION__, __LINE__,
                                      message, "/omp?cmd=get_tasks",
                                      response_data);
            g_free (message);
          }
        return 2;
      default:
        if (response_data)
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        if (response)
          {
            gchar *message;
            message = g_strdup_printf
                       ("An internal error occurred while %s."
                        " It is unclear whether the operation succeeded."
                        " Diagnostics: Internal Error.",
                        message_operation
                         ? message_operation
                         : "performing an operation");
            *response = gsad_message (credentials, "Internal error",
                                      __FUNCTION__, __LINE__,
                                      message, "/omp?cmd=get_tasks",
                                      response_data);
            g_free (message);
          }
        return -1;
    }

  switch (omp_success (entity))
    {
      case 0:
        set_http_status_from_entity (entity, response_data);
        ret = 3;
        break;
      case 1:
        ret = 0;
        break;
      default:
        ret = -1;
        break;
    }
  free_entity (entity);
  return ret;
}

/**
 * @brief Run a single formatted OMP command.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[out] response       Response.
 * @param[out] entity_return  Response entity.
 * @param[out] response_data  Extra data return for the HTTP response.
 * @param[in]  format         Command.
 * @param[in]  ...            Arguments for format string.
 *
 * @return 0 success, -1 failed to connect (response set), 1 send error,
 *         2 read error.
 */
static int
ompf (openvas_connection_t* connection, credentials_t *credentials,
      gchar **response, entity_t *entity_return,
      cmd_response_data_t *response_data, const char *format, ...)
{
  int ret;
  gchar *command;
  va_list args;

  va_start (args, format);
  command = g_markup_vprintf_escaped (format, args);
  va_end (args);

  ret = omp (connection, credentials, response, entity_return, response_data,
             command);
  g_free (command);
  return ret;
}

/**
 * @brief Get a setting by UUID for the current user of an OMP connection.
 *
 * @param[in]  connection  Connection.
 * @param[in]  setting_id  UUID of the setting to get.
 * @param[out] value       Value of the setting.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return     -1 internal error, 0 success, 1 send error, 2 read error.
 */
static int
setting_get_value (openvas_connection_t *connection, const char *setting_id,
                   gchar **value, cmd_response_data_t *response_data)
{
  int ret;
  entity_t entity;
  const char *status;
  gchar *response;

  *value = NULL;

  ret = openvas_connection_sendf (connection,
                                  "<get_settings setting_id=\"%s\"/>",
                                  setting_id);
  if (ret)
    return 1;

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, &response))
    return 2;

  status = entity_attribute (entity, "status");
  if (status == NULL
      || strlen (status) == 0)
    {
      g_free (response);
      free_entity (entity);
      return -1;
    }

  if (status[0] == '2')
    {
      entity_t setting;
      setting = entity_child (entity, "setting");
      if (setting == NULL)
        {
          free_entity (entity);
          g_free (response);
          return 0;
        }
      setting = entity_child (setting, "value");
      if (setting == NULL)
        {
          free_entity (entity);
          g_free (response);
          return -1;
        }
      *value = g_strdup (entity_text (setting));
      g_free (response);
      free_entity (entity);
    }
  else
    {
      if (response_data)
        set_http_status_from_entity (entity, response_data);
      free_entity (entity);
      g_free (response);
      return -1;
    }

  return 0;
}

/**
 * @brief Check a param.
 *
 * @param[in]  name     Param name.
 * @param[in]  op_name  Operation name.
 * @param[in]  ret_func Function to return message.
 */
#define CHECK_PARAM(name, op_name, ret_func)                                   \
  if (name == NULL)                                                            \
    {                                                                          \
      gchar *msg, *ret_html;                                                   \
      msg = g_strdup_printf (GSAD_MESSAGE_INVALID,                             \
                             "Given " G_STRINGIFY (name) " was invalid",       \
                             op_name);                                         \
      ret_html = ret_func (connection, credentials, params, msg,               \
                           response_data);                                     \
      g_free (msg);                                                            \
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;                  \
      return ret_html;                                                         \
    }

/**
 * @brief Check a param using the direct response method.
 *
 * @param[in]  name      Param name.
 * @param[in]  op_name   Operation name.
 * @param[in]  next_cmd  Next command.
 */
#define CHECK_PARAM_INVALID(name, op_name, next_cmd)                           \
  if (name == NULL)                                                            \
    {                                                                          \
      return message_invalid (connection, credentials, params, response_data,  \
                              "Given " G_STRINGIFY (name) " was invalid",      \
                              G_STRINGIFY (MHD_HTTP_BAD_REQUEST),              \
                              op_name, next_cmd);                              \
    }

/**
 * @brief Get an URL for the current page.
 *
 * @param[in]  credentials  Username and password for authentication.
 * @param[in]  cmd          Command for URL.
 *
 * @return URL.
 */
static char *
page_url (credentials_t *credentials, const gchar *cmd)
{
  GString *url;

  assert (cmd);

  url = g_string_new ("");

  if (credentials->caller && strlen (credentials->caller))
    {
      gchar **split_question, *page, *params;

      split_question = g_strsplit (credentials->caller, "?", 2);

      page = *split_question;

      if (page)
        {
          g_string_append_printf (url, "%s?cmd=%s", page, cmd);
          params = split_question[1];
        }
      else
        {
          g_string_append_printf (url, "cmd=%s", cmd);
          params = credentials->caller;
        }
      if (params)
        {
          gchar **split_amp, **point;

          point = split_amp = g_strsplit (params, "&", 0);
          while (*point)
            {
              gchar *param;

              param = *point;

              g_strstrip (param);

              if (strstr (param, "cmd=") == param)
                {
                  point++;
                  continue;
                }

              g_string_append_printf (url, "&%s", param);

              point++;
            }
          g_strfreev (split_amp);
        }
      g_strfreev (split_question);
    }
  else
    g_string_append_printf (url, "?cmd=%s", cmd);

  return g_string_free (url, FALSE);
}

/**
 * @brief Capitalize a type or command name and replace underscores.
 *
 * @param[in]  input  The input string.
 *
 * @return The newly allocated capitalized type or command name.
 */
static gchar*
capitalize (const char* input)
{
  gchar *output;
  if (input == NULL)
    return NULL;
  else
    {
      int first_letter = 1;
      int pos = 0;
      output = g_strdup (input);

      while (output[pos])
        {
          if (g_ascii_isalpha (output[pos]) && first_letter)
            {
              output[pos] = g_ascii_toupper (output[pos]);
              first_letter = 0;
            }
          else if (output[pos] == '_')
            {
              output[pos] = ' ';
              first_letter = 1;
            }
          pos++;
        }
      return output;
    }
}


/* Generic page handlers. */

/**
 * @brief Generate a page URL for a redirect.
 *
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  override_next  Command to redirect to, ignoring "next" or NULL.
 * @param[in]  default_next   Command to redirect to if next" is missing.
 * @param[in]  prev_action    Previous action.
 * @param[in]  action_status  Status code of previous action.
 * @param[in]  action_message Status message of previous action.
 *
 * @return  Newly allocated redirect URL.
 */
static gchar *
next_page_url (credentials_t *credentials, params_t *params,
               const char* override_next, const char *default_next,
               const char* prev_action, const char* action_status,
               const char* action_message)
{
  GString *url;
  const char *next_cmd, *xml_param, *next_xml_param;
  params_iterator_t iter;
  gchar *param_name;
  param_t *current_param;
  int error;
  if (action_status && strcmp (action_status, "") && action_status[0] != '2')
    error = 1;
  else
    error = 0;

  url = g_string_new ("/omp?cmd=");

  if (override_next)
    next_cmd = override_next;
  else if (error && params_valid (params, "next_error"))
    next_cmd = params_value (params, "next_error");
  else if (!error && params_valid (params, "next"))
    next_cmd = params_value (params, "next");
  else if (default_next)
    next_cmd = default_next;
  else
    next_cmd = "get_tasks";

  xml_param = params_value (params, "xml");
  next_xml_param = params_value (params, "next_xml");

  g_string_append (url, next_cmd);

  params_iterator_init (&iter, params);
  while (params_iterator_next (&iter, &param_name, &current_param))
    {
      if (strcmp (param_name, "asset_type") == 0
          || strcmp (param_name, "filter") == 0
          || strcmp (param_name, "filt_id") == 0
          || (strstr (param_name, "_id")
                == param_name + strlen (param_name) - strlen ("_id"))
          || (strcmp (param_name, "name") == 0
              && strcasecmp (prev_action, "Run Wizard") == 0)
          || (strcmp (param_name, "get_name") == 0
              && strcasecmp (next_cmd, "wizard_get") == 0))
        {
          g_string_append_printf (url, "&%s=%s",
                                  param_name,
                                  current_param->value
                                    ? current_param->value
                                    : "");
        }
    }

  if (next_xml_param)
    {
      g_string_append_printf (url, "&xml=%s", next_xml_param);
    }
  else if (xml_param)
    {
      g_string_append_printf (url, "&xml=%s", xml_param);
    }

  if (action_status)
    {
      gchar *escaped = g_uri_escape_string (action_status, NULL, FALSE);
      g_string_append_printf (url, "&action_status=%s", escaped);
      g_free (escaped);
    }

  if (action_message)
    {
      gchar *escaped = g_uri_escape_string (action_message, NULL, FALSE);
      g_string_append_printf (url, "&action_message=%s", escaped);
      g_free (escaped);
    }

  if (prev_action)
    {
      gchar *escaped = g_uri_escape_string (prev_action, NULL, FALSE);
      g_string_append_printf (url, "&prev_action=%s", escaped);
      g_free (escaped);
    }


  g_string_append_printf (url, "&token=%s", credentials->token);

  return g_string_free (url, FALSE);
}

/**
 * @brief Generate a page containing a result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 * @param[in]  action         Name of the action.
 * @param[in]  status         Status code.
 * @param[in]  message        Status message.
 * @param[in]  details        Status details.
 * @param[in]  next_url       URL of next page.
 *
 * @return Result of XSL transformation.
 */
static gchar *
action_result_page (openvas_connection_t *connection,
                    credentials_t *credentials, params_t *params,
                    cmd_response_data_t *response_data,
                    const char* action, const char* status,
                    const char* message, const char* details,
                    const char* next_url)
{
  gchar *xml;
  xml = g_markup_printf_escaped ("<action_result>"
                                 "<action>%s</action>"
                                 "<status>%s</status>"
                                 "<message>%s</message>"
                                 "<details>%s</details>"
                                 "<next>%s</next>"
                                 "</action_result>",
                                 action ? action : "",
                                 status ? status : "",
                                 message ? message : "",
                                 details ? details : "",
                                 next_url ? next_url : "");
  return xsl_transform_omp (connection, credentials, params, xml,
                            response_data);
}

/**
 * @brief Check a param using the direct response method.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  response_data  Response data.
 * @param[in]  message        Message.
 * @param[in]  status         Status code.
 * @param[in]  op_name        Operation name.
 * @param[in]  next_cmd       Next command.
 *
 * @return Result of XSL transformation.
 */
gchar *
message_invalid (openvas_connection_t *connection, credentials_t *credentials,
                 params_t *params, cmd_response_data_t *response_data,
                 const char *message, const char *status,
                 const char *op_name, const char *next_cmd)
{
  gchar *ret;
  gchar *next_url;

  next_url = next_page_url (credentials, params, next_cmd, NULL, op_name,
                            status, message);
  ret = action_result_page (connection, credentials, params, response_data,
                            op_name, G_STRINGIFY (MHD_HTTP_BAD_REQUEST),
                            message, NULL,
                            next_url);
  g_free (next_url);
  response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
  return ret;
}

/**
 * @brief Set redirect or return a basic action_result page based on entity.
 *
 * @param[in]  connection     Connection to manager
 */
static gchar*
response_from_entity (openvas_connection_t *connection,
                      credentials_t* credentials, params_t *params,
                      entity_t entity, int no_redirect,
                      const char* override_next, const char *default_next,
                      const char* override_fail_next,
                      const char* default_fail_next,
                      const char* action, cmd_response_data_t *response_data)
{
  gchar *res, *next_url;
  entity_t status_details_entity;
  const char *status_details;
  int success;
  success = omp_success (entity);

  if (success)
    {
      next_url = next_page_url (credentials, params,
                                override_next, default_next,
                                action,
                                entity_attribute (entity, "status"),
                                entity_attribute (entity, "status_text"));
    }
  else
    {
      set_http_status_from_entity (entity, response_data);
      next_url = next_page_url (credentials, params,
                                override_fail_next, default_fail_next,
                                action,
                                entity_attribute (entity, "status"),
                                entity_attribute (entity, "status_text"));
    }

  status_details_entity = entity_child (entity, "status_details");
  if (status_details_entity)
    {
      status_details = status_details_entity->text;
    }
  else
    {
      status_details = NULL;
    }

  if (no_redirect || success == 0)
    {
      res = action_result_page (connection, credentials, params, response_data,
                                action, entity_attribute (entity, "status"),
                                entity_attribute (entity, "status_text"),
                                status_details, next_url);
      g_free (next_url);
    }
  else
    {
      res = NULL;
      response_data->redirect = next_url;
    }
  return res;
}

/**
 * @brief Generate a page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  response       Extra XML to insert inside page element for XSLT.
 * @param[in]  next           Command.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
generate_page (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, gchar *response, const gchar *next,
               cmd_response_data_t* response_data)
{
  credentials->current_page = page_url (credentials, next);
  if (g_utf8_validate (credentials->current_page, -1, NULL) == FALSE)
    {
      g_free (credentials->current_page);
      g_warning ("%s - current_page is not valid UTF-8", __FUNCTION__);
      credentials->current_page = NULL;
    }

  if (strcmp (next, "edit_role") == 0)
    return edit_role (connection, credentials, params, response, response_data);

  if (strcmp (next, "edit_task") == 0)
    return edit_task (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_alerts") == 0)
    return get_alerts (connection, credentials, params, response,
                       response_data);

  if (strcmp (next, "get_alert") == 0)
    return get_alert (connection, credentials, params, response, response_data);

  if (strcmp (next, "edit_port_list") == 0)
    return edit_port_list (connection, credentials, params, response,
                           response_data);

  if (strcmp (next, "get_agents") == 0)
    return get_agents (connection, credentials, params, response,
                       response_data);

  if (strcmp (next, "get_agent") == 0)
    return get_agent (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_asset") == 0)
    return get_asset (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_assets") == 0)
    return get_assets (connection, credentials, params, response,
                       response_data);

  if (strcmp (next, "get_assets_chart") == 0)
    return get_assets_chart (connection, credentials, params, response,
                             response_data);

  if (strcmp (next, "get_config") == 0)
    return get_config (connection, credentials, params, response, 0,
                       response_data);

  if (strcmp (next, "get_configs") == 0)
    return get_configs (connection, credentials, params, response,
                        response_data);

  if (strcmp (next, "get_filter") == 0)
    return get_filter (connection, credentials, params, response,
                       response_data);

  if (strcmp (next, "get_filters") == 0)
    return get_filters (connection, credentials, params, response,
                        response_data);

  if (strcmp (next, "get_group") == 0)
    return get_group (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_groups") == 0)
    return get_groups (connection, credentials, params, response,
                       response_data);

  if (strcmp (next, "get_credential") == 0)
    return get_credential (connection, credentials, params, response,
                           response_data);

  if (strcmp (next, "get_credentials") == 0)
    return get_credentials (connection, credentials, params, response,
                            response_data);

  if (strcmp (next, "get_note") == 0)
    return get_note (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_notes") == 0)
    return get_notes (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_nvts") == 0)
    return get_nvts (connection, credentials, params, NULL, response,
                     response_data);

  if (strcmp (next, "get_override") == 0)
    return get_override (connection, credentials, params, response,
                         response_data);

  if (strcmp (next, "get_overrides") == 0)
    return get_overrides (connection, credentials, params, response,
                          response_data);

  if (strcmp (next, "get_permission") == 0)
    return get_permission (connection, credentials, params, response,
                           response_data);

  if (strcmp (next, "get_permissions") == 0)
    return get_permissions (connection, credentials, params, response,
                            response_data);

  if (strcmp (next, "get_port_list") == 0)
    return get_port_list (connection, credentials, params, response,
                          response_data);

  if (strcmp (next, "get_port_lists") == 0)
    return get_port_lists (connection, credentials, params, response,
                           response_data);

  if (strcmp (next, "get_tag") == 0)
    return get_tag (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_tags") == 0)
    return get_tags (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_target") == 0)
    return get_target (connection, credentials, params, response,
                       response_data);

  if (strcmp (next, "get_targets") == 0)
    return get_targets (connection, credentials, params, response,
                        response_data);

  if (strcmp (next, "get_task") == 0)
    return get_task (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_tasks") == 0)
    return get_tasks (connection, credentials, params, response,
                      response_data);

  if (strcmp (next, "get_tasks_chart") == 0)
    return get_tasks_chart (connection, credentials, params, response,
                            response_data);

  if (strcmp (next, "get_report") == 0)
    {
      char *result;
      int error = 0;

      result = get_report (connection, credentials, params, NULL, NULL, NULL,
                           NULL, response, &error, response_data);

      return error ? result : xsl_transform_omp (connection, credentials,
                                                 params, result,
                                                 response_data);
    }

  if (strcmp (next, "get_report_format") == 0)
    return get_report_format (connection, credentials, params, response,
                              response_data);

  if (strcmp (next, "get_report_formats") == 0)
    return get_report_formats (connection, credentials, params, response,
                               response_data);

  if (strcmp (next, "get_report_section") == 0)
    return get_report_section (connection, credentials, params, response,
                               response_data);

  if (strcmp (next, "get_reports") == 0)
    return get_reports (connection, credentials, params, response,
                        response_data);

  if (strcmp (next, "get_results") == 0)
    return get_results (connection, credentials, params, response,
                        response_data);

  if (strcmp (next, "get_result") == 0)
    return get_result_page (connection, credentials, params, response,
                            response_data);

  if (strcmp (next, "get_role") == 0)
    return get_role (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_roles") == 0)
    return get_roles (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_scanner") == 0)
    return get_scanner (connection, credentials, params, response,
                        response_data);

  if (strcmp (next, "get_scanners") == 0)
    return get_scanners (connection, credentials, params, response,
                         response_data);

  if (strcmp (next, "get_schedule") == 0)
    return get_schedule (connection, credentials, params, response,
                         response_data);

  if (strcmp (next, "get_schedules") == 0)
    return get_schedules (connection, credentials, params, response,
                          response_data);

  if (strcmp (next, "get_user") == 0)
    return get_user (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_users") == 0)
    return get_users (connection, credentials, params, response, response_data);

  if (strcmp (next, "get_info") == 0)
    return get_info (connection, credentials, params, response, response_data);

  if (strcmp (next, "wizard") == 0)
    return wizard (connection, credentials, params, response, response_data);

  if (strcmp (next, "wizard_get") == 0)
    return wizard_get (connection, credentials, params, response,
                       response_data);

  return NULL;
}

/**
 * @brief Generate next page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  response       Extra XML to insert inside page element for XSLT.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
next_page (openvas_connection_t *connection, credentials_t *credentials,
           params_t *params, gchar *response,
           cmd_response_data_t* response_data)
{
  const char *next;

  next = params_value (params, "next");
  if (next == NULL)
    return NULL;

  return generate_page (connection, credentials, params, response, next,
                        response_data);
}

/**
 * @brief Get one resource, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  type           Type of resource.
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[in]  extra_attribs  Extra attributes for OMP GET command.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_one (openvas_connection_t *connection, const char *type,
         credentials_t * credentials, params_t *params,
         const char *extra_xml, const char *extra_attribs,
         cmd_response_data_t* response_data)
{
  GString *xml;
  int ret;
  gchar *end, *id_name;
  const char *id, *sort_field, *sort_order, *filter, *first, *max;

  id_name = g_strdup_printf ("%s_id", type);
  id = params_value (params, id_name);
  g_free (id_name);
  sort_field = params_value (params, "sort_field");
  sort_order = params_value (params, "sort_order");

  if (id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a resource. "
                           "Diagnostics: missing ID.",
                           "/omp?cmd=get_tasks", response_data);
    }

  xml = g_string_new ("");
  g_string_append_printf (xml, "<get_%s>", type);

  if (strcmp (type, "role") == 0
      && command_enabled (credentials, "GET_PERMISSIONS")
      && params_value (params, "role_id"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (ompf (connection, credentials, &response, &entity, response_data,
                    "<get_permissions"
                    " filter=\"rows=-1 subject_type=role and subject_uuid=%s\"/>",
                    params_value (params, "role_id")))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting permissions. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_roles", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting permissions. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_roles", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting permissins. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_roles", response_data);
        }

      g_string_append (xml, response);

      if (!omp_success (entity))
        set_http_status_from_entity (entity, response_data);

      free_entity (entity);
      g_free (response);
    }

  /* Pass through params for get_resources. */
  filter = params_value (params, "filter");
  first = params_value (params, "first");
  max = params_value (params, "max");
  end = g_markup_printf_escaped ("<filters><term>%s</term></filters>"
                                 "<%ss start=\"%s\" max=\"%s\"/>",
                                 filter ? filter : "",
                                 type,
                                 first ? first : "",
                                 max ? max : "");
  g_string_append (xml, end);
  g_free (end);

  if (extra_xml)
    g_string_append (xml, extra_xml);

  /* Get the resource. */

  if (openvas_connection_sendf (connection,
                                "<get_%ss"
                                " %s_id=\"%s\""
                                " sort_field=\"%s\""
                                " sort_order=\"%s\""
                                " details=\"1\""
                                " %s/>",
                                type,
                                type,
                                id,
                                sort_field ? sort_field : "name",
                                sort_order ? sort_order : "ascending",
                                extra_attribs ? extra_attribs : "")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting resources list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting resources list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  /* Get tag names */

  if (openvas_connection_sendf (connection,
                                "<get_tags"
                                " filter=\"resource_type=%s"
                                "          first=1"
                                "          rows=-1\""
                                " names_only=\"1\""
                                "/>",
                                type)
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting tag names list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting tag names list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  /* Get permissions */

  g_string_append (xml, "<permissions>");

  if ((strcmp (type, "user") == 0)
      || (strcmp (type, "group") == 0)
      || (strcmp (type, "role") == 0))
    ret = openvas_connection_sendf (connection,
                                    "<get_permissions"
                                    " filter=\"subject_uuid=%s"
                                    "          and not resource_uuid=&quot;&quot;"
                                    "          or resource_uuid=%s"
                                    "          first=1 rows=-1\"/>",
                                    id,
                                    id);
  else
    ret = openvas_connection_sendf (connection,
                                    "<get_permissions"
                                    " filter=\"resource_uuid=%s"
                                    "          first=1 rows=-1\"/>",
                                    id);
  if (ret == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting permissions list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting permissions list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  g_string_append (xml, "</permissions>");

  /* Cleanup, and return transformed XML. */

  g_string_append_printf (xml, "</get_%s>", type);
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Get all of a particular type of resource, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  type           Resource type.
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[in]  extra_attribs  Extra attributes for OMP GET command.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_many (openvas_connection_t *connection, const char *type,
          credentials_t * credentials, params_t *params,
          const char *extra_xml, const char *extra_attribs,
          cmd_response_data_t* response_data)
{
  GString *xml;
  GString *type_many; /* The plural form of type */
  gchar *filter_type, *request, *built_filter;
  int no_filter_history;
  const char *build_filter, *given_filt_id, *filt_id, *filter, *filter_extra;
  const char *first, *max, *sort_field, *sort_order, *owner, *permission;
  const char *replace_task_id;
  const char *overrides, *autofp, *autofp_value, *min_qod;
  const char *level_high, *level_medium, *level_low, *level_log;
  const char *level_false_positive;

  no_filter_history = params_value(params, "no_filter_history")
                        ? atoi (params_value(params, "no_filter_history"))
                        : 0;
  build_filter = params_value(params, "build_filter");
  given_filt_id = params_value (params, "filt_id");
  filter = params_value (params, "filter");
  filter_extra = params_value (params, "filter_extra");
  first = params_value (params, "first");
  max = params_value (params, "max");
  replace_task_id = params_value (params, "replace_task_id");
  sort_field = params_value (params, "sort_field");
  sort_order = params_value (params, "sort_order");
  owner = params_value (params, "owner");
  permission = params_value (params, "permission");
  overrides = params_value (params, "overrides");
  autofp = params_value (params, "autofp");
  autofp_value = params_value (params, "autofp_value");
  min_qod = params_value (params, "min_qod");
  level_high = params_value (params, "level_high");
  level_medium = params_value (params, "level_medium");
  level_low = params_value (params, "level_low");
  level_log = params_value (params, "level_log");
  level_false_positive = params_value (params, "level_false_positive");

  if (strcasecmp (type, "info") == 0)
    filter_type = g_strdup (params_value (params, "info_type"));
  else
    filter_type = g_strdup (type);

  if (given_filt_id)
    {
      if (no_filter_history == 0
          && strcmp (given_filt_id, "0") && strcmp (given_filt_id, "-2"))
        g_tree_replace (credentials->last_filt_ids, filter_type,
                        g_strdup (given_filt_id));
      filt_id = given_filt_id;
    }
  else
    {
      if (no_filter_history == 0
          && (filter == NULL || strcmp (filter, "") == 0))
        filt_id = g_tree_lookup (credentials->last_filt_ids, filter_type);
      else
        filt_id = NULL;
      g_free (filter_type);
    }

  /* check if filter still exists */
  switch (filter_exists (connection, filt_id))
    {
      case 1:
        break;
      case 0:
        g_debug ("%s filter doesn't exist anymore %s!\n", __FUNCTION__,
                 filt_id);
        filt_id = NULL;
        break;
      case -1:
        g_debug ("%s filter response didn't contain a status!\n", __FUNCTION__);
        filt_id = NULL;
        break;
      case -2:
        g_debug ("%s could not send filter request!\n", __FUNCTION__);
        filt_id = NULL;
        break;
      case -3:
        g_debug ("%s could not read entity from filter response!\n",
                 __FUNCTION__);
        filt_id = NULL;
        break;
      default:
        filt_id = NULL;
    }

  xml = g_string_new ("");
  type_many = g_string_new (type);

  /* Workaround the fact that info is a non countable noun */
  if (strcmp (type, "info") != 0)
    g_string_append (type_many, "s");

  g_string_append_printf (xml, "<get_%s>", type_many->str);

  if (extra_xml)
    g_string_append (xml, extra_xml);

  built_filter = NULL;
  if (filt_id == NULL
      || (strcmp (filt_id, "") == 0)
      || (strcmp (filt_id, "--") == 0))
    {
      if ((build_filter && (strcmp (build_filter, "1") == 0))
          || ((filter == NULL || strcmp (filter, "") == 0)
              && (filter_extra == NULL || strcmp (filter_extra, "") == 0)))
        {
          if (build_filter && (strcmp (build_filter, "1") == 0))
            {
              gchar *task;
              const char *search_phrase, *task_id;

              if (strcmp (type, "report") == 0
                  || strcmp (type, "task") == 0)
                {
                  task = g_strdup_printf ("apply_overrides=%i min_qod=%s ",
                                          overrides
                                          && strcmp (overrides, "0"),
                                          min_qod ? min_qod : "");
                }
              else if (strcmp (type, "result") == 0)
                {
                  gchar *levels
                    = g_strdup_printf ("%s%s%s%s%s",
                                       level_high ? "h" : "",
                                       level_medium ? "m" : "",
                                       level_low ? "l" : "",
                                       level_log ? "g" : "",
                                       level_false_positive ? "f" : "");
                  task = g_strdup_printf ("apply_overrides=%i min_qod=%s"
                                          " autofp=%s levels=%s ",
                                          (overrides
                                           && strcmp (overrides, "0")),
                                          min_qod ? min_qod : "",
                                          (autofp && autofp_value)
                                            ? autofp_value : "0",
                                          levels);
                  g_free (levels);
                }
              else
                task = NULL;

              search_phrase = params_value (params, "search_phrase");
              task_id = params_value (params, "task_id");
              built_filter = g_strdup_printf
                              ("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                               task ? task : "",
                               task_id ? "task_id=" : "",
                               task_id ? task_id : "",
                               task_id ? " " : "",
                               first ? "first=" : "",
                               first ? first : "",
                               first ? " " : "",
                               max ? "rows=" : "",
                               max ? max : "",
                               max ? " " : "",
                               sort_field
                                ? ((sort_order && strcmp (sort_order,
                                                          "ascending"))
                                    ? "sort-reverse="
                                    : "sort=")
                                : "",
                               sort_field ? sort_field : "",
                               sort_field ? " " : "",
                               permission ? "permission=" : "",
                               permission ? permission : "",
                               permission ? " " : "",
                               owner ? "owner=" : "",
                               owner ? owner : "",
                               owner ? " " : "",
                               (filter && search_phrase) ? " " : "",
                               filter ? filter : "",
                               search_phrase ? " " : "",
                               search_phrase
                                ? search_phrase
                                : "");
              filt_id = "-2";
              g_free (task);
            }
          else if (strcmp (type, "info") == 0
                   && params_value (params, "info_type"))
            {
              if (strcmp (params_value (params, "info_type"), "cve") == 0)
                filter = "sort-reverse=published rows=-2";
              else
                filter = "sort-reverse=created rows=-2";
            }
          else if (strcmp (type, "user") == 0)
            filter = "sort=roles rows=-2";
          else if (strcmp (type, "report") == 0)
            {
              const char *task_id;
              task_id = params_value (params, "task_id");
              if (task_id)
                built_filter = g_strdup_printf ("task_id=%s apply_overrides=1"
                                                " rows=-2 sort-reverse=date",
                                                task_id);
              else
                filter = "apply_overrides=1 rows=-2 sort-reverse=date";
            }
          else if (strcmp (type, "result") == 0)
            {
              built_filter
                = g_strdup_printf("apply_overrides=%d autofp=%s rows=-2"
                                  " sort-reverse=created",
                                  (overrides == NULL
                                   || strcmp (overrides, "0")),
                                  (autofp && strcmp (autofp, "0"))
                                    ? autofp_value
                                    : "0");
            }
          else if (strcmp (type, "task"))
            filter = "rows=-2";
          else
            filter = "apply_overrides=1 rows=-2";
          if (filt_id && strcmp (filt_id, ""))
            /* Request to use "filter" instead. */
            filt_id = "0";
          else
            filt_id = "-2";
        }
      else if ((strcmp (filter, "sort=nvt") == 0)
               && ((strcmp (type, "note") == 0)
                   || (strcmp (type, "override") == 0)))
        filt_id = "-2";
      else if ((strcmp (filter, "apply_overrides=1") == 0)
               && (strcmp (type, "task") == 0))
        filt_id = "-2";
    }
  else if (replace_task_id)
    {
      const char *task_id;
      task_id = params_value (params, "task_id");
      if (task_id)
        built_filter = g_strdup_printf ("task_id=%s %s",
                                        task_id,
                                        filter ? filter : "");
    }

  /* Get the list. */

  request = g_markup_printf_escaped (" %sfilt_id=\"%s\""
                                     " %sfilter=\"%s%s%s%s\""
                                     " filter_replace=\"%s\""
                                     " first=\"%s\""
                                     " max=\"%s\""
                                     " sort_field=\"%s\""
                                     " sort_order=\"%s\"",
                                     strcmp (type, "report") ? "" : "report_",
                                     filt_id ? filt_id : "0",
                                     strcmp (type, "report") ? "" : "report_",
                                     built_filter
                                      ? built_filter
                                      : (filter ? filter : ""),
                                     filter_extra ? " " : "",
                                     filter_extra ? filter_extra : "",
                                     filter_extra ? " " : "",
                                     replace_task_id ? "task_id" : "",
                                     first ? first : "1",
                                     max ? max : "-2",
                                     sort_field ? sort_field : "name",
                                     sort_order ? sort_order : "ascending");

  g_free (built_filter);
  if (openvas_connection_sendf (connection,
                                "<get_%s%s%s %s/>",
                                type_many->str,
                                strcmp (type, "report") ? "" : " details=\"0\"",
                                request,
                                extra_attribs ? extra_attribs : "")
      == -1)
    {
      g_free(request);
      g_string_free (xml, TRUE);
      g_string_free (type_many, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a resource list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }
  g_free(request);
  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      g_string_free (type_many, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting resources list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  // TODO: Test response

  if (command_enabled (credentials, "GET_FILTERS"))
    {
      /* Get the filters. */

      g_string_append (xml, "<filters>");

      if (openvas_connection_sendf_xml
           (connection,
            "<get_filters"
            " filter=\"rows=-1 type=%s or type=\"/>",
            type)
          == -1)
        {
          g_string_free (xml, TRUE);
          g_string_free (type_many, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the filter list. "
                               "The current list of filters is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          g_string_free (type_many, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the filter list. "
                               "The current list of filters is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      g_string_append (xml, "</filters>");
    }

  if (command_enabled (credentials, "GET_SETTINGS"))
    {
      /* Get the Wizard Rows setting. */

      if (openvas_connection_sendf_xml
           (connection,
            "<get_settings"
            " setting_id=\"20f3034c-e709-11e1-87e7-406186ea4fc5\"/>",
            type)
          == -1)
        {
          g_string_free (xml, TRUE);
          g_string_free (type_many, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the filter list. "
                               "The current list of filters is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          g_string_free (type_many, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the filter list. "
                               "The current list of filters is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  if (command_enabled (credentials, "GET_TAGS")
      && params_value (params, "details"))
    {
      /* Get tag names */

      if (openvas_connection_sendf (connection,
                                    "<get_tags"
                                    " filter=\"resource_type=%s"
                                    "          first=1"
                                    "          rows=-1\""
                                    " names_only=\"1\""
                                    "/>",
                                    strcmp (type, "info")
                                      ? type
                                      : params_value (params, "info_type"))
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while getting tag names list. "
                              "The current list of resources is not available. "
                              "Diagnostics: Failure to send command to manager daemon.",
                              "/omp?cmd=get_resources", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while getting tag names list. "
                              "The current list of resources is not available. "
                              "Diagnostics: Failure to receive response from manager daemon.",
                              "/omp?cmd=get_resources", response_data);
        }
    }

  /* Cleanup, and return transformed XML. */
  g_string_append_printf (xml, "</get_%s>", type_many->str);
  g_string_free (type_many, TRUE);
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup edit XML, XSL transform the result.
 *
 * @param[in]  connection         Connection to manager
 * @param[in]  type               Type or resource to edit.
 * @param[in]  credentials        Username and password for authentication.
 * @param[in]  params             Request parameters.
 * @param[in]  extra_get_attribs  Extra attributes for the get_... command.
 * @param[in]  extra_xml          Extra XML to insert inside page element.
 * @param[out] response_data      Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_resource (openvas_connection_t *connection, const char *type,
               credentials_t *credentials, params_t *params,
               const char *extra_get_attribs, const char *extra_xml,
               cmd_response_data_t* response_data)
{
  GString *xml;
  gchar *id_name;
  const char *resource_id;

  id_name = g_strdup_printf ("%s_id", type);
  resource_id = params_value (params, id_name);
  g_free (id_name);

  if (resource_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing a resource. "
                           "The resource remains as it was. "
                           "Diagnostics: Required ID parameter was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (openvas_connection_sendf (connection,
                                /* TODO: Remove redundant COMMANDS. */
                                "<commands>"
                                "<get_%ss"
                                " %s"
                                " %s_id=\"%s\""
                                " details=\"1\"/>"
                                "</commands>",
                                type,
                                extra_get_attribs ? extra_get_attribs : "",
                                type,
                                resource_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a resource. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  xml = g_string_new ("");

  g_string_append_printf (xml, "<edit_%s>", type);

  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a resource. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append_printf (xml, "</edit_%s>", type);
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Generates a file name for exporting.
 *
 * @param[in]   fname_format      Format string.
 * @param[in]   credentials       Current credentials.
 * @param[in]   type              Type of resource.
 * @param[in]   uuid              UUID of resource.
 * @param[in]   resource_entity   Resource entity to extract extra data from.
 *
 * @return The file name.
 */
gchar *
format_file_name (gchar* fname_format, credentials_t* credentials,
                  const char* type, const char* uuid,
                  entity_t resource_entity)
{
  gchar *creation_time, *modification_time, *name, *format_name;
  gchar *ret;

  if (resource_entity)
    {
      entity_t creation_time_entity, modification_time_entity;
      entity_t task_entity, format_entity, format_name_entity, name_entity;

      creation_time_entity = entity_child (resource_entity,
                                           "creation_time");

      if (creation_time_entity)
        creation_time = entity_text (creation_time_entity);
      else
        creation_time = NULL;

      modification_time_entity = entity_child (resource_entity,
                                               "modification_time");

      if (modification_time_entity)
        modification_time = entity_text (modification_time_entity);
      else
        modification_time = NULL;

      if (strcasecmp (type, "report") == 0)
        {
          task_entity = entity_child (resource_entity, "task");
          if (task_entity)
            name_entity = entity_child (task_entity, "name");
          else
            name_entity = NULL;

          format_entity = entity_child (resource_entity, "report_format");
          if (format_entity)
            {
              format_name_entity = entity_child (format_entity, "name");
            }
          else
            format_name_entity = NULL;

          if (format_name_entity && strlen (entity_text (format_name_entity)))
            format_name = entity_text (format_name_entity);
          else
            format_name = NULL;
        }
      else
        {
          name_entity = entity_child (resource_entity, "name");
          format_name = NULL;
        }

      if (name_entity)
        name = entity_text (name_entity);
      else
        name = NULL;
    }
  else
    {
      creation_time = NULL;
      modification_time = NULL;
      name = NULL;
      format_name = NULL;
    }

  ret = openvas_export_file_name (fname_format, credentials->username,
                                  type, uuid, creation_time, modification_time,
                                  name, format_name);
  return ret;
}


/**
 * @brief Export a resource.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   type                 Type of resource.
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Resource XML on success.  HTML result of XSL transformation on error.
 */
char *
export_resource (openvas_connection_t *connection, const char *type,
                 credentials_t * credentials, params_t *params,
                 enum content_type * content_type,
                 char **content_disposition, gsize *content_length,
                 cmd_response_data_t* response_data)
{
  GString *xml;
  entity_t entity;
  entity_t resource_entity;
  char *content = NULL;
  gchar *id_name;
  gchar *fname_format, *file_name;
  int ret;
  const char *resource_id, *subtype;

  *content_length = 0;

  xml = g_string_new ("");

  id_name = g_strdup_printf ("%s_id", type);
  resource_id = params_value (params, id_name);
  g_free (id_name);

  if (resource_id == NULL)
    {
      g_string_append (xml, GSAD_MESSAGE_INVALID_PARAM ("Export Resource"));
      return xsl_transform_omp (connection, credentials, params,
                                g_string_free (xml, FALSE), response_data);
    }

  subtype = params_value (params, "subtype");

  if (openvas_connection_sendf (connection,
                                "<get_%ss"
                                " %s_id=\"%s\""
                                "%s%s%s"
                                " export=\"1\""
                                " details=\"1\"/>",
                                type,
                                type,
                                resource_id,
                                subtype ? " type=\"" : "",
                                subtype ? subtype : "",
                                subtype ? "\"" : "")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a resource. "
                           "The resource could not be delivered. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, &content))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a resource. "
                           "The resource could not be delivered. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (!omp_success (entity))
    set_http_status_from_entity (entity, response_data);

  resource_entity = entity_child (entity, type);

  if (resource_entity == NULL)
    {
      g_free (content);
      free_entity (entity);
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a resource. "
                           "The resource could not be delivered. "
                           "Diagnostics: Failure to receive resource from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  ret = setting_get_value (connection,
                           "a6ac88c5-729c-41ba-ac0a-deea4a3441f2",
                           &fname_format,
                           response_data);
  if (ret)
    {
      g_free (content);
      free_entity (entity);
      g_string_free (xml, TRUE);
      switch (ret)
        {
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a setting. "
                                "The setting could not be delivered. "
                                "Diagnostics: Failure to send command to manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a setting. "
                                "The setting could not be delivered. "
                                "Diagnostics: Failure to receive response from manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a setting. "
                                "The setting could not be delivered. "
                                "Diagnostics: Internal error.",
                                "/omp?cmd=get_tasks", response_data);
        }
    }

  if (fname_format == NULL)
    {
      g_warning ("%s : File name format setting not found.", __FUNCTION__);
      fname_format = "%T-%U";
    }

  file_name = format_file_name (fname_format, credentials, type, resource_id,
                                resource_entity);
  if (file_name == NULL)
    file_name = g_strdup_printf ("%s-%s", type, resource_id);

  *content_type = GSAD_CONTENT_TYPE_APP_XML;
  *content_disposition = g_strdup_printf ("attachment; filename=\"%s.xml\"",
                                          file_name);
  *content_length = strlen (content);
  free_entity (entity);
  g_free (file_name);
  g_string_free (xml, TRUE);
  return content;
}

/**
 * @brief Export a list of resources.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return XML on success.  HTML result of XSL transformation on error.
 */
static char *
export_many (openvas_connection_t *connection,const char *type,
             credentials_t * credentials, params_t *params,
             enum content_type * content_type, char **content_disposition,
             gsize *content_length, cmd_response_data_t* response_data)
{
  entity_t entity;
  char *content = NULL;
  const char *filter;
  gchar *filter_escaped;
  gchar *type_many;
  gchar *fname_format, *file_name;
  int ret;

  *content_length = 0;

  filter = params_value (params, "filter");

  filter_escaped = g_markup_escape_text (filter, -1);

  if (strcmp (type, "info") == 0)
    {
      if (openvas_connection_sendf (connection,
                                    "<get_info"
                                    " type=\"%s\""
                                    " export=\"1\""
                                    " details=\"1\""
                                    " filter=\"%s\"/>",
                                    params_value (params, "info_type"),
                                    filter_escaped ? filter_escaped : "")
          == -1)
        {
          g_free (filter_escaped);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while getting a list. "
                              "The list could not be delivered. "
                              "Diagnostics: Failure to send command to manager daemon.",
                              "/omp?cmd=get_tasks", response_data);
        }
    }
  else if (strcmp (type, "asset") == 0)
    {
      if (openvas_connection_sendf (connection,
                                    "<get_assets"
                                    " type=\"%s\""
                                    " export=\"1\""
                                    " details=\"1\""
                                    " filter=\"%s\"/>",
                                    params_value (params, "asset_type"),
                                    filter_escaped ? filter_escaped : "")
          == -1)
        {
          g_free (filter_escaped);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while getting a list. "
                              "The list could not be delivered. "
                              "Diagnostics: Failure to send command to manager daemon.",
                              "/omp?cmd=get_tasks", response_data);
        }
    }
  else
    {
      if (openvas_connection_sendf (connection,
                                    "<get_%ss"
                                    " export=\"1\""
                                    " details=\"1\""
                                    " filter=\"%s\"/>",
                                    type,
                                    filter_escaped ? filter_escaped : "")
          == -1)
        {
          g_free (filter_escaped);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while getting a list. "
                              "The list could not be delivered. "
                              "Diagnostics: Failure to send command to manager daemon.",
                              "/omp?cmd=get_tasks", response_data);
        }
    }
  g_free (filter_escaped);

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, &content))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a list. "
                           "The list could not be delivered. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (!omp_success (entity))
    set_http_status_from_entity (entity, response_data);

  ret = setting_get_value (connection,
                           "0872a6ed-4f85-48c5-ac3f-a5ef5e006745",
                           &fname_format,
                           response_data);
  if (ret)
    {
      g_free (content);
      free_entity (entity);
      switch (ret)
        {
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a setting. "
                                "The setting could not be delivered. "
                                "Diagnostics: Failure to send command to manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a setting. "
                                "The setting could not be delivered. "
                                "Diagnostics: Failure to receive response from manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a setting. "
                                "The setting could not be delivered. "
                                "Diagnostics: Internal error.",
                                "/omp?cmd=get_tasks", response_data);
        }
    }

  if (fname_format == NULL)
    {
      g_warning ("%s : File name format setting not found.", __FUNCTION__);
      fname_format = "%T-%D";
    }

  if (strcmp (type, "info") == 0)
    type_many = g_strdup (type);
  else
    type_many = g_strdup_printf ("%ss", type);

  file_name = format_file_name (fname_format, credentials, type_many, "list",
                                NULL);
  if (file_name == NULL)
    file_name = g_strdup_printf ("%s-%s", type_many, "list");

  g_free (type_many);

  *content_type = GSAD_CONTENT_TYPE_APP_XML;
  *content_disposition = g_strdup_printf ("attachment; filename=\"%s.xml\"",
                                          file_name);
  *content_length = strlen (content);
  free_entity (entity);
  g_free (file_name);
  return content;
}

/**
 * @brief Delete a resource, get all resources, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  type           Type of resource.
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  ultimate       0 move to trash, 1 remove entirely.
 * @param[in]  get            Next page get command.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_resource (openvas_connection_t *connection, const char *type,
                 credentials_t * credentials, params_t *params, int ultimate,
                 const char *get, cmd_response_data_t* response_data)
{
  gchar *html, *response, *id_name, *resource_id, *extra_attribs;
  const char *no_redirect, *next_id;
  entity_t entity;
  gchar *cap_type, *default_next, *prev_action;

  no_redirect = params_value (params, "no_redirect");
  id_name = g_strdup_printf ("%s_id", type);
  if (params_value (params, id_name))
    resource_id = g_strdup (params_value (params, id_name));
  else
    {
      g_free (id_name);
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while deleting a resource. "
                           "The resource was not deleted. "
                           "Diagnostics: Required parameter resource_id was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* This is a hack for assets, because asset_id is the param name used for
   * both the asset being deleted and the asset on the next page. */
  next_id = params_value (params, "next_id");
  if (next_id)
    {
      param_t *param;
      param = params_get (params, id_name);
      g_free (param->value);
      param->value = g_strdup (next_id);
      param->value_size = strlen (param->value);
    }

  g_free (id_name);

  /* Extra attributes */
  extra_attribs = NULL;

  /* Inheritor of user's resource */
  if (strcmp (type, "user") == 0)
    {
      const char* inheritor_id;
      inheritor_id = params_value (params, "inheritor_id");
      if (inheritor_id)
        extra_attribs = g_strdup_printf ("inheritor_id=\"%s\"", inheritor_id);
    }

  /* Delete the resource and get all resources. */

  if (openvas_connection_sendf (connection,
                                "<delete_%s %s_id=\"%s\" ultimate=\"%i\"%s%s/>",
                                type,
                                type,
                                resource_id,
                                !!ultimate,
                                extra_attribs ? " " : "",
                                extra_attribs ? extra_attribs : "")
      == -1)
    {
      g_free (resource_id);
      g_free (extra_attribs);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while deleting a resource. "
                           "The resource is not deleted. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  g_free (resource_id);
  g_free (extra_attribs);

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, &response))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while deleting a resource. "
                           "It is unclear whether the resource has been deleted or not. "
                           "Diagnostics: Failure to read response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (!omp_success (entity))
    set_http_status_from_entity (entity, response_data);

  cap_type = capitalize (type);
  default_next = g_strdup_printf ("get_%ss", type);
  prev_action = g_strdup_printf ("Delete %s", cap_type);

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, default_next,
                               NULL, default_next,
                               prev_action, response_data);

  g_free (response);
  free_entity (entity);
  g_free (cap_type);
  g_free (default_next);
  g_free (prev_action);

  return html;
}

/**
 * @brief Perform action on resource, get next page, XSL transform result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  type           Type of resource.
 * @param[in]  action         Action to perform.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
resource_action (openvas_connection_t *connection, credentials_t *credentials,
                 params_t *params, const char *type, const char *action,
                 cmd_response_data_t* response_data)
{
  gchar *html, *response, *param_name;
  const char *no_redirect, *resource_id;
  gchar *cap_action, *cap_type, *get_cmd, *prev_action;

  int ret;
  entity_t entity;

  assert (type);

  param_name = g_strdup_printf ("%s_id", type);
  no_redirect = params_value (params, "no_redirect");
  resource_id = params_value (params, param_name);

  if (resource_id == NULL)
    {
      gchar *message;
      message = g_strdup_printf
                 ("An internal error occurred while performing an action. "
                  "The resource remains the same. "
                  "Diagnostics: Required parameter %s was NULL.",
                  param_name);
      g_free (param_name);
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      html = gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           message,
                           "/omp?cmd=get_tasks", response_data);
      g_free (message);
      return html;
    }
  g_free (param_name);

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials, &response, &entity, response_data,
              "<%s_%s %s_id=\"%s\"/>",
              action,
              type,
              type,
              resource_id);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while performing an action. "
                             "The resource remains the same. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while performing an action. "
                             "It is unclear whether the resource has been affected. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while performing an action. "
                             "It is unclear whether the resource has been affected. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  if (!omp_success (entity))
    set_http_status_from_entity (entity, response_data);

  cap_action = capitalize (action);
  cap_type = capitalize (type);
  get_cmd = g_strdup_printf ("get_%ss", type);
  prev_action = g_strdup_printf ("%s %s", cap_action, cap_type);
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, get_cmd,
                               NULL, get_cmd,
                               prev_action, response_data);

  g_free (response);
  free_entity (entity);
  g_free (cap_action);
  g_free (cap_type);
  g_free (get_cmd);
  g_free (prev_action);

  return html;
}


/* Page handlers. */

/**
 * @todo Consider doing the input sanatizing in the page handlers.
 *
 * Currently the input sanatizing is done in serve_post, exec_omp_post and
 * exec_omp_get in gsad.c.  This means that the information about what
 * input is suitable for a page is separate from the page handler.
 *
 * Doing the input sanatizing in the page handler will probably also help
 * in responding with more detailed messages when an input error occurs.
 */

/**
 * @todo Take care of XML in input.
 *
 * Anything that is printed into the XML directly (usually via
 * g_string_append_printf below) must use something like
 * g_markup_printf_escaped or g_markup_escape_text to ensure that any
 * XML special sequences in the string are escaped.
 */

/**
 * @todo Unify the style of page handlers.
 *
 * There are variations in the style of the page handlers that run
 * multiple OMP commands.
 *
 * Some, like delete_credential_omp, simply run the OMP commands inside
 * one OMP COMMANDS and leave it to the XSL to figure out the context.
 *
 * Others, like create_target_omp, run each command separately and wrap the
 * responses in a unique page tag which gives the XSL the context.
 *
 * One handler, delete_target_omp, runs all the commands in a single COMMANDS
 * and also wraps the response in a unique page tag to convey the context to
 * the XSL.  This is probably the way to go.
 */

/**
 * @brief Get setting, returning HTML message on error.
 *
 * @param[in]  credentials  Credentials of user issuing the action.
 * @param[in]  connection   Connection
 * @param[in]  setting_id  UUID of the setting to get.
 * @param[out] value       Value of the setting.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return NULL on success, else error message page HTML.
 */
static char *
setting_get_value_error (credentials_t *credentials,
                         openvas_connection_t *connection,
                         const gchar *setting_id,
                         gchar **value,
                         cmd_response_data_t* response_data)
{
  switch (setting_get_value (connection, setting_id, value, response_data))
    {
      case 0:
        return NULL;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting a setting. "
                            "The setting could not be delivered. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting a setting. "
                            "The setting could not be delivered. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting a setting. "
                            "The setting could not be delivered. "
                            "Diagnostics: Internal error.",
                            "/omp?cmd=get_tasks", response_data);
    }
}

/**
 * @brief Get a value from a param or fall back to a setting
 *
 * @param[out]  value       Variable to assign the value to.
 * @param[in]   param       The param to try get the value from first.
 * @param[in]   setting_id  The UUID of the setting to try next.
 * @param[in]   cleanup     Code to run on failure.
 */
#define PARAM_OR_SETTING(value, param, setting_id, cleanup)                   \
  if (params_valid (params, param))                                           \
    value = g_strdup (params_value (params, param));                          \
  else                                                                        \
    {                                                                         \
      char *message;                                                          \
      message = setting_get_value_error (credentials, connection, setting_id, \
                                         &value, response_data);              \
      if (message)                                                            \
        {                                                                     \
          cleanup;                                                            \
          return message;                                                     \
        }                                                                     \
    }

/**
 * @brief Returns page to create a new task.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  message        If not NULL, display message.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_task (openvas_connection_t *connection, credentials_t * credentials,
          const char *message, params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  GString *xml;
  int apply_overrides;
  const char *alerts, *overrides;
  int ret;
  gchar *alert, *schedule, *target;
  gchar *openvas_config, *osp_config, *openvas_scanner, *osp_scanner;

  alerts = params_value (params, "alerts");
  overrides = params_value (params, "overrides");

  apply_overrides = overrides ? strcmp (overrides, "0") : 0;

  ret = setting_get_value (connection,
                           "f9f5a546-8018-48d0-bef5-5ad4926ea899",
                           &alert,
                           response_data);
  if (ret)
    {
      switch (ret)
        {
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a setting. "
                                "The setting could not be delivered. "
                                "Diagnostics: Failure to send command to manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a setting. "
                                "The setting could not be delivered. "
                                "Diagnostics: Failure to receive response from manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a setting. "
                                "The setting could not be delivered. "
                                "Diagnostics: Internal error.",
                                "/omp?cmd=get_tasks", response_data);
        }
    }

  PARAM_OR_SETTING (schedule, "schedule_id",
                    "778eedad-5550-4de0-abb6-1320d13b5e18",
                    g_free (alert));

  PARAM_OR_SETTING (target, "target_id",
                    "23409203-940a-4b4a-b70c-447475f18323",
                    g_free (alert);
                    g_free (schedule));

  PARAM_OR_SETTING (openvas_config, "config_id",
                    "fe7ea321-e3e3-4cc6-9952-da836aae83ce",
                    g_free (alert);
                    g_free (schedule);
                    g_free (target));

  PARAM_OR_SETTING (osp_config, "osp_config_id",
                    "fb19ac4b-614c-424c-b046-0bc32bf1be73",
                    g_free (alert);
                    g_free (schedule);
                    g_free (target);
                    g_free (openvas_config));

  PARAM_OR_SETTING (openvas_scanner, "scanner_id",
                    "f7d0f6ed-6f9e-45dc-8bd9-05cced84e80d",
                    g_free (alert);
                    g_free (schedule);
                    g_free (target);
                    g_free (openvas_config);
                    g_free (osp_config));

  PARAM_OR_SETTING (osp_scanner, "osp_scanner_id",
                    "b20697c9-be0a-4cd4-8b4d-5fe7841ebb03",
                    g_free (alert);
                    g_free (schedule);
                    g_free (target);
                    g_free (openvas_config);
                    g_free (osp_config);
                    g_free (openvas_scanner));

  xml = g_string_new ("<new_task>");

  g_string_append_printf (xml,
                          "<alert_id>%s</alert_id>"
                          "<config_id>%s</config_id>"
                          "<osp_config_id>%s</osp_config_id>"
                          "<scanner_id>%s</scanner_id>"
                          "<osp_scanner_id>%s</osp_scanner_id>"
                          "<schedule_id>%s</schedule_id>"
                          "<target_id>%s</target_id>",
                          alert ? alert : "",
                          (openvas_config && strlen (openvas_config))
                           ? openvas_config
                           : "daba56c8-73ec-11df-a475-002264764cea",
                          osp_config ? osp_config : "",
                          openvas_scanner ? openvas_scanner : "",
                          osp_scanner ? osp_scanner : "",
                          schedule ? schedule : "",
                          (target && strlen (target))
                           ? target
                           : "b493b7a8-7489-11df-a3ec-002264764cea");

  g_free (schedule);
  g_free (target);
  g_free (openvas_config);
  g_free (osp_config);
  g_free (openvas_scanner);
  g_free (osp_scanner);

  /* Get list of targets. */
  if (openvas_connection_sendf (connection,
                                "<get_targets"
                                " filter=\"rows=-1 sort=name\"/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting targets list. "
                           "The current list of targets is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting targets list. "
                           "The current list of targets is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Get configs to select in new task UI. */
  if (openvas_connection_sendf (connection,
                                "<get_configs"
                                " filter=\"rows=-1 sort=name\"/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting config list. "
                           "The current list of configs is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting config list. "
                           "The current list of configs is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (command_enabled (credentials, "GET_ALERTS"))
    {
      /* Get alerts to select in new task UI. */
      if (openvas_connection_sendf (connection,
                                    "<get_alerts"
                                    " filter=\"rows=-1 sort=name\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting alert list. "
                               "The current list of alerts is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting alert list. "
                               "The current list of alerts is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  if (command_enabled (credentials, "GET_SCHEDULES"))
    {
      /* Get schedules to select in new task UI. */
      if (openvas_connection_sendf
           (connection,
            "<get_schedules"
            " filter=\"rows=-1 sort=name\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the schedule list. "
                               "The current list of schedules is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the schedule list. "
                               "The current list of schedules is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  if (command_enabled (credentials, "GET_SCANNERS"))
    {
      /* Get scanners to select in new task UI. */
      if (openvas_connection_sendf (connection,
                                    "<get_scanners"
                                    " filter=\"rows=-1\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the"
                               " scanner list. "
                               "The current list of scanners is not available. "
                               "Diagnostics: Failure to send command to manager"
                               " daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting"
                               " the scanner list."
                               "The current list of scanners is not available. "
                               "Diagnostics: Failure to receive response from"
                               " manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  if (command_enabled (credentials, "GET_GROUPS"))
    {
      /* Get groups for Observer Groups. */

      if (openvas_connection_sendf (connection,
                                    "<get_groups/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting group list. "
                               "The current list of groups is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting group list. "
                               "The current list of groups is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  if (command_enabled (credentials, "GET_TAGS"))
    {
      /* Get tag names. */

      if (openvas_connection_sendf (connection,
                                    "<get_tags names_only=\"1\""
                                    " filter=\"resource_type=task rows=-1\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting tag list. "
                               "The current list of tags is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting tag list. "
                               "The current list of tags is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  if (extra_xml)
    g_string_append (xml, extra_xml);
  if (message)
    g_string_append_printf (xml, GSAD_MESSAGE_INVALID, message, "Create Task");
  g_string_append_printf (xml,
                          "<user>%s</user>"
                          "<apply_overrides>%i</apply_overrides>"
                          "<alerts>%s</alerts>"
                          "</new_task>",
                          credentials->username,
                          apply_overrides,
                          alerts ? alerts : "1");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to create a new task.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_task_omp (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return new_task (connection, credentials, NULL, params, NULL, response_data);
}

/**
 * @brief Returns page to create a new container task.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  message        If not NULL, display message.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_container_task (openvas_connection_t *connection,
                    credentials_t * credentials, const char *message,
                    params_t *params, const char *extra_xml,
                    cmd_response_data_t* response_data)
{
  GString *xml;

  xml = g_string_new ("<new_container_task>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (message)
    g_string_append_printf (xml, GSAD_MESSAGE_INVALID, message, "Create Task");

  g_string_append_printf (xml, "</new_container_task>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to create a new task.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_container_task_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  return new_container_task (connection, credentials, NULL, params, NULL,
                             response_data);
}

/**
 * @brief Returns page to upload a new report.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
upload_report (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, const char *extra_xml,
               cmd_response_data_t* response_data)
{
  GString *xml;

  xml = g_string_new ("<upload_report>");
  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (command_enabled (credentials, "GET_TASKS"))
    {
      gchar *response;

      if (simple_ompf (connection, "getting Tasks", credentials, &response,
                       response_data,
                       "<get_tasks"
                       /* All container tasks. */
                       " filter=\"target= rows=-1 owner=any permission=any\"/>"))
        {
          g_string_free (xml, TRUE);
          return response;
        }

      g_string_append (xml, response);
    }

  g_string_append (xml, "</upload_report>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the upload report page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
upload_report_omp (openvas_connection_t *connection, credentials_t *credentials,
                   params_t *params, cmd_response_data_t* response_data)
{
  return upload_report (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create a report, get all tasks, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_report_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  entity_t entity;
  int ret;
  gchar *command, *html, *response;
  const char *no_redirect, *cmd, *task_id, *name, *comment, *xml_file;
  const char *in_assets;

  no_redirect = params_value (params, "no_redirect");
  task_id = params_value (params, "task_id");
  xml_file = params_value (params, "xml_file");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  in_assets = params_value (params, "in_assets");

  if (task_id == NULL)
    {
      CHECK_PARAM_INVALID (name, "Create Report", "new_container_task");
      CHECK_PARAM_INVALID (comment, "Create Report", "new_container_task");
    }
  CHECK_PARAM_INVALID (xml_file, "Create Report", "new_container_task");

  if (params_given (params, "in_assets"))
    CHECK_PARAM_INVALID (xml_file, "Create Report", "new_container_task");

  if (strlen (xml_file) == 0)
    {
      if (task_id)
        return message_invalid (connection, credentials, params, response_data,
                                "Report required",
                                G_STRINGIFY (MHD_HTTP_BAD_REQUEST),
                                "Create Report", "new_container_task");

      /* Create only the container task. */

      command = g_markup_printf_escaped ("<create_task>"
                                         "<target id=\"0\"/>"
                                         "<name>%s</name>"
                                         "<comment>%s</comment>"
                                         "</create_task>",
                                         name,
                                         comment);
    }
  else
    {
      gchar **xml_file_array, *xml_file_escaped;

      xml_file_array = g_strsplit (xml_file, "%", -1);
      if (xml_file_array != NULL && xml_file_array[0] != NULL)
        xml_file_escaped = g_strjoinv ("%%", xml_file_array);
      else
        xml_file_escaped = g_strdup (xml_file);
      g_strfreev (xml_file_array);

      if (task_id)
        command = g_strdup_printf ("<create_report>"
                                   "<in_assets>%s</in_assets>"
                                   "<task id=\"%s\"/>"
                                   "%s"
                                   "</create_report>",
                                   in_assets ? in_assets : "0",
                                   task_id ? task_id : "0",
                                   xml_file_escaped ? xml_file_escaped : "");
      else
        {
          gchar *name_escaped, *comment_escaped;
          name_escaped = name ? g_markup_escape_text (name, -1)
                              : NULL;
          comment_escaped = comment ? g_markup_escape_text (comment, -1)
                                    : NULL;
          command = g_strdup_printf ("<create_report>"
                                     "<in_assets>%s</in_assets>"
                                     "<task>"
                                     "<name>%s</name>"
                                     "<comment>%s</comment>"
                                     "</task>"
                                     "%s"
                                     "</create_report>",
                                     in_assets ? in_assets : "",
                                     name_escaped,
                                     comment_escaped,
                                     xml_file_escaped);
          g_free (name_escaped);
          g_free (comment_escaped);
        }
      g_free (xml_file_escaped);
    }

  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             command);
  g_free (command);

  switch (ret)
    {
      case 0:
        break;
      case -1:
        /* 'omp' set response. */
        return response;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new report. "
                             "No new report was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new report. "
                             "It is unclear whether the report has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new report. "
                             "It is unclear whether the report has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  cmd = params_value (params, "cmd");
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_tasks",
                               NULL,
                               (cmd && strcmp (cmd, "import_report"))
                                  ? "new_container_task" : "upload_report",
                               "Import Report", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Import report, get all reports, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
import_report_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  return create_report_omp (connection, credentials, params, response_data);
}

#define CHECK(name)                                                        \
CHECK_PARAM_INVALID (name, "Create Task", "new_task")

/**
 * @brief Create a container task, serve next page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_container_task_omp (openvas_connection_t *connection,
                           credentials_t * credentials, params_t *params,
                           cmd_response_data_t* response_data)
{
  entity_t entity;
  int ret;
  gchar *command, *html, *response;
  const char *no_redirect, *name, *comment;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  CHECK_PARAM_INVALID (name, "Create Container Task", "new_container_task");
  CHECK_PARAM_INVALID (comment, "Create Container Task", "new_container_task");

  command = g_markup_printf_escaped ("<create_task>"
                                     "<target id=\"0\"/>"
                                     "<name>%s</name>"
                                     "<comment>%s</comment>"
                                     "</create_task>",
                                     name,
                                     comment);
  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             command);
  g_free (command);

  switch (ret)
    {
      case 0:
        break;
      case -1:
        /* 'omp' set response. */
        return response;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a container task. "
                             "No task was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a container task. "
                             "It is unclear whether the task has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a container task. "
                             "It is unclear whether the task has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "task_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_tasks",
                               NULL, "new_container_task",
                               "Create Container Task", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Create a task, get all tasks, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_task_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  entity_t entity;
  int ret;
  gchar *schedule_element, *command;
  gchar *response, *html;
  const char *no_redirect;
  const char *name, *comment, *config_id, *target_id, *scanner_type;
  const char *scanner_id, *schedule_id, *schedule_periods;
  const char *max_checks, *max_hosts;
  const char *in_assets, *hosts_ordering, *alterable, *source_iface;
  const char *add_tag, *tag_name, *tag_value, *auto_delete, *auto_delete_data;
  const char *apply_overrides, *min_qod;
  gchar *name_escaped, *comment_escaped;
  params_t *alerts;
  GString *alert_element;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  target_id = params_value (params, "target_id");
  scanner_type = params_value (params, "scanner_type");
  hosts_ordering = params_value (params, "hosts_ordering");
  schedule_id = params_value (params, "schedule_id");
  schedule_periods = params_value (params, "schedule_periods");
  scanner_id = params_value (params, "scanner_id");
  config_id = params_value (params, "config_id");
  in_assets = params_value (params, "in_assets");
  apply_overrides = params_value (params, "apply_overrides");
  min_qod = params_value (params, "min_qod");
  max_checks = params_value (params, "max_checks");
  source_iface = params_value (params, "source_iface");
  auto_delete = params_value (params, "auto_delete");
  auto_delete_data = params_value (params, "auto_delete_data");
  max_hosts = params_value (params, "max_hosts");
  alterable = params_value (params, "alterable");
  add_tag = params_value (params, "add_tag");
  tag_name = params_value (params, "tag_name");
  tag_value = params_value (params, "tag_value");
  CHECK (scanner_type);
  if (!strcmp (scanner_type, "1"))
    {
      hosts_ordering = "";
      max_checks = "";
      source_iface = "";
      max_hosts = "";
    }
  else if (!strcmp (scanner_type, "3"))
    {
      config_id = "";
      hosts_ordering = "";
      max_checks = "";
      source_iface = "";
      max_hosts = "";
    }

  CHECK (name);
  CHECK (comment);
  CHECK (config_id);
  CHECK (target_id);
  CHECK (hosts_ordering);
  CHECK (scanner_id);
  CHECK (schedule_id);
  if (params_given (params, "schedule_periods"))
    {
      CHECK (schedule_periods);
    }
  else
    schedule_periods = "0";
  CHECK (in_assets);
  if (!strcmp (in_assets, "1"))
    {
      CHECK (apply_overrides);
      CHECK (min_qod);
    }
  else
    {
      if (!params_given (params, "apply_overrides")
          || !params_valid (params, "apply_overrides"))
        apply_overrides = "";

      if (!params_given (params, "min_qod")
          || !params_valid (params, "min_qod"))
        min_qod = "";
    }
  CHECK (max_checks);
  CHECK (source_iface);
  CHECK (auto_delete);
  CHECK (auto_delete_data);
  CHECK (max_hosts);
  CHECK (alterable);
  if (add_tag)
    {
      CHECK (add_tag);
      CHECK (tag_name);
      CHECK (tag_value);
    }

  if (schedule_id == NULL || strcmp (schedule_id, "0") == 0)
    schedule_element = g_strdup ("");
  else
    schedule_element = g_strdup_printf ("<schedule id=\"%s\"/>", schedule_id);

  alert_element = g_string_new ("");
  if (params_given (params, "alert_id_optional:"))
    alerts = params_values (params, "alert_id_optional:");
  else
    alerts = params_values (params, "alert_ids:");

  if (alerts)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, alerts);
      while (params_iterator_next (&iter, &name, &param))
        if (param->value && strcmp (param->value, "0"))
          g_string_append_printf (alert_element,
                                  "<alert id=\"%s\"/>",
                                  param->value ? param->value : "");
    }

  name_escaped = name ? g_markup_escape_text (name, -1) : NULL;
  comment_escaped = comment ? g_markup_escape_text (comment, -1) : NULL;

  command = g_strdup_printf ("<create_task>"
                             "<config id=\"%s\"/>"
                             "<schedule_periods>%s</schedule_periods>"
                             "%s%s"
                             "<target id=\"%s\"/>"
                             "<scanner id=\"%s\"/>"
                             "<hosts_ordering>%s</hosts_ordering>"
                             "<name>%s</name>"
                             "<comment>%s</comment>"
                             "<preferences>"
                             "<preference>"
                             "<scanner_name>max_checks</scanner_name>"
                             "<value>%s</value>"
                             "</preference>"
                             "<preference>"
                             "<scanner_name>max_hosts</scanner_name>"
                             "<value>%s</value>"
                             "</preference>"
                             "<preference>"
                             "<scanner_name>in_assets</scanner_name>"
                             "<value>%s</value>"
                             "</preference>"
                             "<preference>"
                             "<scanner_name>"
                             "assets_apply_overrides"
                             "</scanner_name>"
                             "<value>%s</value>"
                             "</preference>"
                             "<preference>"
                             "<scanner_name>assets_min_qod</scanner_name>"
                             "<value>%s</value>"
                             "</preference>"
                             "<preference>"
                             "<scanner_name>source_iface</scanner_name>"
                             "<value>%s</value>"
                             "</preference>"
                             "<preference>"
                             "<scanner_name>auto_delete</scanner_name>"
                             "<value>%s</value>"
                             "</preference>"
                             "<preference>"
                             "<scanner_name>auto_delete_data</scanner_name>"
                             "<value>%s</value>"
                             "</preference>"
                             "</preferences>"
                             "<alterable>%i</alterable>"
                             "</create_task>",
                             config_id,
                             schedule_periods,
                             schedule_element,
                             alert_element->str,
                             target_id,
                             scanner_id,
                             hosts_ordering,
                             name_escaped,
                             comment_escaped,
                             max_checks,
                             max_hosts,
                             strcmp (in_assets, "0") ? "yes" : "no",
                             strcmp (apply_overrides, "0") ? "yes" : "no",
                             min_qod,
                             source_iface,
                             auto_delete,
                             auto_delete_data,
                             alterable ? strcmp (alterable, "0") : 0);

  g_free (name_escaped);
  g_free (comment_escaped);

  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             command);
  g_free (command);

  g_free (schedule_element);
  g_string_free (alert_element, TRUE);

  switch (ret)
    {
      case 0:
        break;
      case -1:
        /* 'omp' set response. */
        return response;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new task. "
                             "No new task was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new task. "
                             "It is unclear whether the task has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new task. "
                             "It is unclear whether the task has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  if (omp_success (entity))
    {
      if (add_tag && strcmp (add_tag, "0"))
        {
          const char *new_task_id = entity_attribute (entity, "id");
          gchar *tag_command, *tag_response;
          entity_t tag_entity;

          if (tag_value && strcmp (tag_value, ""))
            tag_command
              = g_markup_printf_escaped ("<create_tag>"
                                         "<name>%s</name>"
                                         "<resource id=\"%s\">"
                                         "<type>task</type>"
                                         "</resource>"
                                         "<value>%s</value>"
                                         "</create_tag>",
                                         tag_name,
                                         new_task_id,
                                         tag_value);
          else
            tag_command
              = g_markup_printf_escaped ("<create_tag>"
                                         "<name>%s</name>"
                                         "<resource id=\"%s\">"
                                         "<type>task</type>"
                                         "</resource>"
                                         "</create_tag>",
                                         tag_name,
                                         new_task_id);

          ret = omp (connection, credentials,
                     &tag_response,
                     &tag_entity,
                     response_data,
                     tag_command);

          switch (ret)
            {
              case 0:
              case -1:
                break;
              case 1:
                free_entity (entity);
                g_free (response);
                response_data->http_status_code
                  = MHD_HTTP_INTERNAL_SERVER_ERROR;
                return gsad_message (credentials,
                                    "Internal error", __FUNCTION__, __LINE__,
                                    "An internal error occurred while creating a new tag. "
                                    "No new tag was created. "
                                    "Diagnostics: Failure to send command to manager daemon.",
                                    "/omp?cmd=get_tasks", response_data);
              case 2:
                free_entity (entity);
                g_free (response);
                response_data->http_status_code
                  = MHD_HTTP_INTERNAL_SERVER_ERROR;
                return gsad_message (credentials,
                                    "Internal error", __FUNCTION__, __LINE__,
                                    "An internal error occurred while creating a new tag. "
                                    "It is unclear whether the tag has been created or not. "
                                    "Diagnostics: Failure to receive response from manager daemon.",
                                    "/omp?cmd=get_tasks", response_data);
              default:
                free_entity (entity);
                g_free (response);
                response_data->http_status_code
                  = MHD_HTTP_INTERNAL_SERVER_ERROR;
                return gsad_message (credentials,
                                    "Internal error", __FUNCTION__, __LINE__,
                                    "An internal error occurred while creating a new task. "
                                    "It is unclear whether the tag has been created or not. "
                                    "Diagnostics: Internal Error.",
                                    "/omp?cmd=get_tasks", response_data);
            }

          if (entity_attribute (entity, "id"))
            params_add (params, "task_id", entity_attribute (entity, "id"));
          html
            = response_from_entity (connection, credentials, params, tag_entity,
                                    (no_redirect && strcmp (no_redirect, "0")),
                                    NULL, "get_tasks",
                                    NULL, "new_tasks",
                                    "Create Task and Tag", response_data);
          free_entity (tag_entity);
          g_free (tag_response);
        }
      else
        {
          if (entity_attribute (entity, "id"))
            params_add (params, "task_id", entity_attribute (entity, "id"));
          html
            = response_from_entity (connection, credentials, params, entity,
                                    (no_redirect && strcmp (no_redirect, "0")),
                                    NULL, "get_tasks",
                                    NULL, "new_task",
                                    "Create Task", response_data);
        }
    }
  else
    {
      html = response_from_entity (connection, credentials, params, entity,
                                   (no_redirect && strcmp (no_redirect, "0")),
                                   NULL, "get_tasks",
                                   NULL, "new_task",
                                   "Create Task", response_data);
    }
  free_entity (entity);
  g_free (response);
  return html;
}


/**
 * @brief Delete a task, get all tasks, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_task_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return delete_resource (connection, "task", credentials, params, 0, NULL, response_data);
}

/**
 * @brief Setup edit_task XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_task (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  GString *xml;
  const char *task_id, *next, *refresh_interval, *sort_field, *sort_order;
  const char *overrides, *alerts;
  int apply_overrides;

  task_id = params_value (params, "task_id");
  next = params_value (params, "next");
  refresh_interval = params_value (params, "refresh_interval");
  sort_field = params_value (params, "sort_field");
  sort_order = params_value (params, "sort_order");
  overrides = params_value (params, "overrides");
  alerts = params_value (params, "alerts");

  apply_overrides = overrides ? strcmp (overrides, "0") : 1;

  if (task_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing a task. "
                           "The task remains as it was. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (next == NULL)
    next = "get_task";

  if (openvas_connection_sendf (connection,
                                "<commands>"
                                "<get_tasks task_id=\"%s\" details=\"1\" />"
                                "<get_targets"
                                " filter=\"rows=-1 sort=name\"/>"
                                "<get_configs"
                                " filter=\"rows=-1 sort=name\"/>"
                                "%s"
                                "%s"
                                "%s"
                                "%s"
                                "</commands>",
                                task_id,
                                command_enabled (credentials, "GET_ALERTS")
                                 ? "<get_alerts"
                                   " filter=\"rows=-1 sort=name\"/>"
                                 : "",
                                command_enabled (credentials, "GET_SCHEDULES")
                                 ? "<get_schedules"
                                   " filter=\"rows=-1 sort=name\"/>"
                                 : "",
                                command_enabled (credentials, "GET_SCANNERS")
                                 ? "<get_scanners"
                                   " filter=\"rows=-1\"/>"
                                 : "",
                                command_enabled (credentials, "GET_GROUPS")
                                 ? "<get_groups/>"
                                 : "")
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting task info. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  xml = g_string_new ("");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  g_string_append_printf (xml,
                          "<edit_task>"
                          "<task id=\"%s\"/>"
                          "<user>%s</user>"
                          "<alerts>%s</alerts>"
                          /* Page that follows. */
                          "<next>%s</next>"
                          /* Passthroughs. */
                          "<refresh_interval>%s</refresh_interval>"
                          "<sort_field>%s</sort_field>"
                          "<sort_order>%s</sort_order>"
                          "<apply_overrides>%i</apply_overrides>",
                          task_id,
                          credentials->username,
                          alerts ? alerts : "1",
                          next,
                          refresh_interval ? refresh_interval : "",
                          sort_field,
                          sort_order,
                          apply_overrides);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting task info. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</edit_task>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup edit_task XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_task_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return edit_task (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Save task, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_task_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  gchar *html, *response, *format;
  const char *no_redirect;
  const char *comment, *name, *schedule_id, *in_assets;
  const char *scanner_id, *task_id, *max_checks, *max_hosts;
  const char *config_id, *target_id, *hosts_ordering, *alterable, *source_iface;
  const char *scanner_type, *schedule_periods, *auto_delete, *auto_delete_data;
  const char *apply_overrides, *min_qod;
  int ret;
  params_t *alerts;
  GString *alert_element;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  comment = params_value (params, "comment");
  name = params_value (params, "name");
  task_id = params_value (params, "task_id");
  in_assets = params_value (params, "in_assets");
  apply_overrides = params_value (params, "apply_overrides");
  min_qod = params_value (params, "min_qod");
  target_id = params_value (params, "target_id");
  scanner_type = params_value (params, "scanner_type");
  hosts_ordering = params_value (params, "hosts_ordering");
  config_id = params_value (params, "config_id");
  schedule_id = params_value (params, "schedule_id");
  schedule_periods = params_value (params, "schedule_periods");
  scanner_id = params_value (params, "scanner_id");
  max_checks = params_value (params, "max_checks");
  source_iface = params_value (params, "source_iface");
  auto_delete = params_value (params, "auto_delete");
  auto_delete_data = params_value (params, "auto_delete_data");
  max_hosts = params_value (params, "max_hosts");
  alterable = params_value (params, "alterable");
  CHECK_PARAM_INVALID (scanner_type, "Save Task", "edit_task");
  if (!strcmp (scanner_type, "1"))
    {
      hosts_ordering = "";
      max_checks = "";
      source_iface = "";
      max_hosts = "";
    }
  else if (!strcmp (scanner_type, "3"))
    {
      config_id = "0";
      hosts_ordering = "";
      max_checks = "";
      source_iface = "";
      max_hosts = "";
    }

  CHECK_PARAM_INVALID (name, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (comment, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (target_id, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (hosts_ordering, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (config_id, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (schedule_id, "Save Task", "edit_task");
  if (params_given (params, "schedule_periods"))
    {
      CHECK (schedule_periods);
    }
  else
    schedule_periods = "0";
  CHECK_PARAM_INVALID (scanner_id, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (task_id, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (max_checks, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (source_iface, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (auto_delete, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (auto_delete_data, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (max_hosts, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (in_assets, "Save Task", "edit_task");

  if (!strcmp (in_assets, "1"))
    {
      CHECK_PARAM_INVALID (apply_overrides, "Save Task", "edit_task");
      CHECK_PARAM_INVALID (min_qod, "Save Task", "edit_task");
    }
  else
    {
      if (!params_given (params, "apply_overrides")
          || !params_valid (params, "apply_overrides"))
        apply_overrides = "";

      if (!params_given (params, "min_qod")
          || !params_valid (params, "min_qod"))
        min_qod = "";
    }

  alert_element = g_string_new ("");
  if (params_given (params, "alert_id_optional:"))
    alerts = params_values (params, "alert_id_optional:");
  else
    alerts = params_values (params, "alert_ids:");

  if (alerts)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, alerts);
      while (params_iterator_next (&iter, &name, &param))
      {
        if (param->value && strcmp (param->value, "0"))
          g_string_append_printf (alert_element,
                                  "<alert id=\"%s\"/>",
                                  param->value ? param->value : "");
      }
    }

  // Remove Alerts from Task if none are given.
  if (strcmp (alert_element->str, "") == 0)
    g_string_append_printf (alert_element, "<alert id=\"0\"/>");

  format = g_strdup_printf ("<modify_task task_id=\"%%s\">"
                            "<name>%%s</name>"
                            "<comment>%%s</comment>"
                            "<hosts_ordering>%s</hosts_ordering>"
                            "%s"
                            "<target id=\"%%s\"/>"
                            "<config id=\"%%s\"/>"
                            "<schedule id=\"%%s\"/>"
                            "<schedule_periods>%%s</schedule_periods>"
                            "<scanner id=\"%%s\"/>"
                            "<preferences>"
                            "<preference>"
                            "<scanner_name>max_checks</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "<preference>"
                            "<scanner_name>max_hosts</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "<preference>"
                            "<scanner_name>in_assets</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "<preference>"
                            "<scanner_name>assets_apply_overrides</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "<preference>"
                            "<scanner_name>assets_min_qod</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "<preference>"
                            "<scanner_name>source_iface</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "<preference>"
                            "<scanner_name>auto_delete</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "<preference>"
                            "<scanner_name>auto_delete_data</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "</preferences>"
                            "%s%i%s"
                            "</modify_task>",
                            hosts_ordering,
                            alert_element->str,
                            alterable ? "<alterable>" : "",
                            alterable ? strcmp (alterable, "0") : 0,
                            alterable ? "</alterable>" : "");
  response = NULL;
  entity = NULL;
  ret = ompf (connection,
              credentials,
              &response,
              &entity,
              response_data,
              format,
              task_id,
              name,
              comment,
              target_id,
              config_id,
              schedule_id,
              schedule_periods,
              scanner_id,
              max_checks,
              max_hosts,
              strcmp (in_assets, "0") ? "yes" : "no",
              strcmp (apply_overrides, "0") ? "yes" : "no",
              min_qod,
              source_iface,
              auto_delete,
              auto_delete_data);
  g_free (format);

  g_string_free (alert_element, TRUE);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a task. "
                             "The task was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a task. "
                             "It is unclear whether the task has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a task. "
                             "It is unclear whether the task has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_tasks",
                               NULL, "edit_task",
                               "Save Task", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

#undef CHECK

/**
 * @brief Save container task, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_container_task_omp (openvas_connection_t *connection,
                         credentials_t * credentials, params_t *params,
                         cmd_response_data_t* response_data)
{
  gchar *format, *response, *html;
  const char *no_redirect, *comment, *name, *task_id;
  const char *in_assets, *auto_delete, *auto_delete_data;
  int ret;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  comment = params_value (params, "comment");
  in_assets = params_value (params, "in_assets");
  name = params_value (params, "name");
  task_id = params_value (params, "task_id");
  auto_delete = params_value (params, "auto_delete");
  auto_delete_data = params_value (params, "auto_delete_data");
  CHECK_PARAM_INVALID (name, "Save Task", "edit_task")
  CHECK_PARAM_INVALID (comment, "Save Task", "edit_task")
  CHECK_PARAM_INVALID (task_id, "Save Task", "edit_task")
  CHECK_PARAM_INVALID (in_assets, "Save Task", "edit_task")
  CHECK_PARAM_INVALID (auto_delete, "Save Task", "edit_task");
  CHECK_PARAM_INVALID (auto_delete_data, "Save Task", "edit_task");

  format = g_strdup_printf ("<modify_task task_id=\"%%s\">"
                            "<name>%%s</name>"
                            "<comment>%%s</comment>"
                            "<preferences>"
                            "<preference>"
                            "<scanner_name>in_assets</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "<preference>"
                            "<scanner_name>auto_delete</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "<preference>"
                            "<scanner_name>auto_delete_data</scanner_name>"
                            "<value>%%s</value>"
                            "</preference>"
                            "</preferences>"
                            "</modify_task>");

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials, &response, &entity, response_data,
              format, task_id, name, comment,
              strcmp (in_assets, "0") ? "yes" : "no",
              auto_delete,
              auto_delete_data);
  g_free (format);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a task. "
                             "No new task was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a task. "
                             "It is unclear whether the task has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a task. "
                             "It is unclear whether the task has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_tasks",
                               NULL, "edit_task",
                               "Save Container Task", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Export a task.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Note XML on success.  HTML result of XSL transformation on error.
 */
char *
export_task_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, enum content_type * content_type,
                 char **content_disposition, gsize *content_length,
                 cmd_response_data_t* response_data)
{
  return export_resource (connection, "task", credentials, params, content_type,
                          content_disposition, content_length, response_data);
}

/**
 * @brief Export a list of tasks.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Tasks XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_tasks_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, enum content_type * content_type,
                  char **content_disposition, gsize *content_length,
                  cmd_response_data_t* response_data)
{
  return export_many (connection, "task", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Stop a task, get all tasks, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
stop_task_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return resource_action (connection, credentials, params, "task", "stop",
                          response_data);
}

/**
 * @brief Resume a task, get all tasks, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
resume_task_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return resource_action (connection, credentials, params, "task", "resume",
                          response_data);
}

/**
 * @brief Start a task, get all tasks, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
start_task_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return resource_action (connection, credentials, params, "task", "start",
                          response_data);
}

/**
 * @brief Reassign a task to a new OMP slave.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
move_task_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  gchar *command, *response, *html;
  const char *no_redirect, *task_id, *slave_id;
  int ret;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  slave_id = params_value (params, "slave_id");
  task_id = params_value (params, "task_id");

  command = g_strdup_printf ("<move_task task_id=\"%s\" slave_id=\"%s\"/>",
                             task_id ? task_id : "",
                             slave_id ? slave_id : "");

  response = NULL;
  entity = NULL;
  ret = omp (connection, credentials, &response, &entity, response_data,
             command);
  g_free (command);
  switch (ret)
    {
      case 0:
        break;
      case -1:
        /* 'omp' set response. */
        return response;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while moving a task. "
                             "The task was not moved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while moving a task. "
                             "It is unclear whether the task has been moved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while moving a task. "
                             "It is unclear whether the task has been moved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_tasks",
                               NULL, "get_tasks",
                               "Move Task", response_data);

  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Requests NVT details, accepting extra commands.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials for the manager connection.
 * @param[in]  params         Request parameters.
 * @param[in]  commands       Extra commands to run before the others.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return XSL transformed NVT details response or error message.
 */
static char*
get_nvts (openvas_connection_t *connection, credentials_t *credentials,
          params_t *params, const char *commands, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  GString *xml = NULL;
  const char *oid;

  oid = params_value (params, "oid");
  if (oid == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting an NVT. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (openvas_connection_sendf (connection,
                                "<commands>"
                                "%s"
                                "<get_nvts"
                                " nvt_oid=\"%s\""
                                " details=\"1\""
                                " preferences=\"1\"/>"
                                "<get_notes"
                                " nvt_oid=\"%s\""
                                " sort_field=\"notes.text\"/>"
                                "<get_overrides"
                                " nvt_oid=\"%s\""
                                " sort_field=\"overrides.text\"/>"
                                "</commands>",
                                commands ? commands : "",
                                oid,
                                oid,
                                oid)
        == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting nvt details. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_tasks", response_data);
    }

  xml = g_string_new ("<get_nvts>");
  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting nvt details. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Append extra_xml */
  if (extra_xml)
    g_string_append (xml, extra_xml);

  /* Get tag names */

  if (openvas_connection_sendf (connection,
                                "<get_tags"
                                " filter=\"resource_type=nvt"
                                "          first=1"
                                "          rows=-1\""
                                " names_only=\"1\""
                                "/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting tag names list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting tag names list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  g_string_append (xml, "</get_nvts>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Requests SecInfo.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials for the manager connection.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return XSL transformed SecInfo response or error message.
 */
char *
get_info (openvas_connection_t *connection, credentials_t *credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  char *ret;
  GString *extra_attribs, *extra_response;
  const char *info_type;

  info_type = params_value (params, "info_type");
  if (info_type == NULL)
    {
      param_t *param;
      param = params_add (params, "info_type", "nvt");
      param->valid = 1;
      param->valid_utf8 = g_utf8_validate (param->value, -1, NULL);
      info_type = params_value (params, "info_type");
    }

  if (strcmp (info_type, "nvt")
      && strcmp (info_type, "cve")
      && strcmp (info_type, "cpe")
      && strcmp (info_type, "ovaldef")
      && strcmp (info_type, "cert_bund_adv")
      && strcmp (info_type, "dfn_cert_adv")
      && strcmp (info_type, "allinfo")
      && strcmp (info_type, "NVT")
      && strcmp (info_type, "CVE")
      && strcmp (info_type, "CPE")
      && strcmp (info_type, "OVALDEF")
      && strcmp (info_type, "CERT_BUND_ADV")
      && strcmp (info_type, "DFN_CERT_ADV")
      && strcmp (info_type, "ALLINFO"))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting SecInfo. "
                           "Diagnostics: Invalid info_type parameter value",
                           "/omp?cmd=get_info", response_data);
    }

  if (params_value (params, "info_name")
      && params_value (params, "info_id"))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting SecInfo. "
                           "Diagnostics: Both ID and Name set.",
                           "/omp?cmd=get_info", response_data);
    }
  extra_response = g_string_new (extra_xml ? extra_xml : "");

  if (command_enabled (credentials, "GET_NOTES")
      && (strcasecmp (info_type, "NVT") == 0)
      && params_value (params, "info_id"))
    {
      gchar *response;

      if (simple_ompf (connection, "getting SecInfo", credentials, &response,
                       response_data,
                       "<get_notes"
                       " nvt_oid=\"%s\""
                       " sort_field=\"notes.text\"/>",
                       params_value (params, "info_id")))
        {
          g_string_free (extra_response, TRUE);
          return response;
        }

      g_string_append (extra_response, response);
    }

  if (command_enabled (credentials, "GET_OVERRIDES")
      && (strcasecmp (info_type, "NVT") == 0)
      && params_value (params, "info_id"))
    {
      gchar *response;

      if (simple_ompf (connection, "getting SecInfo", credentials, &response,
                       response_data,
                       "<get_overrides"
                       " nvt_oid=\"%s\""
                       " sort_field=\"overrides.text\"/>",
                       params_value (params, "info_id")))
        {
          g_string_free (extra_response, TRUE);
          return response;
        }

      g_string_append (extra_response, response);
    }

  extra_attribs = g_string_new("");
  g_string_append_printf (extra_attribs, "type=\"%s\"",
                          params_value (params, "info_type"));
  if (params_value (params, "info_name"))
    g_string_append_printf (extra_attribs,
                            " name=\"%s\"",
                            params_value (params, "info_name"));
  else if (params_value (params, "info_id"))
    g_string_append_printf (extra_attribs,
                            " info_id=\"%s\"",
                            params_value (params, "info_id"));
  if (params_value (params, "details"))
    g_string_append_printf (extra_attribs,
                            " details=\"%s\"",
                            params_value (params, "details"));
  ret = get_many (connection, "info", credentials, params, extra_response->str,
                  extra_attribs->str, response_data);

  g_string_free (extra_response, TRUE);
  g_string_free (extra_attribs, TRUE);

  return ret;
}

/**
 * @brief Get info, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_info_omp (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params,
              cmd_response_data_t* response_data)
{
  return get_info (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Requests NVT details, accepting extra commands.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials for the manager connection.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return XSL transformed NVT details response or error message.
 */
char*
get_nvts_omp (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return get_nvts (connection, credentials, params, NULL, NULL, response_data);
}

/**
 * @brief Toggle overrides.
 *
 * @param[in]  params     Request parameters.
 * @param[in]  overrides  New overrides value.
 */
static void
params_toggle_overrides (params_t *params, const char *overrides)
{
  param_t *filt_id, *build_filter;
  const char *new_filt_id;

  build_filter = params_get (params, "build_filter");

  if (build_filter)
    new_filt_id = "";
  else
    new_filt_id = "0";

  filt_id = params_get (params, "filt_id");
  if (filt_id)
    {
      filt_id->value = g_strdup (new_filt_id);
      filt_id->value_size = strlen (filt_id->value);
      filt_id->valid = 1;
      filt_id->valid_utf8 = 1;
    }
  else
    params_add (params, "filt_id", new_filt_id);

  if (build_filter == NULL)
    {
      param_t *filter;
      filter = params_get (params, "filter");
      if (filter && filter->value)
        {
          gchar *old;
          old = filter->value;
          filter->value = g_strdup_printf ("apply_overrides=%s %s",
                                           overrides,
                                           old);
          g_free (old);
        }
      else if (strcmp (overrides, "0"))
        params_add (params, "filter",
                    "apply_overrides=1 rows=-2");
      else
        params_add (params, "filter",
                    "apply_overrides=0 rows=-2");
    }
}

/**
 * @brief Get all tasks, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_tasks (openvas_connection_t *connection, credentials_t *credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  const char *overrides, *schedules_only, *ignore_pagination;
  gchar *extra_attribs, *ret;

  overrides = params_value (params, "overrides");
  schedules_only = params_value (params, "schedules_only");
  ignore_pagination = params_value (params, "ignore_pagination");

  if (overrides)
    /* User toggled overrides.  Set the overrides value in the filter. */
    params_toggle_overrides (params, overrides);

  extra_attribs = g_strdup_printf ("%s%s%s"
                                   "%s%s%s",
                                   schedules_only ? "schedules_only=\"" : "",
                                   schedules_only ? schedules_only : "",
                                   schedules_only ? "\" " : "",
                                   ignore_pagination
                                    ? "ignore_pagination=\""
                                    : "",
                                   ignore_pagination ? ignore_pagination : "",
                                   ignore_pagination ? "\" " : "");

  ret = get_many (connection, "task", credentials, params, extra_xml,
                  extra_attribs, response_data);
  g_free (extra_attribs);
  return ret;
}

/**
 * @brief Get all tasks, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_tasks_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return get_tasks (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get a tasks chart, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_tasks_chart (openvas_connection_t *connection, credentials_t *credentials,
                 params_t *params, const char *extra_xml,
                 cmd_response_data_t* response_data)
{
  return xsl_transform_omp (connection, credentials, params,
                            g_strdup ("<get_tasks_chart/>"), response_data);
}

/**
 * @brief Get a tasks chart, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_tasks_chart_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  return get_tasks_chart (connection, credentials, params, NULL, response_data);
}


/**
 * @brief Get all tasks, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_task (openvas_connection_t *connection, credentials_t *credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  GString *xml = NULL;
  GString *commands_xml = NULL;
  entity_t commands_entity = NULL;
  entity_t task_entity = NULL;
  int notes, get_overrides, apply_overrides;
  int get_target, get_alerts;
  const char *overrides, *task_id;

  task_id = params_value (params, "task_id");
  if (task_id == NULL)
    return get_tasks (connection, credentials, params, extra_xml,
                      response_data);

  overrides = params_value (params, "overrides");
  apply_overrides = overrides ? strcmp (overrides, "0") : 1;

  notes = command_enabled (credentials, "GET_NOTES");
  get_overrides = command_enabled (credentials, "GET_OVERRIDES");
  if (openvas_connection_sendf
       (connection,
        "<commands>"
        "<get_tasks"
        " task_id=\"%s\""
        " filter=\"apply_overrides=%i\""
        " details=\"0\"/>"
        "%s%s%s"
        "%s%s%s"
        "</commands>",
        task_id,
        apply_overrides,
        notes
         ? "<get_notes"
           " sort_field=\"notes_nvt_name, notes.text\""
           " task_id=\""
         : "",
        notes ? task_id : "",
        notes ? "\"/>" : "",
        get_overrides
         ? "<get_overrides"
           " sort_field=\"overrides_nvt_name, overrides.text\""
           " task_id=\""
         : "",
        get_overrides ? task_id : "",
        get_overrides ? "\"/>" : "")
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the status. "
                           "No update on the requested task can be retrieved. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  commands_xml = g_string_new ("");
  xml = g_string_new ("<get_task>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  g_string_append_printf (xml,
                          "<apply_overrides>%i</apply_overrides>"
                          "<delta>%s</delta>",
                          apply_overrides,
                          params_value (params, "delta_report_id")
                           ? params_value (params, "delta_report_id")
                           : "");
  if (read_string_c (connection, &commands_xml))
    {
      g_string_free (commands_xml, TRUE);
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the status. "
                           "No update of the status can be retrieved. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }
  g_string_append (xml, commands_xml->str);

  if (parse_entity (commands_xml->str, &commands_entity))
    {
      g_string_free (commands_xml, TRUE);
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the status. "
                           "No update of the status can be retrieved. "
                           "Diagnostics: Failure to parse response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  get_target = command_enabled (credentials, "GET_TARGETS");
  get_alerts = command_enabled (credentials, "GET_ALERTS");
  task_entity = entity_child (commands_entity, "get_tasks_response");
  if (task_entity == NULL)
    {
      g_warning ("%s: No get_tasks_response found in manager response.",
                 __FUNCTION__);
    }
  else
    {
      task_entity = entity_child (task_entity, "task");
      if (task_entity == NULL)
        g_message ("%s: No task found in manager response.", __FUNCTION__);
      else if (get_target || get_alerts)
        {
          entities_t child_entities;
          entity_t child_entity;
          child_entities = task_entity->entities;

          while ((child_entity = first_entity (child_entities)))
            {
              if (get_alerts &&
                  strcmp (entity_name (child_entity), "alert") == 0)
                {
                  const char *resource_id
                    = entity_attribute (child_entity, "id");

                  if (resource_id != NULL && strcmp (resource_id, ""))
                    {
                      if (openvas_connection_sendf (connection,
                                                    "<get_alerts"
                                                    " alert_id=\"%s\"/>",
                                                    resource_id))
                        {
                          g_string_free (xml, TRUE);
                          g_string_free (commands_xml, TRUE);
                          free_entity (commands_entity);
                          response_data->http_status_code
                            = MHD_HTTP_INTERNAL_SERVER_ERROR;
                          return gsad_message (credentials,
                                              "Internal error",
                                              __FUNCTION__, __LINE__,
                                              "An internal error occurred while getting an alert of a task. "
                                              "Diagnostics: Failure to send command to manager daemon.",
                                              "/omp?cmd=get_tasks",
                                               response_data);
                        }
                      if (read_string_c (connection, &xml))
                        {
                          g_string_free (commands_xml, TRUE);
                          g_string_free (xml, TRUE);
                          free_entity (commands_entity);
                          response_data->http_status_code
                            = MHD_HTTP_INTERNAL_SERVER_ERROR;
                          return gsad_message (credentials,
                                              "Internal error",
                                              __FUNCTION__, __LINE__,
                                              "An internal error occurred while getting an alert of a task. "
                                              "Diagnostics: Failure to receive response from manager daemon.",
                                              "/omp?cmd=get_tasks",
                                               response_data);
                        }
                    }
                }

              if (get_target &&
                  strcmp (entity_name (child_entity), "target") == 0)
                {
                  const char *resource_id
                    = entity_attribute (child_entity, "id");

                  if (resource_id != NULL && strcmp (resource_id, ""))
                    {
                      if (openvas_connection_sendf (connection,
                                                    "<get_targets"
                                                    " target_id=\"%s\"/>",
                                                    resource_id))
                        {
                          g_string_free (xml, TRUE);
                          g_string_free (commands_xml, TRUE);
                          free_entity (commands_entity);
                          response_data->http_status_code
                            = MHD_HTTP_INTERNAL_SERVER_ERROR;
                          return gsad_message (credentials,
                                              "Internal error",
                                              __FUNCTION__, __LINE__,
                                              "An internal error occurred while getting the target of a task. "
                                              "Diagnostics: Failure to send command to manager daemon.",
                                              "/omp?cmd=get_tasks",
                                               response_data);
                        }
                      if (read_string_c (connection, &xml))
                        {
                          g_string_free (commands_xml, TRUE);
                          g_string_free (xml, TRUE);
                          free_entity (commands_entity);
                          response_data->http_status_code
                            = MHD_HTTP_INTERNAL_SERVER_ERROR;
                          return gsad_message (credentials,
                                              "Internal error",
                                              __FUNCTION__, __LINE__,
                                              "An internal error occurred while getting the target of a task. "
                                              "Diagnostics: Failure to receive response from manager daemon.",
                                              "/omp?cmd=get_tasks",
                                               response_data);
                        }
                    }
                }

              child_entities = next_entities (child_entities);
            }
        }
    }

  g_string_free (commands_xml, TRUE);
  free_entity (commands_entity);

  /* Get slave scanners. */

  if (command_enabled (credentials, "GET_SCANNERS"))
    {
      if (openvas_connection_sendf (connection,
                                    "<get_scanners"
                                    " filter=\"first=1 rows=-1 type=4\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while getting slaves list. "
                              "The current list of resources is not available. "
                              "Diagnostics: Failure to send command to manager daemon.",
                              "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while getting slaves list. "
                              "The current list of resources is not available. "
                              "Diagnostics: Failure to receive response from manager daemon.",
                              "/omp?cmd=get_tasks", response_data);
        }
    }

  /* Get tag names */

  if (openvas_connection_sendf (connection,
                                "<get_tags"
                                " filter=\"resource_type=task"
                                "          first=1"
                                "          rows=-1\""
                                " names_only=\"1\""
                                "/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting tag names list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting tag names list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  /* Get permissions */

  g_string_append (xml, "<permissions>");

  if (openvas_connection_sendf (connection,
                                "<get_permissions"
                                " filter=\"name:^.*(task)s?$"
                                "          and resource_uuid=%s"
                                "          first=1 rows=-1\"/>",
                                task_id)
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting permissions list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting permissions list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  g_string_append (xml, "</permissions>");

  g_string_append (xml, "</get_task>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Get a task, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_task_omp (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return get_task (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Returns page to create a new Credential.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_credential (openvas_connection_t *connection, credentials_t *credentials,
                params_t *params, const char *extra_xml,
                cmd_response_data_t* response_data)
{
  GString *xml;
  xml = g_string_new ("<new_credential>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_credential>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Create a credential, get all credentials, XSL transform result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_credential_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect;
  const char *name, *comment, *login, *type, *password, *passphrase;
  const char *private_key, *certificate, *community, *privacy_password;
  const char *auth_algorithm, *privacy_algorithm, *allow_insecure;
  int autogenerate;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  login = params_value (params, "credential_login");
  type = params_value (params, "base");
  password = params_value (params, "lsc_password");
  passphrase = params_value (params, "passphrase");
  private_key = params_value (params, "private_key");
  certificate = params_value (params, "certificate");
  community = params_value (params, "community");
  privacy_password = params_value (params, "privacy_password");
  auth_algorithm = params_value (params, "auth_algorithm");
  privacy_algorithm = params_value (params, "privacy_algorithm");
  allow_insecure = params_value (params, "allow_insecure");

  if (params_value (params, "autogenerate"))
    autogenerate = strcmp (params_value (params, "autogenerate"), "0");
  else if (params_given (params, "autogenerate"))
    return message_invalid (connection, credentials, params, response_data,
                            "Given autogenerate was invalid",
                            G_STRINGIFY (MHD_HTTP_BAD_REQUEST),
                            "Create Credential", "new_credential");
  else
    autogenerate = 0;

  CHECK_PARAM_INVALID (name, "Create Credential", "new_credential");
  CHECK_PARAM_INVALID (comment, "Create Credential", "new_credential");
  CHECK_PARAM_INVALID (type, "Create Credential", "new_credential");
  CHECK_PARAM_INVALID (allow_insecure, "Create Credential", "new_credential");

  if (autogenerate)
    {
      if (type && (strcmp (type, "cc") == 0))
        {
          // Auto-generate types without username
          ret = ompf (connection,
                      credentials,
                      &response,
                      &entity,
                      response_data,
                      "<create_credential>"
                      "<name>%s</name>"
                      "<comment>%s</comment>"
                      "<type>%s</type>"
                      "<allow_insecure>%s</allow_insecure>"
                      "</create_credential>",
                      name,
                      comment ? comment : "",
                      type,
                      allow_insecure);
        }
      else
        {
          // Auto-generate types with username
          CHECK_PARAM_INVALID (login, "Create Credential", "new_credential");

          ret = ompf (connection, credentials,
                      &response,
                      &entity,
                      response_data,
                      "<create_credential>"
                      "<name>%s</name>"
                      "<comment>%s</comment>"
                      "<type>%s</type>"
                      "<login>%s</login>"
                      "<allow_insecure>%s</allow_insecure>"
                      "</create_credential>",
                      name,
                      comment ? comment : "",
                      type,
                      login,
                      allow_insecure);
        }
    }
  else
    {
      if (type && (strcmp (type, "up") == 0))
        {
          CHECK_PARAM_INVALID (login,
                                "Create Credential", "new_credential");
          CHECK_PARAM_INVALID (password,
                                "Create Credential", "new_credential");

          ret = ompf (connection, credentials,
                      &response,
                      &entity,
                      response_data,
                      "<create_credential>"
                      "<name>%s</name>"
                      "<comment>%s</comment>"
                      "<type>%s</type>"
                      "<login>%s</login>"
                      "<password>%s</password>"
                      "<allow_insecure>%s</allow_insecure>"
                      "</create_credential>",
                      name,
                      comment ? comment : "",
                      type,
                      login ? login : "",
                      password ? password : "",
                      allow_insecure);
        }
      else if (type && (strcmp (type, "usk") == 0))
        {
          CHECK_PARAM_INVALID (login,
                                "Create Credential", "new_credential");
          CHECK_PARAM_INVALID (passphrase,
                                "Create Credential", "new_credential");
          CHECK_PARAM_INVALID (private_key,
                                "Create Credential", "new_credential");

          ret = ompf (connection, credentials,
                      &response,
                      &entity,
                      response_data,
                      "<create_credential>"
                      "<name>%s</name>"
                      "<comment>%s</comment>"
                      "<type>%s</type>"
                      "<login>%s</login>"
                      "<key>"
                      "<private>%s</private>"
                      "<phrase>%s</phrase>"
                      "</key>"
                      "<allow_insecure>%s</allow_insecure>"
                      "</create_credential>",
                      name,
                      comment ? comment : "",
                      type,
                      login ? login : "",
                      private_key ? private_key : "",
                      passphrase ? passphrase : "",
                      allow_insecure);
        }
      else if (type && (strcmp (type, "cc") == 0))
        {
          CHECK_PARAM_INVALID (certificate,
                                "Create Credential", "new_credential");
          CHECK_PARAM_INVALID (private_key,
                                "Create Credential", "new_credential");

          ret = ompf (connection, credentials,
                      &response,
                      &entity,
                      response_data,
                      "<create_credential>"
                      "<name>%s</name>"
                      "<comment>%s</comment>"
                      "<type>%s</type>"
                      "<certificate>%s</certificate>"
                      "<key>"
                      "<private>%s</private>"
                      "</key>"
                      "<allow_insecure>%s</allow_insecure>"
                      "</create_credential>",
                      name,
                      comment ? comment : "",
                      type,
                      certificate ? certificate : "",
                      private_key ? private_key : "",
                      allow_insecure);

        }
      else if (type && (strcmp (type, "snmp") == 0))
        {
          CHECK_PARAM_INVALID (community,
                                "Create Credential", "new_credential");
          CHECK_PARAM_INVALID (login,
                                "Create Credential", "new_credential");
          CHECK_PARAM_INVALID (password,
                                "Create Credential", "new_credential");
          CHECK_PARAM_INVALID (privacy_password,
                                "Create Credential", "new_credential");
          CHECK_PARAM_INVALID (auth_algorithm,
                                "Create Credential", "new_credential");
          CHECK_PARAM_INVALID (privacy_algorithm,
                                "Create Credential", "new_credential");

          if (privacy_password && strcmp (privacy_password, ""))
            ret = ompf (connection, credentials,
                        &response,
                        &entity,
                        response_data,
                        "<create_credential>"
                        "<name>%s</name>"
                        "<comment>%s</comment>"
                        "<type>%s</type>"
                        "<community>%s</community>"
                        "<login>%s</login>"
                        "<password>%s</password>"
                        "<privacy>"
                        "<password>%s</password>"
                        "<algorithm>%s</algorithm>"
                        "</privacy>"
                        "<auth_algorithm>%s</auth_algorithm>"
                        "<allow_insecure>%s</allow_insecure>"
                        "</create_credential>",
                        name,
                        comment ? comment : "",
                        type,
                        community ? community : "",
                        login ? login : "",
                        password ? password : "",
                        privacy_password ? privacy_password : "",
                        privacy_algorithm ? privacy_algorithm : "",
                        auth_algorithm ? auth_algorithm : "",
                        allow_insecure);
          else
            ret = ompf (connection, credentials,
                        &response,
                        &entity,
                        response_data,
                        "<create_credential>"
                        "<name>%s</name>"
                        "<comment>%s</comment>"
                        "<type>%s</type>"
                        "<community>%s</community>"
                        "<login>%s</login>"
                        "<password>%s</password>"
                        "<auth_algorithm>%s</auth_algorithm>"
                        "<allow_insecure>%s</allow_insecure>"
                        "</create_credential>",
                        name,
                        comment ? comment : "",
                        type,
                        community ? community : "",
                        login ? login : "",
                        password ? password : "",
                        auth_algorithm ? auth_algorithm : "",
                        allow_insecure);
        }
      else
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while creating a new credential. "
                               "The credential could not be created. "
                               "Diagnostics: Unrecognized credential type.",
                               "/omp?cmd=get_credentials", response_data);
        }
    }

  /* Create the credential. */
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new credential. "
                             "It is unclear whether the credential has been created or not. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_credentials", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new credential. "
                             "It is unclear whether the credential has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_credentials", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new credential. "
                             "It is unclear whether the credential has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_credentials", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "credential_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_credentials",
                               NULL, "new_credential",
                               "Create Credential",
                               response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Get one credential, XSL transform the result.
 *
 * @param[in]   connection    Connection to manager
 * @param[in]   credentials   Username and password for authentication.
 * @param[in]   params        Request parameters.
 * @param[in]   commands      Extra commands to run before the others.
 * @param[out]  response_data Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_credential (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, const char *extra_xml,
                cmd_response_data_t* response_data)
{
  return get_one (connection, "credential", credentials, params, extra_xml,
                  "targets=\"1\" scanners=\"1\"", response_data);
}

/**
 * @brief Get one credential, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_credential_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  return get_credential (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Export a Credential in a defined format.
 *
 * @param[in]   connection     Connection to manager
 * @param[in]   credentials    Username and password for authentication.
 * @param[in]   params         Request parameters.
 * @param[out]  result_len     Length of result.
 * @param[out]  html           Result of XSL transformation.  Required.
 * @param[out]  login          Login name return.  NULL to skip.  Only set on
 *                              success with credential_id.
 * @param[out]  response_data  Extra data return for the HTTP response.
 *
 * @return 0 success, 1 failure.
 */
int
download_credential_omp (openvas_connection_t *connection,
                         credentials_t * credentials,
                         params_t *params,
                         gsize *result_len,
                         char ** html,
                         char ** login,
                         cmd_response_data_t* response_data)
{
  entity_t entity;
  const char *credential_id, *format;

  assert (html);

  if (result_len) *result_len = 0;

  /* Send the request. */

  credential_id = params_value (params, "credential_id");
  format = params_value (params, "package_format");

  if ((credential_id == NULL) || (format == NULL))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      *html = gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting a credential. "
                            "Diagnostics: Required parameter was NULL.",
                            "/omp?cmd=get_credentials", response_data);
      return 1;
    }

  if (openvas_connection_sendf (connection,
                                "<get_credentials"
                                " credential_id=\"%s\""
                                " format=\"%s\"/>",
                                credential_id,
                                format)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      *html = gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting a credential. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_credentials", response_data);
      return 1;
    }

  /* Read and handle the response. */

  if (strcmp (format, "rpm") == 0
      || strcmp (format, "deb") == 0
      || strcmp (format, "exe") == 0)
    {
      gchar *package_decoded = NULL;
      entity_t package_entity = NULL, credential_entity;

      /* A base64 encoded package. */

      entity = NULL;
      if (read_entity_c (connection, &entity))
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          *html = gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a credential. "
                                "The credential is not available. "
                                "Diagnostics: Failure to receive response from manager daemon.",
                                "/omp?cmd=get_credentials", response_data);
          return 1;
        }

      credential_entity = entity_child (entity, "credential");
      if (credential_entity)
        package_entity = entity_child (credential_entity, "package");
      if (package_entity != NULL)
        {
          gsize len;
          char *package_encoded = entity_text (package_entity);
          if (strlen (package_encoded))
            {
              package_decoded = (gchar *) g_base64_decode (package_encoded,
                                                           &len);
              if (package_decoded == NULL)
                {
                  package_decoded = (gchar *) g_strdup ("");
                  len = 0;
                }
            }
          else
            {
              package_decoded = (gchar *) g_strdup ("");
              len = 0;
            }
          if (result_len) *result_len = len;
          *html = package_decoded;
          if (login)
            {
              entity_t login_entity;
              login_entity = entity_child (credential_entity, "login");
              if (login_entity)
                *login = g_strdup (entity_text (login_entity));
              else
                *login = NULL;
            }
          free_entity (entity);
          return 0;
        }
      else
        {
          free_entity (entity);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          *html = gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a credential. "
                                "The credential could not be delivered. "
                                "Diagnostics: Failure to receive credential from manager daemon.",
                                "/omp?cmd=get_credentials", response_data);
          return 1;
        }
    }
  else
    {
      entity_t credential_entity, key_entity = NULL;

      /* A key or certificate. */

      entity = NULL;
      if (read_entity_c (connection, &entity))
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          *html = gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a credential. "
                                "The credential could not be delivered. "
                                "Diagnostics: Failure to receive credential from manager daemon.",
                                "/omp?cmd=get_credentials", response_data);
          return 1;
        }

      credential_entity = entity_child (entity, "credential");
      if (credential_entity)
        {
          if (strcmp (format, "pem") == 0)
            key_entity = entity_child (credential_entity, "certificate");
          else
            key_entity = entity_child (credential_entity, "public_key");
        }
      if (key_entity != NULL)
        {
          *html = g_strdup (entity_text (key_entity));
          if (login)
            {
              entity_t login_entity = entity_child (credential_entity, "login");
              if (login_entity)
                *login = g_strdup (entity_text (login_entity));
              else
                *login = NULL;
            }
          free_entity (entity);
          return 0;
        }
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      *html = gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting a credential. "
                            "The credential could not be delivered. "
                            "Diagnostics: Failure to parse credential from manager daemon.",
                            "/omp?cmd=get_credentials", response_data);
      free_entity (entity);
      return 1;
    }
}

/**
 * @brief Export a Credential.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Credential XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_credential_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       enum content_type * content_type,
                       char **content_disposition, gsize *content_length,
                       cmd_response_data_t* response_data)
{
  return export_resource (connection, "credential", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of Credentials.
 *
 * @param[in]  connection            Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Credentials XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_credentials_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        enum content_type * content_type,
                        char **content_disposition, gsize *content_length,
                        cmd_response_data_t* response_data)
{
  return export_many (connection, "credential", credentials, params,
                      content_type, content_disposition, content_length,
                      response_data);
}

/**
 * @brief Get one or all credentials, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  commands       Extra commands to run before the others when
 *                            credential_id is NULL.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return 0 success, 1 failure.
 */
static char *
get_credentials (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, const char *extra_xml,
                 cmd_response_data_t* response_data)
{
  return get_many (connection, "credential", credentials, params, extra_xml,
                   NULL, response_data);
}

/**
 * @brief Get one or all credentials, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return 0 success, 1 failure.
 */
char *
get_credentials_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  return get_credentials (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Delete credential, get all credentials, XSL transform result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_credential_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  return delete_resource (connection, "credential", credentials, params, 0,
                          "get_credentials", response_data);
}

/**
 * @brief Returns page to create a new Credential.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_credential_omp (openvas_connection_t *connection,
                    credentials_t *credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  return new_credential (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Setup edit_credential XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
edit_credential (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, const char *extra_xml,
                 cmd_response_data_t* response_data)
{
  return edit_resource (connection, "credential", credentials, params, NULL,
                        extra_xml, response_data);
}

/**
 * @brief Setup edit_credential XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_credential_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  return edit_credential (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Save credential, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_credential_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  int ret, change_password, change_passphrase;
  int change_community, change_privacy_password;
  gchar *html, *response;
  const char *no_redirect, *credential_id;
  const char *name, *comment, *login, *password, *passphrase;
  const char *private_key, *certificate, *community, *privacy_password;
  const char *auth_algorithm, *privacy_algorithm, *allow_insecure;
  GString *command;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  credential_id = params_value (params, "credential_id");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  login = params_value (params, "credential_login");
  password = params_value (params, "password");
  passphrase = params_value (params, "passphrase");
  private_key = params_value (params, "private_key");
  certificate = params_value (params, "certificate");
  community = params_value (params, "community");
  privacy_password = params_value (params, "privacy_password");
  auth_algorithm = params_value (params, "auth_algorithm");
  privacy_algorithm = params_value (params, "privacy_algorithm");
  allow_insecure = params_value (params, "allow_insecure");

  CHECK_PARAM_INVALID (credential_id, "Save Credential", "edit_credential");
  CHECK_PARAM_INVALID (name, "Save Credential", "edit_credential");
  CHECK_PARAM_INVALID (comment, "Save Credential", "edit_credential");
  CHECK_PARAM_INVALID (allow_insecure, "Save Credential", "edit_credential");
  if (params_given (params, "certificate"))
    CHECK_PARAM_INVALID (certificate, "Save Credential", "edit_credential");
  if (params_given (params, "private_key"))
    CHECK_PARAM_INVALID (private_key, "Save Credential", "edit_credential");
  if (params_given (params, "login"))
    CHECK_PARAM_INVALID (login, "Save Credential", "edit_credential");
  if (params_given (params, "auth_algorithm"))
    CHECK_PARAM_INVALID (auth_algorithm, "Save Credential", "edit_credential");
  if (params_given (params, "privacy_algorithm"))
    CHECK_PARAM_INVALID (privacy_algorithm,
                          "Save Credential", "edit_credential");

  change_community = (params_value (params, "change_community") ? 1 : 0);
  if (change_community)
    CHECK_PARAM_INVALID (community, "Save Credential", "edit_credential");
  change_passphrase = (params_value (params, "change_passphrase") ? 1 : 0);
  if (change_passphrase)
    CHECK_PARAM_INVALID (passphrase, "Save Credential", "edit_credential");
  change_password = (params_value (params, "change_password") ? 1 : 0);
  if (change_password)
    CHECK_PARAM_INVALID (password, "Save Credential", "edit_credential");
  change_privacy_password
    = (params_value (params, "change_privacy_password") ? 1 : 0);
  if (change_privacy_password)
    CHECK_PARAM_INVALID (privacy_password,
                          "Save Credential", "edit_credential");

  /* Prepare command */
  command = g_string_new ("");

  xml_string_append (command,
                     "<modify_credential credential_id=\"%s\">"
                     "<name>%s</name>"
                     "<comment>%s</comment>"
                     "<allow_insecure>%s</allow_insecure>",
                     credential_id,
                     name,
                     comment,
                     allow_insecure);

  if (auth_algorithm)
    xml_string_append (command,
                       "<auth_algorithm>%s</auth_algorithm>",
                       auth_algorithm);

  if (certificate && strcmp (certificate, ""))
    xml_string_append (command,
                       "<certificate>%s</certificate>",
                       certificate);

  if (change_community)
    xml_string_append (command,
                       "<community>%s</community>",
                       community);

  if (login && strcmp (login, ""))
    xml_string_append (command,
                       "<login>%s</login>",
                       login);

  if (change_password)
    xml_string_append (command,
                       "<password>%s</password>",
                       password);

  if (privacy_algorithm || change_privacy_password)
    {
      xml_string_append (command,
                         "<privacy>");
      if (privacy_algorithm && strcmp (privacy_algorithm, ""))
        {
          xml_string_append (command,
                             "<algorithm>%s</algorithm>",
                             privacy_algorithm);
          if (change_privacy_password)
            xml_string_append (command,
                               "<password>%s</password>",
                               privacy_password);
        }
      else if (privacy_algorithm)
        {
          xml_string_append (command,
                             "<algorithm></algorithm>");
          xml_string_append (command,
                             "<password></password>");
        }

      xml_string_append (command,
                         "</privacy>");
    }

  if ((private_key && strcmp (private_key, "")) || change_passphrase)
    {
      xml_string_append (command,
                         "<key>");
      if (change_passphrase)
        xml_string_append (command,
                           "<phrase>%s</phrase>",
                           passphrase);
      if (private_key)
        xml_string_append (command,
                           "<private>%s</private>",
                           private_key);
      xml_string_append (command,
                         "</key>");
    }

  xml_string_append (command,
                     "</modify_credential>");

  /* Modify the credential. */
  response = NULL;
  entity = NULL;
  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             command->str);
  g_string_free (command, TRUE);

  switch (ret)
    {
      case 0:
        break;
      case -1:
        /* 'omp' set response. */
        return response;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a Credential. "
                             "The Credential was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_credentials", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a Credential. "
                             "It is unclear whether the Credential has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_credentials", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a Credential. "
                             "It is unclear whether the Credential has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_credentials", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_credentials",
                               NULL, "edit_credential",
                               "Save Credential", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Returns page to create a new agent.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_agent (openvas_connection_t *connection, credentials_t *credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  GString *xml;
  xml = g_string_new ("<new_agent>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_agent>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the new agent page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_agent_omp (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return new_agent (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create an agent, get all agents, XSL transform result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_agent_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  entity_t entity;
  gchar *response, *html;
  const char *no_redirect;
  const char *name, *comment, *installer, *installer_filename, *installer_sig;
  const char *howto_install, *howto_use;
  int installer_size, installer_sig_size, howto_install_size, howto_use_size;
  int ret;
  gchar *name_escaped, *comment_escaped;
  gchar *installer_64, *installer_sig_64, *howto_install_64, *howto_use_64;
  gchar *command;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  installer = params_value (params, "installer");
  installer_filename = params_filename (params, "installer");
  installer_size = params_value_size (params, "installer");
  installer_sig = params_value (params, "installer_sig");
  installer_sig_size = params_value_size (params, "installer_sig");
  howto_install = params_value (params, "howto_install");
  howto_install_size = params_value_size (params, "howto_install");
  howto_use = params_value (params, "howto_use");
  howto_use_size = params_value_size (params, "howto_use");

  CHECK_PARAM_INVALID (name, "Create Agent", "new_agent");
  CHECK_PARAM_INVALID (comment, "Create Agent", "new_agent");

  /* Create the agent. */

  installer_64 = (installer_size > 0)
                 ? g_base64_encode ((guchar *) installer,
                                    installer_size)
                 : g_strdup ("");

  installer_sig_64 = (installer_sig_size > 0)
                     ? g_base64_encode ((guchar *) installer_sig,
                                        installer_sig_size)
                     : g_strdup ("");

  howto_install_64 = (howto_install_size > 0)
                     ? g_base64_encode ((guchar *) howto_install,
                                        howto_install_size)
                     : g_strdup ("");

  howto_use_64 = (howto_use_size > 0)
                 ? g_base64_encode ((guchar *) howto_use,
                                    howto_use_size)
                 : g_strdup ("");

  name_escaped = name ? g_markup_escape_text (name, -1) : NULL;
  comment_escaped = comment ? g_markup_escape_text (comment, -1) : NULL;

  command = g_strdup_printf ("<create_agent>"
                             "<name>%s</name>"
                             "%s%s%s"
                             "<installer>"
                             "%s"
                             "<signature>%s</signature>"
                             "<filename>%s</filename>"
                             "</installer>"
                             "<howto_install>%s</howto_install>"
                             "<howto_use>%s</howto_use>"
                             "</create_agent>",
                             name_escaped,
                             comment_escaped ? "<comment>" : "",
                             comment_escaped ? comment_escaped : "",
                             comment_escaped ? "</comment>" : "",
                             installer_64,
                             installer_sig_64,
                             installer_filename ? installer_filename : "",
                             howto_install_64,
                             howto_use_64);

  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             command);
  g_free (command);

  g_free (installer_64);
  g_free (howto_install_64);
  g_free (howto_use_64);
  g_free (name_escaped);
  g_free (comment_escaped);

  switch (ret)
    {
      case 0:
        break;
      case -1:
        /* 'omp' set response. */
        return response;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new agent. "
                            "No new agent was created. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_agents", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new agent. "
                            "It is unclear whether the agent has been created or not. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_agents", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new agent. "
                            "It is unclear whether the agent has been created or not. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=get_agents", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "agent_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_agents",
                               NULL, "new_agent",
                               "Create Agent", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Delete agent, get all agents, XSL transform result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_agent_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  return delete_resource (connection, "agent", credentials, params, 0,
                          "get_agents", response_data);
}

/**
 * @brief Get an agent, XSL transform the result.
 *
 * @param[in]   connection     Connection to manager
 * @param[in]   credentials    Username and password for authentication.
 * @param[in]   params         Request parameters.
 * @param[out]  result_len     Length of result.
 * @param[out]  html           Result of XSL transformation.  Required.
 * @param[out]  filename       Agent filename return.  NULL to skip.  Only set
 *                             on success with agent_id.
 * @param[out]  response_data  Extra data return for the HTTP response.
 *
 * @return 0 success, 1 failure.
 */
int
download_agent_omp (openvas_connection_t *connection,
                    credentials_t * credentials,
                    params_t *params,
                    gsize *result_len,
                    char ** html,
                    char ** filename,
                    cmd_response_data_t* response_data)
{
  entity_t entity;
  const char *agent_id, *format;

  agent_id = params_value (params, "agent_id");
  format = params_value (params, "agent_format");

  if ((agent_id == NULL) || (format == NULL))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      *html = gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while downloading "
                            "an agent. "
                            "Diagnostics: Required parameter was NULL.",
                            "/omp?cmd=get_agents", response_data);
      return 1;
    }

  *result_len = 0;

  /* Send the request. */

  if (openvas_connection_sendf (connection,
                                "<get_agents agent_id=\"%s\" format=\"%s\"/>",
                                agent_id,
                                format)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      *html = gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting agent list. "
                            "The current list of agents is not available. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_agents", response_data);
      return 1;
    }

  /* Read and handle the response. */

  if (strcmp (format, "installer") == 0
      || strcmp (format, "howto_install") == 0
      || strcmp (format, "howto_use") == 0)
    {
      gchar *package_decoded = NULL;
      entity_t package_entity = NULL, agent_entity;

      /* A base64 encoded package. */

      entity = NULL;
      if (read_entity_c (connection, &entity))
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          *html = gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a agent. "
                                "The agent is not available. "
                                "Diagnostics: Failure to receive response from manager daemon.",
                                "/omp?cmd=get_agents", response_data);
          return 1;
        }

      agent_entity = entity_child (entity, "agent");
      if (agent_entity)
        package_entity = entity_child (agent_entity, "package");
      if (package_entity != NULL)
        {
          char *package_encoded = entity_text (package_entity);
          if (strlen (package_encoded))
            {
              package_decoded = (gchar *) g_base64_decode (package_encoded,
                                                           result_len);
              if (package_decoded == NULL)
                {
                  package_decoded = (gchar *) g_strdup ("");
                  *result_len = 0;
                }
            }
          else
            {
              package_decoded = (gchar *) g_strdup ("");
              *result_len = 0;
            }
          *html = package_decoded;
          if (filename)
            {
              entity_t filename_entity;
              filename_entity = entity_child (package_entity,
                                              "filename");
              if (filename_entity)
                *filename = g_strdup (entity_text (filename_entity));
              else
                *filename = NULL;
              if (!(*filename && strlen (*filename)))
                {
                  g_free(*filename);
                  *filename = g_strdup_printf ("agent-%s-%s", agent_id, format);
                }
            }
          free_entity (entity);
          return 0;
        }
      else
        {
          free_entity (entity);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          *html = gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a agent. "
                                "The agent could not be delivered. "
                                "Diagnostics: Failure to receive agent from manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          return 1;
        }
    }
  else
    {
      /* An error. */

      entity = NULL;
      if (read_entity_c (connection, &entity))
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          *html = gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a agent. "
                                "The agent could not be delivered. "
                                "Diagnostics: Failure to receive agent from manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          return 1;
        }

      free_entity (entity);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      *html = gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting a agent. "
                            "The agent could not be delivered. "
                            "Diagnostics: Failure to parse agent from manager daemon.",
                            "/omp?cmd=get_tasks", response_data);
      return 1;
    }
}

/**
 * @brief Setup edit_agent XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_agent (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  return edit_resource (connection, "agent", credentials, params, NULL,
                        extra_xml, response_data);
}

/**
 * @brief Setup edit_agent XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_agent_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return edit_agent (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Modify a agent, get all agents, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_agent_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect, *agent_id, *name, *comment;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  agent_id = params_value (params, "agent_id");
  name = params_value (params, "name");
  comment = params_value (params, "comment");

  CHECK_PARAM_INVALID (agent_id, "Save Agent", "edit_agent");
  CHECK_PARAM_INVALID (name, "Save Agent", "edit_agent");
  CHECK_PARAM_INVALID (comment, "Save Agent", "edit_agent");

  /* Modify the agent. */

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<modify_agent agent_id=\"%s\">"
              "<name>%s</name>"
              "<comment>%s</comment>"
              "</modify_agent>",
              agent_id,
              name,
              comment);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a agent. "
                             "The agent was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_agents", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a agent. "
                             "It is unclear whether the agent has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_agents", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a agent. "
                             "It is unclear whether the agent has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_agents", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_agents",
                               NULL, "edit_agent",
                               "Save Agent", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Get one agent, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_agent (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  return get_one (connection, "agent", credentials, params, extra_xml, NULL,
                  response_data);
}

/**
 * @brief Get one agent, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_agent_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return get_agent (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all agents, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_agents (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  return get_many (connection, "agent", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all agents, XSL transform the result.
 *
 * @param[in]   connection     Connection to manager
 * @param[in]   credentials    Username and password for authentication.
 * @param[in]   params         Request parameters.
 * @param[out]  response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_agents_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return get_agents (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Verify agent, get agents, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
verify_agent_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *agent_id;
  int ret;
  entity_t entity;

  agent_id = params_value (params, "agent_id");
  if (agent_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while verifying an agent. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_agents", response_data);
    }
  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<verify_agent agent_id=\"%s\" />",
              agent_id);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while verifying a agent. "
                             "The agent was not verified. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_agents", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while verifying a agent. "
                             "It is unclear whether the agent was verified or not. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_agents", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while verifying a agent. "
                             "It is unclear whether the agent was verified or not. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_agents", response_data);
    }

  if (omp_success (entity))
    {
      html = next_page (connection, credentials, params, response,
                        response_data);
      if (html == NULL)
        {
          free_entity (entity);
          g_free (response);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while verifying a agent. "
                               "It is unclear whether the agent was verified or not. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_agents", response_data);
        }
    }
  else
    {
      set_http_status_from_entity (entity, response_data);
      html = get_agents (connection, credentials, params, response,
                         response_data);
    }
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Export a agent.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Agent XML on success.  HTML result of XSL transformation on error.
 */
char *
export_agent_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, enum content_type * content_type,
                  char **content_disposition, gsize *content_length,
                  cmd_response_data_t* response_data)
{
  return export_resource (connection, "agent", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of agents.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Agents XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_agents_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   enum content_type * content_type, char **content_disposition,
                   gsize *content_length, cmd_response_data_t* response_data)
{
  return export_many (connection, "agent", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Get an aggregate of resources.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return The aggregate.
 */
char *
get_aggregate_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  params_t *data_columns, *text_columns;
  params_t *sort_fields, *sort_stats, *sort_orders;
  params_iterator_t data_columns_iterator, text_columns_iterator;
  params_iterator_t sort_fields_iterator, sort_stats_iterator;
  params_iterator_t sort_orders_iterator;
  char *param_name;
  param_t *param;

  const char *data_column, *group_column, *subgroup_column, *type;
  const char *filter, *filt_id, *xml_param;
  const char *first_group, *max_groups;
  const char *mode;
  gchar *filter_escaped, *command_escaped, *response;
  entity_t entity;
  GString *xml, *command;
  int ret;

  data_columns = params_values (params, "data_columns:");
  data_column = params_value (params, "data_column");
  text_columns = params_values (params, "text_columns:");
  group_column = params_value (params, "group_column");
  subgroup_column = params_value (params, "subgroup_column");
  type = params_value (params, "aggregate_type");
  filter = params_value (params, "filter");
  filt_id = params_value (params, "filt_id");
  sort_fields = params_values (params, "sort_fields:");
  sort_stats = params_values (params, "sort_stats:");
  sort_orders = params_values (params, "sort_orders:");
  first_group = params_value (params, "first_group");
  max_groups = params_value (params, "max_groups");
  mode = params_value (params, "aggregate_mode");
  if (filter && strcmp (filter, ""))
    filter_escaped = g_markup_escape_text (filter, -1);
  else
    {
      if (filt_id == NULL
          || strcmp (filt_id, "") == 0
          || strcmp (filt_id, "0") == 0)
        filter_escaped = g_strdup ("rows=-2");
      else
        filter_escaped = NULL;
    }
  xml_param = params_value (params, "xml");

  if (xml_param == NULL || atoi (xml_param) == 0)
    {
      return xsl_transform_omp (connection, credentials, params,
                                g_strdup ("<get_aggregate/>"), response_data);
    }
  xml = g_string_new ("<get_aggregate>");

  command = g_string_new ("<get_aggregates");
  g_string_append_printf (command, " type=\"%s\"", type);
  if (data_column)
    g_string_append_printf (command, " data_column=\"%s\"", data_column);
  if (group_column)
    g_string_append_printf (command, " group_column=\"%s\"", group_column);
  if (subgroup_column)
    g_string_append_printf (command,
                            " subgroup_column=\"%s\"", subgroup_column);
  if (filter_escaped && strcmp (filter_escaped, ""))
    g_string_append_printf (command, " filter=\"%s\"", filter_escaped);
  if (filt_id && strcmp (filt_id, ""))
    g_string_append_printf (command, " filt_id=\"%s\"", filt_id);
  if (first_group && strcmp (first_group, ""))
    g_string_append_printf (command, " first_group=\"%s\"", first_group);
  if (max_groups && strcmp (max_groups, ""))
    g_string_append_printf (command, " max_groups=\"%s\"", max_groups);
  if (mode && strcmp (mode, ""))
    g_string_append_printf (command, " mode=\"%s\"", mode);
  g_string_append (command, ">");

  if (sort_fields && sort_stats && sort_orders)
    {
      param_t *field_param, *stat_param, *order_param;
      gchar *field_i, *stat_i, *order_i;

      params_iterator_init (&sort_fields_iterator, sort_fields);
      params_iterator_init (&sort_stats_iterator, sort_stats);
      params_iterator_init (&sort_orders_iterator, sort_orders);

      while (params_iterator_next (&sort_fields_iterator,
                                   &field_i, &field_param)
             && params_iterator_next (&sort_stats_iterator,
                                      &stat_i, &stat_param)
             && params_iterator_next (&sort_orders_iterator,
                                      &order_i, &order_param))
        {
          if (field_param->valid && stat_param->valid && order_param->valid)
            {
              xml_string_append (command,
                                 "<sort field=\"%s\""
                                 "      stat=\"%s\""
                                 "      order=\"%s\"/>",
                                 field_param->value ? field_param->value : "",
                                 stat_param->value ? stat_param->value : "",
                                 order_param->value ? order_param->value : "");
            }
        }
    }

  if (data_columns)
    {
      params_iterator_init (&data_columns_iterator, data_columns);
      while (params_iterator_next (&data_columns_iterator, &param_name, &param))
        {
          if (param->valid)
            {
              xml_string_append (command,
                                "<data_column>%s</data_column>",
                                param->value);
            }
        }
    }

  if (text_columns)
    {
      params_iterator_init (&text_columns_iterator, text_columns);
      while (params_iterator_next (&text_columns_iterator, &param_name, &param))
        {
          if (param->valid)
            {
              xml_string_append (command,
                                "<text_column>%s</text_column>",
                                param->value);
            }
        }
    }

  g_string_append (command, "</get_aggregates>");

  g_free (filter_escaped);

  command_escaped = g_markup_escape_text (command->str, -1);
  g_string_append (xml, command_escaped);
  g_free (command_escaped);

  ret = omp (connection, credentials, &response, &entity, response_data,
             command->str);
  g_string_free (command, TRUE);
  switch (ret)
    {
      case 0:
        break;
      case -1:
        /* 'omp' set response. */
        return response;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting aggregates. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting aggregates. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting aggregates. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  g_string_append (xml, response);

  g_string_append (xml, "</get_aggregate>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to create a new alert.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_alert (openvas_connection_t *connection, credentials_t *credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  GString *xml;
  int ret;
  entity_t entity;
  gchar *response;

  xml = g_string_new ("<new_alert>");
  if (extra_xml)
    g_string_append (xml, extra_xml);

  /* Get Report Formats. */

  response = NULL;
  entity = NULL;
  ret = omp (connection, credentials, &response, &entity, response_data,
             "<get_report_formats filter=\"rows=-1\"/>");
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting Report "
                             "Formats for new alert. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_alerts", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting Report "
                             "Formats for new alert. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_alerts", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting Report "
                             "Formats for new alert. It is unclear whether"
                             " the alert has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_alerts", response_data);
    }
  g_string_append (xml, response);
  g_free (response);
  free_entity (entity);

  /* Get Report Filters. */

  ret = omp (connection, credentials, &response, &entity, response_data,
             "<get_filters filter=\"rows=-1\"/>");

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting Report "
                             "Filters for new alert. "
                             "The task was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_alerts", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting Report "
                             "Filters for new alert. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_alerts", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting Report "
                             "Filters for new alert. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_alerts", response_data);
    }
  g_string_append (xml, response);
  g_free (response);
  free_entity (entity);

  /* Get Tasks. */

  ret = omp (connection, credentials, &response, &entity, response_data,
             "<get_tasks"
             " schedules_only=\"1\""
             " filter=\"owner=any permission=start_task rows=-1\"/>");

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting Tasks"
                             " for new alert. "
                             "The task was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_alerts",
                             response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting Tasks"
                             " for new alert. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_alerts",
                             response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting Tasks"
                             " for new alert. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_alerts",
                             response_data);
    }
  g_string_append (xml, response);
  g_free (response);
  free_entity (entity);

  /* Get Credentials. */

  ret = omp (connection, credentials, &response, &entity, response_data,
             "<get_credentials"
             " filter=\"type=up owner=any permission=any rows=-1\"/>");

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting"
                             " Credentials for new alert. "
                             "The task was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_alerts",
                             response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting"
                             " Credentials for new alert. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_alerts",
                             response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting"
                             " Credentials for new alert. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_alerts",
                             response_data);
    }

  g_string_append (xml, response);
  g_free (response);
  free_entity (entity);

  g_string_append (xml, "</new_alert>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to create a new alert.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_alert_omp (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return new_alert (connection, credentials, params, NULL, response_data);
}

char *
get_alerts (openvas_connection_t*, credentials_t *, params_t *, const char *,
            cmd_response_data_t*);

/**
 * @brief Send event data for an alert.
 *
 * @param[in]   xml     XML.
 * @param[out]  data    Data.
 * @param[out]  event   Event.
 *
 * @return 0 on success, -1 on error.
 */
static void
append_alert_event_data (GString *xml, params_t *data, const char *event)
{
  if (data)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, data);
      while (params_iterator_next (&iter, &name, &param))
        if ((strcmp (event, "Task run status changed") == 0
             && strcmp (name, "status") == 0)
            || ((strcmp (event, "New SecInfo arrived") == 0
                 || strcmp (event, "Updated SecInfo arrived") == 0)
                && strcmp (name, "secinfo_type") == 0))
          xml_string_append (xml,
                             "<data><name>%s</name>%s</data>",
                             name,
                             param->value ? param->value : "");
    }
}

/**
 * @brief Send condition data for an alert.
 *
 * @param[in]   xml        XML.
 * @param[out]  data       Data.
 * @param[out]  condition  Condition.
 */
static void
append_alert_condition_data (GString *xml, params_t *data,
                             const char * condition)
{
  if (data)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, data);
      while (params_iterator_next (&iter, &name, &param))
        {
          if (strcmp (condition, "Filter count at least") == 0)
            {
              if (strcmp (name, "at_least_count") == 0)
                xml_string_append (xml,
                                   "<data><name>count</name>%s</data>",
                                   param->value ? param->value : "");
              if (strcmp (name, "at_least_filter_id") == 0)
                xml_string_append (xml,
                                   "<data><name>filter_id</name>%s</data>",
                                   param->value ? param->value : "");
            }
          else if (strcmp (condition, "Filter count changed") == 0)
            {
              if (strcmp (name, "count") == 0
                  || strcmp (name, "filter_id") == 0)
                xml_string_append (xml,
                                   "<data><name>%s</name>%s</data>",
                                   name,
                                   param->value ? param->value : "");
              else if (strcmp (name, "filter_direction") == 0)
                xml_string_append (xml,
                                   "<data><name>direction</name>%s</data>",
                                   param->value ? param->value : "");
            }
          else if ((strcmp (condition, "Severity at least") == 0
                    && strcmp (name, "severity") == 0)
                   || (strcmp (condition, "Severity changed") == 0
                       && strcmp (name, "direction") == 0))
            xml_string_append (xml,
                               "<data><name>%s</name>%s</data>",
                               name,
                               param->value ? param->value : "");
        }
    }
}

/**
 * @brief Send method data for an alert.
 *
 * @param[in]   xml      XML.
 * @param[out]  data     Data.
 * @param[out]  method   Method.
 */
static void
append_alert_method_data (GString *xml, params_t *data, const char *method)
{
  params_iterator_t iter;
  char *name;
  param_t *param;
  int notice;

  if (data == NULL)
    return;

  params_iterator_init (&iter, data);
  /* Used to check email notice type before sending report formats values */
  notice = 1;
  while (params_iterator_next (&iter, &name, &param))
    if (strcmp (name, "notice") == 0)
      {
        notice = atoi (param->value);
        break;
      }

  if (strcmp (method, "Sourcefire Connector"))
    {
      params_iterator_init (&iter, data);

      while (params_iterator_next (&iter, &name, &param))
        if ((strcmp (method, "HTTP Get") == 0
             && strcmp (name, "URL") == 0)
            || (strcmp (method, "Send") == 0
                && (strcmp (name, "send_host") == 0
                    || strcmp (name, "send_port") == 0
                    || strcmp (name, "send_report_format") == 0))
            || (strcmp (method, "SCP") == 0
                && (strcmp (name, "scp_credential") == 0
                    || strcmp (name, "scp_host") == 0
                    || strcmp (name, "scp_known_hosts") == 0
                    || strcmp (name, "scp_path") == 0
                    || strcmp (name, "scp_report_format") == 0))
            || (strcmp (method, "SMB") == 0
                && (strcmp (name, "smb_credential") == 0
                    || strcmp (name, "smb_file_path") == 0
                    || strcmp (name, "smb_report_format") == 0
                    || strcmp (name, "smb_share_path") == 0))
            || (strcmp (method, "SNMP") == 0
                && (strcmp (name, "snmp_community") == 0
                    || strcmp (name, "snmp_agent") == 0
                    || strcmp (name, "snmp_message") == 0))
            || (strcmp (method, "TippingPoint SMS") == 0
                && (strcmp (name, "tp_sms_credential") == 0
                    || strcmp (name, "tp_sms_hostname") == 0
                    || strcmp (name, "tp_sms_tls_certificate") == 0
                    || strcmp (name, "tp_sms_tls_workaround") == 0))
            || (strcmp (method, "verinice Connector") == 0
                && (strcmp (name, "verinice_server_credential") == 0
                    || strcmp (name, "verinice_server_url") == 0
                    || strcmp (name, "verinice_server_report_format") == 0))
            || (strcmp (method, "Email") == 0
                && (strcmp (name, "to_address") == 0
                    || strcmp (name, "from_address") == 0
                    || strcmp (name, "subject") == 0
                    || strcmp (name, "notice") == 0
                    || (strcmp (name, "notice_report_format") == 0
                        && notice == 0)
                    || (strcmp (name, "notice_attach_format") == 0
                        && notice == 2)))
            || (strcmp (method, "Syslog") == 0
                && strcmp (name, "submethod") == 0)
            || (strcmp (method, "Start Task") == 0
                && strcmp (name, "start_task_task") == 0)
            || strcmp (name, "details_url") == 0)
          xml_string_append (xml,
                             "<data><name>%s</name>%s</data>",
                             name,
                             param->value ? param->value : "");
        else if (strcmp (method, "Email") == 0
                 && notice == 0
                 && strcmp (name, "message") == 0)
          xml_string_append (xml,
                             "<data><name>message</name>%s</data>",
                             param->value ? param->value : "");
        else if (strcmp (method, "Email") == 0
                 && notice == 2
                 && strcmp (name, "message_attach") == 0)
          xml_string_append (xml,
                             "<data><name>message</name>%s</data>",
                             param->value ? param->value : "");

      return;
    }

  params_iterator_init (&iter, data);
  while (params_iterator_next (&iter, &name, &param))
    if (strcmp (name, "pkcs12"))
      {
        if (strcmp (name, "defense_center_ip") == 0
            || strcmp (name, "defense_center_port") == 0)
          xml_string_append (xml,
                             "<data><name>%s</name>%s</data>",
                             name,
                             param->value ? param->value : "");
      }
    else
      {
        gchar *base64;

        /* Special case the pkcs12 file, which is binary. */

        base64 = (param->value && param->value_size)
                  ? g_base64_encode ((guchar*) param->value,
                                     param->value_size)
                  : g_strdup ("");
        xml_string_append (xml,
                           "<data><name>%s</name>%s</data>",
                           name,
                           base64);
        g_free (base64);
      }
}

/**
 * @brief Create an alert, get all alerts, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_alert_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect;
  const char *name, *comment, *condition, *event, *method, *filter_id;
  params_t *method_data, *event_data, *condition_data;
  entity_t entity;
  GString *xml;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  if (params_given (params, "condition"))
    condition = params_value (params, "condition");
  else
    condition = "Always";
  event = params_value (params, "event");
  method = params_value (params, "method");
  filter_id = params_value (params, "filter_id");

  CHECK_PARAM_INVALID (name, "Create Alert", "new_alert");
  CHECK_PARAM_INVALID (comment, "Create Alert", "new_alert");
  CHECK_PARAM_INVALID (condition, "Create Alert", "new_alert");
  CHECK_PARAM_INVALID (event, "Create Alert", "new_alert");
  CHECK_PARAM_INVALID (method, "Create Alert", "new_alert");
  if (strcmp (event, "Task run status changed") == 0)
    {
      CHECK_PARAM_INVALID (filter_id, "Save Alert", "new_alert");
    }

  /* Create the alert. */

  method_data = params_values (params, "method_data:");
  event_data = params_values (params, "event_data:");
  condition_data = params_values (params, "condition_data:");

  xml = g_string_new ("");

  if ((strcmp (event, "New SecInfo arrived") == 0) && event_data)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, event_data);
      while (params_iterator_next (&iter, &name, &param))
        if ((strcmp (name, "feed_event") == 0)
            && param->value
            && (strcmp (param->value, "updated") == 0))
          {
            event = "Updated SecInfo arrived";
            break;
          }
    }

  xml_string_append (xml,
                     "<create_alert>"
                     "<name>%s</name>"
                     "<filter id=\"%s\"/>"
                     "<comment>%s</comment>"
                     "<event>%s",
                     name,
                     filter_id,
                     comment ? comment : "",
                     event);

  append_alert_event_data (xml, event_data, event);

  xml_string_append (xml,
                     "</event>"
                     "<method>%s",
                     method);

  append_alert_method_data (xml, method_data, method);

  xml_string_append (xml,
                     "</method>"
                     "<condition>%s",
                     condition);

  append_alert_condition_data (xml, condition_data, condition);

  xml_string_append (xml,
                     "</condition>"
                     "</create_alert>");

  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             xml->str);
  g_string_free (xml, TRUE);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new alert. "
                            "No new alert was created. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_alerts", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new alert. "
                            "It is unclear whether the alert has been created or not. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_alerts", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new alert. "
                            "It is unclear whether the alert has been created or not. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=get_alerts", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "alert_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_alerts",
                               NULL, "new_alert",
                               "Create Alert", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Delete an alert, get all alerts, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_alert_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  return delete_resource (connection, "alert", credentials, params, 0,
                          "get_alerts", response_data);
}

/**
 * @brief Get one alert, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_alert (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  gchar *html;
  GString *extra;

  extra = g_string_new ("");
  if (extra_xml)
    g_string_append (extra, extra_xml);
  if (command_enabled (credentials, "GET_REPORT_FORMATS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_report_formats"
                   " filter=\"rows=-1\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting Report "
                                 "Formats for the alert. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_alerts", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting Report "
                                 "Formats for the alert. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_alerts", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting Report "
                                 "Formats for the alert. "
                                 "It is unclear whether the task has been saved or not. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_alerts", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_TASKS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_tasks"
                   " schedules_only=\"1\""
                   " filter=\"owner=any permission=start_task rows=-1\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting Tasks "
                                 "for the alert. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_alerts", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting Tasks "
                                 "for the alert. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_alerts", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting Tasks "
                                 "for the alert. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_alerts", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_FILTERS"))
    {
      gchar *response;
      entity_t entity;

      /* Get result filters for condition link. */

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_filters"
                   " filter=\"type=result rows=-1\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting filters "
                                 "for the alert. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_alerts", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting filters "
                                 "for the alert. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_alerts", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting filters "
                                 "for the alert. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_alerts", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  html = get_one (connection, "alert", credentials, params, extra->str,
                  "tasks=\"1\"", response_data);
  g_string_free (extra, TRUE);
  return html;
}

/**
 * @brief Get one alert, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_alert_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return get_alert (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all alerts, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_alerts (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  gchar *html;
  GString *extra;

  extra = g_string_new ("");
  if (command_enabled (credentials, "GET_TASKS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_tasks"
                   " schedules_only=\"1\""
                   " filter=\"owner=any permission=start_task rows=-1\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the tasks. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_tasks",
                                 response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the tasks. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_tasks",
                                 response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the reports. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_tasks",
                                 response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }


  if (command_enabled (credentials, "GET_FILTERS"))
    {
      gchar *response;
      entity_t entity;

      /* Get result filters for condition link. */

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_filters"
                   " filter=\"type=result rows=-1\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting filters "
                                 "for the alerts. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_tasks", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting filters "
                                 "for the alerts. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_tasks", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while getting filters "
                                 "for the alerts. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_tasks", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (extra_xml)
    g_string_append (extra, extra_xml);
  html = get_many (connection, "alert", credentials, params, extra->str, NULL,
                   response_data);
  g_string_free (extra, TRUE);
  return html;
}

/**
 * @brief Get all alerts, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_alerts_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return get_alerts (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Setup edit_alert XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_alert (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  GString *xml;
  gchar *edit;
  const char *alert_id, *next, *filter;

  alert_id = params_value (params, "alert_id");
  next = params_value (params, "next");
  filter = params_value (params, "filter");

  if (alert_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing an alert. "
                           "The alert remains as it was. "
                           "Diagnostics: Required parameter alert_id was NULL.",
                           "/omp?cmd=get_alerts", response_data);
    }

  if (next == NULL)
    next = "get_alerts";

  if (openvas_connection_sendf (connection,
                                "<get_alerts"
                                " alert_id=\"%s\""
                                " details=\"1\"/>",
                                alert_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting alert info. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_alerts", response_data);
    }

  xml = g_string_new ("<edit_alert>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  edit = g_markup_printf_escaped ("<alert id=\"%s\"/>"
                                  /* Page that follows. */
                                  "<next>%s</next>"
                                  /* Passthroughs. */
                                  "<filters><term>%s</term></filters>",
                                  alert_id,
                                  next,
                                  filter);
  g_string_append (xml, edit);
  g_free (edit);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting alert info. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_alerts", response_data);
    }

  if (command_enabled (credentials, "GET_REPORT_FORMATS"))
    {
      /* Get the report formats. */

      if (openvas_connection_sendf (connection,
                                    "<get_report_formats"
                                    " filter=\"rows=-1\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting report formats. "
                               "The current list of report formats is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_alerts", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting report formats. "
                               "The current list of report formats is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_alerts", response_data);
        }
    }

  if (command_enabled (credentials, "GET_FILTERS"))
    {
      /* Get filters. */

      if (openvas_connection_sendf (connection,
                                    "<get_filters filter=\"rows=-1\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the list "
                               "of filters. "
                               "The current list of filters is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_alerts", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the list "
                               "of filters. "
                               "The current list of filters is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_filters", response_data);
        }
    }

  if (command_enabled (credentials, "GET_TASKS"))
    {
      /* Get tasks. */

      if (openvas_connection_sendf (connection,
                                    "<get_tasks"
                                    " schedules_only=\"1\""
                                    " filter=\"owner=any permission=start_task"
                                    "          rows=-1\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the list "
                               "of tasks. "
                               "The current list of tasks is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_alerts", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the list "
                               "of tasks. "
                               "The current list of tasks is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  /* Get Credentials. */

  if (command_enabled (credentials, "GET_CREDENTIALS"))
    {
      if (openvas_connection_sendf (connection,
                                    "<get_credentials"
                                    " filter=\"type=up owner=any permission=any"
                                    "          rows=-1\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the list "
                               "of credentials. "
                               "The current list of tasks is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_alerts", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the list "
                               "of credentials. "
                               "The current list of tasks is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</edit_alert>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup edit_alert XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_alert_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return edit_alert (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Modify an alert, get all alerts, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_alert_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  GString *xml;
  int ret;
  gchar *html, *response;
  const char *no_redirect, *name, *comment, *alert_id;
  const char *event, *condition, *method;
  const char *filter_id;
  params_t *event_data, *condition_data, *method_data;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  if (params_given (params, "condition"))
    condition = params_value (params, "condition");
  else
    condition = "Always";
  event = params_value (params, "event");
  method = params_value (params, "method");
  alert_id = params_value (params, "alert_id");
  filter_id = params_value (params, "filter_id");

  CHECK_PARAM_INVALID (name, "Save Alert", "edit_alert");
  CHECK_PARAM_INVALID (comment, "Save Alert", "edit_alert");
  CHECK_PARAM_INVALID (alert_id, "Save Alert", "edit_alert");
  CHECK_PARAM_INVALID (condition, "Save Alert", "edit_alert");
  CHECK_PARAM_INVALID (event, "Save Alert", "edit_alert");
  CHECK_PARAM_INVALID (method, "Save Alert", "edit_alert");
  if (strcmp (event, "Task run status changed") == 0)
    {
      CHECK_PARAM_INVALID (filter_id, "Save Alert", "edit_alert");
    }

  xml = g_string_new ("");

  /* Modify the alert. */

  event_data = params_values (params, "event_data:");
  condition_data = params_values (params, "condition_data:");
  method_data = params_values (params, "method_data:");

  if ((strcmp (event, "New SecInfo arrived") == 0) && event_data)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, event_data);
      while (params_iterator_next (&iter, &name, &param))
        if ((strcmp (name, "feed_event") == 0)
            && param->value
            && (strcmp (param->value, "updated") == 0))
          {
            event = "Updated SecInfo arrived";
            break;
          }
    }

  xml_string_append (xml,
                     "<modify_alert alert_id=\"%s\">"
                     "<name>%s</name>"
                     "<filter id=\"%s\"/>"
                     "<comment>%s</comment>"
                     "<event>%s",
                     alert_id,
                     name,
                     filter_id,
                     comment ? comment : "",
                     event);

  append_alert_event_data (xml, event_data, event);

  xml_string_append (xml,
                     "</event>"
                     "<method>%s",
                     method);

  append_alert_method_data (xml, method_data, method);

  xml_string_append (xml,
                     "</method>"
                     "<condition>%s",
                     condition);

  append_alert_condition_data (xml, condition_data, condition);

  xml_string_append (xml,
                     "</condition>"
                     "</modify_alert>");

  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             xml->str);
  g_string_free (xml, TRUE);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while saving a new alert. "
                            "No new alert was created. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_alerts", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while saving a new alert. "
                            "It is unclear whether the alert has been created or not. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_alerts", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while saving a new alert. "
                            "It is unclear whether the alert has been created or not. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=get_alerts", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_alerts",
                               NULL, "edit_alert",
                               "Save Alert", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Test an alert, get all alerts XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
test_alert_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *no_redirect, *alert_id;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  alert_id = params_value (params, "alert_id");

  if (alert_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while testing an alert. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_alerts", response_data);
    }

  /* Test the alert. */

  if (openvas_connection_sendf (connection,
                                "<test_alert alert_id=\"%s\"/>",
                                alert_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while testing an alert. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_alerts", response_data);
    }

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, &response))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while testing an alert. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_alerts", response_data);
    }

  /* Cleanup, and return transformed XML. */

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_alerts",
                               NULL, "get_alerts",
                               "Test Alert", response_data);

  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Export an alert.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Alert XML on success.  HTML result of XSL transformation on error.
 */
char *
export_alert_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, enum content_type * content_type,
                  char **content_disposition, gsize *content_length,
                  cmd_response_data_t* response_data)
{
  return export_resource (connection, "alert", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of alerts.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Alerts XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_alerts_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   enum content_type * content_type, char **content_disposition,
                   gsize *content_length, cmd_response_data_t* response_data)
{
  return export_many (connection, "alert", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Returns page to create a new target.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_target (openvas_connection_t *connection, credentials_t *credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  GString *xml;
  gchar *port_list;
  gchar *ssh_credential, *smb_credential, *esxi_credential, *snmp_credential;
  gchar *end;
  const char *filter, *first, *max;

  filter = params_value (params, "filter");
  if (filter == NULL)
    filter = "";

  first = params_value (params, "first");
  if (first == NULL)
    first = "";

  max = params_value (params, "max");
  if (max == NULL)
    max = "";

  PARAM_OR_SETTING (port_list, "port_list_id",
                    "d74a9ee8-7d35-4879-9485-ab23f1bd45bc",);

  PARAM_OR_SETTING (ssh_credential, "ssh_credential_id",
                    "6fc56b72-c1cf-451c-a4c4-3a9dc784c3bd",
                    g_free (port_list));

  PARAM_OR_SETTING (smb_credential, "smb_credential_id",
                    "a25c0cfe-f977-417b-b1da-47da370c03e8",
                    g_free (port_list);
                    g_free (ssh_credential));

  PARAM_OR_SETTING (esxi_credential, "esxi_credential_id",
                    "83545bcf-0c49-4b4c-abbf-63baf82cc2a7",
                    g_free (port_list);
                    g_free (ssh_credential);
                    g_free (smb_credential));

  PARAM_OR_SETTING (snmp_credential, "snmp_credential_id",
                    "024550b8-868e-4b3c-98bf-99bb732f6a0d",
                    g_free (port_list);
                    g_free (ssh_credential);
                    g_free (smb_credential);
                    g_free (esxi_credential));

  xml = g_string_new ("<new_target>");

  g_string_append_printf (xml,
                          "<port_list_id>%s</port_list_id>"
                          "<ssh_credential_id>%s</ssh_credential_id>"
                          "<smb_credential_id>%s</smb_credential_id>"
                          "<esxi_credential_id>%s</esxi_credential_id>"
                          "<snmp_credential_id>%s</snmp_credential_id>",
                          (port_list && strlen (port_list))
                           ? port_list
                           : "33d0cd82-57c6-11e1-8ed1-406186ea4fc5",
                          ssh_credential ? ssh_credential : "",
                          smb_credential ? smb_credential : "",
                          esxi_credential ? esxi_credential : "",
                          snmp_credential ? snmp_credential : "");

  g_free (port_list);
  g_free (ssh_credential);
  g_free (smb_credential);
  g_free (esxi_credential);

  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (command_enabled (credentials, "GET_CREDENTIALS"))
    {
      /* Get the credentials. */

      if (openvas_connection_sendf (connection,
                                    "<get_credentials"
                                    " filter=\"rows=-1 sort=name\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting targets list. "
                               "The current list of targets is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_targets", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting targets list. "
                               "The current list of targets is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_targets", response_data);
        }
    }

  if (command_enabled (credentials, "GET_PORT_LISTS"))
    {
      /* Get the port lists. */

      if (openvas_connection_sendf (connection,
                                    "<get_port_lists"
                                    " filter=\"rows=-1 sort=name\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting targets list. "
                               "The current list of targets is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting targets list. "
                               "The current list of targets is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  end = g_markup_printf_escaped ("<filters><term>%s</term></filters>"
                                 "<targets start=\"%s\" max=\"%s\"/>"
                                 "</new_target>",
                                 filter,
                                 first,
                                 max);
  g_string_append (xml, end);
  g_free (end);

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to create a new target.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_target_omp (openvas_connection_t *connection, credentials_t *credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return new_target (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create a target, get all targets, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_target_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response, *command;
  const char *no_redirect, *name, *hosts, *exclude_hosts, *comment;
  const char *target_ssh_credential, *port, *target_smb_credential;
  const char *target_esxi_credential, *target_snmp_credential, *target_source;
  const char *port_list_id, *reverse_lookup_only, *reverse_lookup_unify;
  const char *alive_tests, *hosts_filter, *file;
  gchar *ssh_credentials_element, *smb_credentials_element;
  gchar *esxi_credentials_element, *snmp_credentials_element;
  gchar *asset_hosts_element;
  gchar* comment_element = NULL;
  entity_t entity;
  GString *xml;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  hosts = params_value (params, "hosts");
  exclude_hosts = params_value (params, "exclude_hosts");
  reverse_lookup_only = params_value (params, "reverse_lookup_only");
  reverse_lookup_unify = params_value (params, "reverse_lookup_unify");
  target_source = params_value (params, "target_source");
  comment = params_value (params, "comment");
  port_list_id = params_value (params, "port_list_id");
  target_ssh_credential = params_value (params, "ssh_credential_id");
  port = params_value (params, "port");
  target_smb_credential = params_value (params, "smb_credential_id");
  target_esxi_credential = params_value (params, "esxi_credential_id");
  target_snmp_credential = params_value (params, "snmp_credential_id");
  alive_tests = params_value (params, "alive_tests");
  hosts_filter = params_value (params, "hosts_filter");
  file = params_value (params, "file");

  CHECK_PARAM_INVALID (name, "Create Target", "new_target");
  CHECK_PARAM_INVALID (target_source, "Create Target", "new_target")
  if (hosts == NULL && strcmp (target_source, "manual") == 0)
    return message_invalid (connection, credentials, params, response_data,
                            "Missing manual list of hosts",
                            G_STRINGIFY (MHD_HTTP_BAD_REQUEST),
                            "Create Target", "new_target");
  if (strcmp (target_source, "file") == 0 && file == NULL)
    return message_invalid (connection, credentials, params, response_data,
                            "Missing hosts file",
                            G_STRINGIFY (MHD_HTTP_BAD_REQUEST),
                            "Create Target", "new_target");

  /* require hosts_filter if target_source is "asset_hosts" */
  if (strcmp (target_source, "asset_hosts") == 0)
    CHECK_PARAM_INVALID (hosts_filter, "Create Target", "new_target");

  CHECK_PARAM_INVALID (comment, "Create Target", "new_target");
  CHECK_PARAM_INVALID (port_list_id, "Create Target", "new_target");
  CHECK_PARAM_INVALID (target_ssh_credential, "Create Target", "new_target");
  if (strcmp (target_ssh_credential, "--"))
    CHECK_PARAM_INVALID (port, "Create Target", "new_target");
  CHECK_PARAM_INVALID (target_smb_credential, "Create Target", "new_target");
  CHECK_PARAM_INVALID (target_esxi_credential, "Create Target", "new_target");
  CHECK_PARAM_INVALID (target_snmp_credential, "Create Target", "new_target");
  CHECK_PARAM_INVALID (alive_tests, "Create Target", "new_target");

  if (comment != NULL)
    comment_element = g_strdup_printf ("<comment>%s</comment>", comment);
  else
    comment_element = g_strdup ("");

  if (strcmp (target_ssh_credential, "0") == 0)
    ssh_credentials_element = g_strdup ("");
  else
    ssh_credentials_element =
      g_strdup_printf ("<ssh_credential id=\"%s\">"
                       "<port>%s</port>"
                       "</ssh_credential>",
                       target_ssh_credential,
                       port);

  if (strcmp (target_smb_credential, "0") == 0)
    smb_credentials_element = g_strdup ("");
  else
    smb_credentials_element =
      g_strdup_printf ("<smb_credential id=\"%s\"/>",
                       target_smb_credential);

  if (strcmp (target_esxi_credential, "0") == 0)
    esxi_credentials_element = g_strdup ("");
  else
    esxi_credentials_element =
      g_strdup_printf ("<esxi_credential id=\"%s\"/>",
                       target_esxi_credential);

  if (strcmp (target_snmp_credential, "0") == 0)
    snmp_credentials_element = g_strdup ("");
  else
    snmp_credentials_element =
      g_strdup_printf ("<snmp_credential id=\"%s\"/>",
                       target_snmp_credential);

  if (strcmp (target_source, "asset_hosts") == 0)
    asset_hosts_element = g_strdup_printf ("<asset_hosts filter=\"%s\"/>",
                                           hosts_filter);
  else
    asset_hosts_element = g_strdup ("");

  /* Create the target. */

  xml = g_string_new ("");

  xml_string_append (xml,
                     "<name>%s</name>"
                     "<hosts>%s</hosts>"
                     "<exclude_hosts>%s</exclude_hosts>"
                     "<reverse_lookup_only>%s</reverse_lookup_only>"
                     "<reverse_lookup_unify>%s</reverse_lookup_unify>"
                     "<port_list id=\"%s\"/>"
                     "<alive_tests>%s</alive_tests>",
                     name,
                     strcmp (target_source, "file") == 0 ? file : hosts,
                     exclude_hosts ? exclude_hosts : "",
                     reverse_lookup_only ? reverse_lookup_only : "0",
                     reverse_lookup_unify ? reverse_lookup_unify : "0",
                     port_list_id,
                     alive_tests);

  command = g_strdup_printf ("<create_target>"
                             "%s%s%s%s%s%s%s"
                             "</create_target>",
                             xml->str,
                             comment_element,
                             ssh_credentials_element,
                             smb_credentials_element,
                             esxi_credentials_element,
                             snmp_credentials_element,
                             asset_hosts_element);

  g_string_free (xml, TRUE);
  g_free (comment_element);
  g_free (ssh_credentials_element);
  g_free (smb_credentials_element);
  g_free (esxi_credentials_element);

  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             command);
  g_free (command);
  switch (ret)
    {
      case 0:
        break;
      case -1:
        /* 'omp' set response. */
        return response;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new target. "
                            "No new target was created. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_targets", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new target. "
                            "It is unclear whether the target has been created or not. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_targets", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new target. "
                            "It is unclear whether the target has been created or not. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=get_targets", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "target_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_targets",
                               NULL, "new_target",
                               "Create Target", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Check a param.
 *
 * @param[in]  name  Param name.
 */
#define CHECK(name)                                                                 \
  if (name == NULL)                                                                 \
    {                                                                               \
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;                       \
      return gsad_message (credentials,                                             \
                           "Internal error", __FUNCTION__, __LINE__,                \
                           "An internal error occurred while cloning a resource. "  \
                           "The resource was not cloned. "                          \
                           "Diagnostics: Required parameter '" G_STRINGIFY (name)   \
                           "' was NULL.",                                           \
                           "/omp?cmd=get_tasks", response_data);                    \
    }

/**
 * @brief Clone a resource, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
clone_omp (openvas_connection_t *connection, credentials_t *credentials,
           params_t *params, cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *id, *type, *alterable, *no_redirect, *next_id;
  gchar *next_id_name, *cap_type, *prev_action;
  entity_t entity;

  id = params_value (params, "id");
  type = params_value (params, "resource_type");
  alterable = params_value (params, "alterable");
  no_redirect = params_value (params, "no_redirect");

  CHECK (id);
  CHECK (type);

  /* Clone the resource. */

  if (alterable && strcmp (alterable, "0"))
    {
      if (openvas_connection_sendf (connection,
                                    "<create_%s>"
                                    "<copy>%s</copy>"
                                    "<alterable>1</alterable>"
                                    "</create_%s>",
                                    type,
                                    id,
                                    type)
          == -1)
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while cloning a resource. "
                               "The resource was not cloned. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }
  else if (openvas_connection_sendf (connection,
                                     "<create_%s>"
                                     "<copy>%s</copy>"
                                     "</create_%s>",
                                     type,
                                     id,
                                     type)
           == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while cloning a resource. "
                           "The resource was not cloned. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, &response))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while cloning a resource. "
                           "It is unclear whether the resource has been cloned or not. "
                           "Diagnostics: Failure to read response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Cleanup, and return next page. */

  if (omp_success (entity) == 0 || params_given (params, "next") == 0)
    {
      gchar *next;
      next = g_strdup_printf ("get_%ss", type);
      params_add (params, "next", next);
      g_free (next);
    }

  if (omp_success (entity))
    {
      next_id = entity_attribute (entity, "id");
      if (next_id == NULL)
        {
          free_entity (entity);
          g_free (response);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while cloning a resource. "
                              "The resource remains the same. "
                              "Diagnostics: Error getting new resource.",
                              "/omp?cmd=get_tasks", response_data);
        }
      next_id_name = g_strdup_printf ("%s_id", type);
      params_add (params, next_id_name, next_id);
      g_free (next_id_name);
    }
  else
    {
      set_http_status_from_entity (entity, response_data);
      next_id_name = NULL;
      next_id = NULL;
    }

  cap_type = capitalize (type);
  prev_action = g_strdup_printf ("Clone %s", cap_type);
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, NULL,
                               NULL, NULL,
                               prev_action, response_data);

  free_entity (entity);
  g_free (cap_type);
  g_free (prev_action);
  g_free (response);

  return html;
}

#undef CHECK

/**
 * @brief Delete a target, get all targets, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_target_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  return delete_resource (connection, "target", credentials, params, 0,
                          "get_targets", response_data);
}

/**
 * @brief Delete a trash agent, get all agents, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_agent_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  return delete_resource (connection, "agent", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a trash config, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_config_omp (openvas_connection_t *connection,
                         credentials_t * credentials, params_t *params,
                         cmd_response_data_t* response_data)
{
  return delete_resource (connection, "config", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a trash alert, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_alert_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  return delete_resource (connection, "alert", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a trash credential, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_credential_omp (openvas_connection_t *connection,
                             credentials_t * credentials, params_t *params,
                             cmd_response_data_t* response_data)
{
  return delete_resource (connection, "credential", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a trash report format, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_report_format_omp (openvas_connection_t *connection,
                                credentials_t * credentials, params_t *params,
                                cmd_response_data_t* response_data)
{
  return delete_resource (connection, "report_format", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a trash schedule, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_schedule_omp (openvas_connection_t *connection,
                           credentials_t * credentials, params_t *params,
                           cmd_response_data_t* response_data)
{
  return delete_resource (connection, "schedule", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a trash target, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_target_omp (openvas_connection_t *connection,
                         credentials_t * credentials, params_t *params,
                         cmd_response_data_t* response_data)
{
  return delete_resource (connection, "target", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a trash task, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_task_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  return delete_resource (connection, "task", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Restore a resource, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
restore_omp (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, cmd_response_data_t* response_data)
{
  GString *xml;
  gchar *ret;
  entity_t entity;
  const char *target_id, *no_redirect;

  target_id = params_value (params, "target_id");
  no_redirect = params_value (params, "no_redirect");

  if (target_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while restoring a resource. "
                           "The resource was not restored. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  xml = g_string_new ("");

  /* Restore the resource. */

  if (openvas_connection_sendf (connection,
                                "<restore"
                                " id=\"%s\"/>",
                                target_id)
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while restoring a resource. "
                           "The resource was not deleted. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_trash", response_data);
    }

  if (read_entity_and_string_c (connection, &entity, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while restoring a resource. "
                           "It is unclear whether the resource has been restored or not. "
                           "Diagnostics: Failure to read response from manager daemon.",
                           "/omp?cmd=get_trash", response_data);
    }

  /* Cleanup, and return trash page. */

  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_trash",
                              NULL, "get_trash",
                              "Restore", response_data);
  free_entity (entity);
  g_string_free (xml, FALSE);
  return ret;
}

/**
 * @brief Empty the trashcan, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
empty_trashcan_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  GString *xml;
  const char* no_redirect;
  gchar *ret;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");

  xml = g_string_new ("");

  /* Empty the trash. */

  if (openvas_connection_sendf (connection,
                                "<empty_trashcan/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while emptying the trashcan. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_trash", response_data);
    }

  if (read_entity_and_string_c (connection, &entity, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while emptying the trashcan. "
                           "Diagnostics: Failure to read response from manager daemon.",
                           "/omp?cmd=get_trash", response_data);
    }

  /* Cleanup, and return trash page. */

  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_trash",
                              NULL, "get_trash",
                              "Empty Trashcan", response_data);
  free_entity (entity);
  g_string_free (xml, FALSE);
  return ret;
}

/**
 * @brief Returns page to create a new tag.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_tag (openvas_connection_t *connection, credentials_t *credentials,
         params_t *params, const char *extra_xml,
         cmd_response_data_t* response_data)
{
  GString *xml;
  gchar *end;
  const char *resource_type, *resource_id, *tag_id, *tag_name;

  resource_type = params_value (params, "resource_type");
  resource_id = params_value (params, "resource_id");

  tag_id = params_value (params, "tag_id");
  tag_name = params_value (params, "tag_name");

  xml = g_string_new ("<new_tag>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  end = g_markup_printf_escaped ("<tag id=\"%s\"/>"
                                 "<resource_type>%s</resource_type>"
                                 "<resource_id>%s</resource_id>"
                                 "<tag_name>%s%s</tag_name>"
                                 "<tag_value></tag_value>"
                                 "<comment></comment>"
                                 "<active>1</active>"
                                 "</new_tag>",
                                 tag_id ? tag_id : "0",
                                 resource_type ? resource_type : "",
                                 resource_id ? resource_id : "",
                                 tag_name ? tag_name : (resource_type
                                                          ? resource_type
                                                          : "default"),
                                 tag_name ? "" : ":unnamed");
  g_string_append (xml, end);
  g_free (end);

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to create a new target.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_tag_omp (openvas_connection_t *connection, credentials_t *credentials,
             params_t *params, cmd_response_data_t* response_data)
{
  return new_tag (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create a tag, get report, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_tag_omp (openvas_connection_t *connection, credentials_t *credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  char *ret;
  const char* no_redirect;
  gchar *response;
  const char *name, *comment, *value, *resource_type, *resource_id, *active;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "tag_name");
  comment = params_value (params, "comment");
  value = params_value (params, "tag_value");
  resource_type = params_value (params, "resource_type");
  resource_id = params_value (params, "resource_id");
  active = params_value (params, "active");

  CHECK_PARAM_INVALID (name, "Create Tag", "new_tag")
  CHECK_PARAM_INVALID (comment, "Create Tag", "new_tag")
  CHECK_PARAM_INVALID (value, "Create Tag", "new_tag")
  CHECK_PARAM_INVALID (resource_type, "Create Tag", "new_tag")
  CHECK_PARAM_INVALID (resource_id, "Create Tag", "new_tag")
  CHECK_PARAM_INVALID (active, "Create Tag", "new_tag")

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<create_tag>"
                "<name>%s</name>"
                "<comment>%s</comment>"
                "<value>%s</value>"
                "<resource id=\"%s\">"
                "<type>%s</type>"
                "</resource>"
                "<active>%s</active>"
                "</create_tag>",
                name,
                comment,
                value,
                resource_id,
                resource_type,
                active))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new tag. "
                             "No new tag was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_targets", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new tag. "
                             "It is unclear whether the tag has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tags", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new tag. "
                             "It is unclear whether the tag has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tags", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "tag_id", entity_attribute (entity, "id"));
  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_tags",
                              NULL, "new_tag",
                              "Create Tag", response_data);

  free_entity (entity);
  g_free (response);
  return ret;
}

/**
 * @brief Delete note, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_tag_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return delete_resource (connection, "tag", credentials, params, 0, NULL,
                          response_data);
}

/**
 * @brief Delete a note, get all notes, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_tag_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      cmd_response_data_t* response_data)
{
  return delete_resource (connection, "tag", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Setup edit_tag XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_tag (openvas_connection_t *connection, credentials_t * credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  GString *xml;
  gchar *edit;
  const char *tag_id;

  tag_id = params_value (params, "tag_id");
  if (tag_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing a tag. "
                           "The tag remains as it was. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_tags", response_data);
    }

  if (openvas_connection_sendf (connection,
                                "<get_tags"
                                " tag_id=\"%s\""
                                "/>",
                                tag_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting tag info. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tags", response_data);
    }

  xml = g_string_new ("");

  edit = g_markup_printf_escaped ("<edit_tag>"
                                  "<tag id=\"%s\"/>",
                                  tag_id);

  g_string_append (xml, edit);
  g_free (edit);

  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting target info. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tags", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</edit_tag>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup edit_tag XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_tag_omp (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return edit_tag (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Modify a tag, get all tags, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_tag_omp (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  gchar *response;
  const char *name, *comment, *value, *resource_type, *resource_id, *active;
  const char *tag_id, *no_redirect;
  entity_t entity;
  char* ret;

  no_redirect = params_value (params, "no_redirect");
  tag_id = params_value (params, "tag_id");
  name = params_value (params, "tag_name");
  comment = params_value (params, "comment");
  value = params_value (params, "tag_value");
  resource_type = params_value (params, "resource_type");
  resource_id = params_value (params, "resource_id");
  active = params_value (params, "active");

  CHECK_PARAM_INVALID (tag_id, "Save Tag", "edit_tag")
  CHECK_PARAM_INVALID (name, "Save Tag", "edit_tag")
  CHECK_PARAM_INVALID (comment, "Save Tag", "edit_tag")
  CHECK_PARAM_INVALID (value, "Save Tag", "edit_tag")
  CHECK_PARAM_INVALID (resource_type, "Save Tag", "edit_tag")
  CHECK_PARAM_INVALID (resource_id, "Save Tag", "edit_tag")
  CHECK_PARAM_INVALID (active, "Save Tag", "edit_tag")

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<modify_tag tag_id=\"%s\">"
                "<name>%s</name>"
                "<comment>%s</comment>"
                "<value>%s</value>"
                "<resource id=\"%s\">"
                "<type>%s</type>"
                "</resource>"
                "<active>%s</active>"
                "</modify_tag>",
                tag_id,
                name,
                comment,
                value,
                resource_id,
                resource_type,
                active))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a tag. "
                             "The tag remains the same. "
                             "Diagnostics: Failure to send command to "
                             "manager daemon.",
                             "/omp?cmd=get_targets", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a tag. "
                             "It is unclear whether the tag has been saved "
                             "or not. "
                             "Diagnostics: Failure to receive response from "
                             "manager daemon.",
                             "/omp?cmd=get_tags", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a tag. "
                             "It is unclear whether the tag has been saved "
                             "or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tags", response_data);
    }

  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_tags",
                              NULL, "edit_tag",
                              "Save Tag", response_data);

  free_entity (entity);
  g_free (response);
  return ret;

}

/**
 * @brief Export a tag.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Target XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_tag_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, enum content_type * content_type,
                char **content_disposition, gsize *content_length,
                cmd_response_data_t* response_data)
{
  return export_resource (connection, "tag", credentials, params, content_type,
                          content_disposition, content_length, response_data);
}

/**
 * @brief Export a list of tags.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Targets XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_tags_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, enum content_type * content_type,
                 char **content_disposition, gsize *content_length,
                 cmd_response_data_t* response_data)
{
  return export_many (connection, "tag", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Get one tag, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_tag (openvas_connection_t *connection, credentials_t * credentials,
         params_t *params, const char *extra_xml,
         cmd_response_data_t* response_data)
{
  return get_one (connection, "tag", credentials, params, extra_xml, NULL,
                  response_data);
}

/**
 * @brief Get one tag, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_tag_omp (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, cmd_response_data_t* response_data)
{
  return get_tag (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all tags, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_tags (openvas_connection_t *connection, credentials_t * credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  return get_many (connection, "tag", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all tags, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_tags_omp (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return get_tags (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Set tag enabled status.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
toggle_tag_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *no_redirect, *tag_id, *enable;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  tag_id = params_value (params, "tag_id");
  enable = params_value (params, "enable");

  if (tag_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while modifying a tag. "
                           "The tag was not modified. "
                           "Diagnostics: Required parameter tag_id was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }
  if (enable == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while modifying a tag. "
                           "The tag was not modified. "
                           "Diagnostics: Required parameter enable was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Delete the resource and get all resources. */

  if (openvas_connection_sendf (connection,
                                "<modify_tag tag_id=\"%s\">"
                                "<active>%s</active>"
                                "</modify_tag>",
                                tag_id,
                                enable)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while modifying a tag. "
                           "The tag is not modified. "
                           "Diagnostics: Failure to send command to"
                           " manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, &response))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while modifying a tag. "
                           "It is unclear whether the tag has been modified"
                           " or not. "
                           "Diagnostics: Failure to read response from"
                           " manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (! omp_success (entity))
    set_http_status_from_entity (entity, response_data);
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_tags",
                               NULL, "get_tags",
                               "Toggle Tag", response_data);

  free_entity (entity);
  g_free (response);

  return html;
}

/**
 * @brief Setup edit_target XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_target (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  GString *xml;
  gchar *edit;
  const char *target_id, *next, *filter, *first, *max;

  target_id = params_value (params, "target_id");
  filter = params_value (params, "filter");
  first = params_value (params, "first");
  max = params_value (params, "max");
  next = params_value (params, "next");

  if (target_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing a target. "
                           "The target remains as it was. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_targets", response_data);
    }

  if (next == NULL)
    next = "get_target";

  if (openvas_connection_sendf (connection,
                                "<get_targets"
                                " target_id=\"%s\""
                                " details=\"1\"/>",
                                target_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting target info. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_targets", response_data);
    }

  xml = g_string_new ("");

  if (extra_xml)
    g_string_append (xml, extra_xml);


  edit = g_markup_printf_escaped ("<edit_target>"
                                  "<target id=\"%s\"/>"
                                  /* Page that follows. */
                                  "<next>%s</next>"
                                  /* Passthroughs. */
                                  "<filters><term>%s</term></filters>"
                                  "<targets start=\"%s\" max=\"%s\"/>",
                                  target_id,
                                  next,
                                  filter,
                                  first,
                                  max);
  g_string_append (xml, edit);
  g_free (edit);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting target info. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_targets", response_data);
    }

  if (command_enabled (credentials, "GET_CREDENTIALS"))
    {
      /* Get the credentials. */

      if (openvas_connection_sendf (connection,
                                    "<get_credentials"
                                    " filter=\"rows=-1 sort=name\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting targets list. "
                               "The current list of targets is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_targets", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting targets list. "
                               "The current list of targets is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_targets", response_data);
        }
    }

  if (command_enabled (credentials, "GET_PORT_LISTS"))
    {
      /* Get the port lists. */

      if (openvas_connection_sendf (connection,
                                    "<get_port_lists"
                                    " filter=\"rows=-1 sort=name\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting targets list. "
                               "The current list of targets is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting targets list. "
                               "The current list of targets is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</edit_target>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup edit_target XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_target_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return edit_target (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get one target, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_target (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  return get_one (connection, "target", credentials, params, extra_xml,
                  "tasks=\"1\"", response_data);
}

/**
 * @brief Get one target, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_target_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return get_target (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all targets, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_targets (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  return get_many (connection, "target", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all targets, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_targets_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return get_targets (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Modify a target, get all targets, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_target_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *no_redirect, *name, *hosts, *exclude_hosts, *comment;
  const char *target_ssh_credential, *port, *target_smb_credential;
  const char *target_esxi_credential, *target_snmp_credential, *target_source;
  const char *target_id, *port_list_id, *reverse_lookup_only;
  const char *reverse_lookup_unify, *alive_tests, *in_use;
  GString *command;

  no_redirect = params_value (params, "no_redirect");
  alive_tests = params_value (params, "alive_tests");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  in_use = params_value (params, "in_use");
  target_id = params_value (params, "target_id");

  CHECK_PARAM_INVALID (name, "Save Target", "edit_target");
  CHECK_PARAM_INVALID (target_id, "Save Target", "edit_target");
  CHECK_PARAM_INVALID (comment, "Save Target", "edit_target");
  CHECK_PARAM_INVALID (alive_tests, "Save Target", "edit_target");
  CHECK_PARAM_INVALID (in_use, "Save Target", "edit_target");

  if (strcmp (in_use, "0"))
    {
      entity_t entity;
      int ret;

      /* Target is in use.  Modify fewer fields. */

      command = g_string_new ("");
      xml_string_append (command,
                         "<modify_target target_id=\"%s\">"
                         "<name>%s</name>"
                         "<comment>%s</comment>"
                         "<alive_tests>%s</alive_tests>"
                         "</modify_target>",
                         target_id,
                         name ? name : "",
                         comment ? comment : "",
                         alive_tests);

      response = NULL;
      entity = NULL;
      ret = omp (connection, credentials, &response, &entity, response_data,
                 command->str);
      g_string_free (command, TRUE);
      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while saving a target. "
                                 "The target remains the same. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_targets", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while saving a target. "
                                 "It is unclear whether the target has been saved or not. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_targets", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while saving a target. "
                                 "It is unclear whether the target has been saved or not. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_targets", response_data);
        }

      html = response_from_entity (connection, credentials, params, entity,
                                   (no_redirect && strcmp (no_redirect, "0")),
                                   NULL, "get_targets",
                                   NULL, "edit_target",
                                   "Save Target", response_data);

      free_entity (entity);
      g_free (response);
      return html;
    }

  hosts = params_value (params, "hosts");
  exclude_hosts = params_value (params, "exclude_hosts");
  reverse_lookup_only = params_value (params, "reverse_lookup_only");
  reverse_lookup_unify = params_value (params, "reverse_lookup_unify");
  target_source = params_value (params, "target_source");
  port_list_id = params_value (params, "port_list_id");
  target_ssh_credential = params_value (params, "ssh_credential_id");
  port = params_value (params, "port");
  target_smb_credential = params_value (params, "smb_credential_id");
  target_esxi_credential = params_value (params, "esxi_credential_id");
  target_snmp_credential = params_value (params, "snmp_credential_id");

  CHECK_PARAM_INVALID (target_source, "Save Target", "edit_target");
  CHECK_PARAM_INVALID (port_list_id, "Save Target", "edit_target");
  CHECK_PARAM_INVALID (target_ssh_credential, "Save Target", "edit_target");
  CHECK_PARAM_INVALID (target_smb_credential, "Save Target", "edit_target");
  CHECK_PARAM_INVALID (target_esxi_credential, "Save Target", "edit_target");
  CHECK_PARAM_INVALID (target_snmp_credential, "Save Target", "edit_target");

  if (strcmp (target_ssh_credential, "--")
      && strcmp (target_ssh_credential, "0"))
    CHECK_PARAM_INVALID (port, "Save Target", "edit_target");

  if (hosts == NULL && strcmp (target_source, "manual") == 0)
    {
      return new_target (connection, credentials, params,
                         GSAD_MESSAGE_INVALID_PARAM ("Modify Target"),
                         response_data);
    }
  if (strcmp (target_source, "import") == 0 && name == NULL)
    {
      gchar *msg;
      msg = g_strdup_printf (GSAD_MESSAGE_INVALID,
                            "Given target_source was invalid",
                            "Modify Target");
      html = new_target (connection, credentials, params, msg, response_data);
      g_free (msg);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return html;
    }

  {
    int ret;
    gchar *ssh_credentials_element, *smb_credentials_element;
    gchar *esxi_credentials_element, *snmp_credentials_element;
    gchar* comment_element;
    entity_t entity;

    if (comment)
      comment_element = g_strdup_printf ("<comment>%s</comment>", comment);
    else
      comment_element = g_strdup ("");

    if (strcmp (target_ssh_credential, "--") == 0)
      ssh_credentials_element = g_strdup ("");
    else
      ssh_credentials_element =
        g_strdup_printf ("<ssh_credential id=\"%s\">"
                         "<port>%s</port>"
                         "</ssh_credential>",
                         target_ssh_credential,
                         port);

    if (strcmp (target_smb_credential, "--") == 0)
      smb_credentials_element = g_strdup ("");
    else
      smb_credentials_element =
        g_strdup_printf ("<smb_credential id=\"%s\"/>",
                         target_smb_credential);

    if (strcmp (target_esxi_credential, "--") == 0)
      esxi_credentials_element = g_strdup ("");
    else
      esxi_credentials_element =
        g_strdup_printf ("<esxi_credential id=\"%s\"/>",
                         target_esxi_credential);

    if (strcmp (target_snmp_credential, "--") == 0)
      snmp_credentials_element = g_strdup ("");
    else
      snmp_credentials_element =
        g_strdup_printf ("<snmp_credential id=\"%s\"/>",
                         target_snmp_credential);

    command = g_string_new ("");
    xml_string_append (command,
                       "<modify_target target_id=\"%s\">"
                       "<name>%s</name>"
                       "<hosts>%s</hosts>"
                       "<exclude_hosts>%s</exclude_hosts>"
                       "<reverse_lookup_only>%s</reverse_lookup_only>"
                       "<reverse_lookup_unify>%s</reverse_lookup_unify>"
                       "<port_list id=\"%s\"/>"
                       "<alive_tests>%s</alive_tests>",
                       target_id,
                       name,
                       strcmp (target_source, "file") == 0
                         ? params_value (params, "file")
                         : hosts,
                       exclude_hosts ? exclude_hosts : "",
                       reverse_lookup_only ? reverse_lookup_only : "0",
                       reverse_lookup_unify ? reverse_lookup_unify : "0",
                       port_list_id,
                       alive_tests);

    g_string_append_printf (command,
                            "%s%s%s%s%s"
                            "</modify_target>",
                            comment_element,
                            ssh_credentials_element,
                            smb_credentials_element,
                            esxi_credentials_element,
                            snmp_credentials_element);

    g_free (comment_element);
    g_free (ssh_credentials_element);
    g_free (smb_credentials_element);
    g_free (esxi_credentials_element);
    g_free (snmp_credentials_element);

    /* Modify the target. */

    ret = openvas_connection_sendf (connection, "%s", command->str);
    g_string_free (command, TRUE);

    if (ret == -1)
      {
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while modifying target. "
                             "No target was modified. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_targets", response_data);
      }

    entity = NULL;
    if (read_entity_and_text_c (connection, &entity, &response))
      {
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while modifying a target. "
                             "It is unclear whether the target has been modified or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_targets", response_data);
      }

    html = response_from_entity (connection, credentials, params, entity,
                                 (no_redirect && strcmp (no_redirect, "0")),
                                 NULL, "get_targets",
                                 NULL, "edit_target",
                                 "Save Target", response_data);
  }

  /* Pass response to handler of following page. */

  return html;
}

/**
 * @brief Export a target.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Target XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_target_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   enum content_type * content_type, char **content_disposition,
                   gsize *content_length, cmd_response_data_t* response_data)
{
  return export_resource (connection, "target", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of targets.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Targets XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_targets_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    enum content_type * content_type, char **content_disposition,
                    gsize *content_length, cmd_response_data_t* response_data)
{
  return export_many (connection, "target", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Returns page to create a new scan config.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_config (openvas_connection_t *connection, credentials_t *credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  GString *xml;
  int ret;
  entity_t entity = NULL;
  gchar *response = NULL;

  xml = g_string_new ("<new_config>");
  if (extra_xml)
    g_string_append (xml, extra_xml);

  /* Get Scanners. */
  ret = omp (connection, credentials, &response, &entity, response_data,
             "<get_scanners/>");
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting scanners"
                             " for new config. Diagnostics: Failure to send"
                             " command to manager daemon.",
                             "/omp?cmd=get_configs", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting scanners"
                             " for new config. " "Diagnostics: Failure to"
                             " receive response from manager daemon.",
                             "/omp?cmd=get_configs", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting scanners"
                             "for new config. It is unclear whether the config"
                             " has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_configs", response_data);
    }
  g_string_append (xml, response);
  g_free (response);
  free_entity (entity);

  g_string_append (xml, "</new_config>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the new scan config page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_config_omp (openvas_connection_t *connection, credentials_t *credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return new_config (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Returns page to upload a new scan config.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
upload_config (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, const char *extra_xml,
               cmd_response_data_t* response_data)
{
  GString *xml;

  xml = g_string_new ("<upload_config>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</upload_config>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the upload scan config page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
upload_config_omp (openvas_connection_t *connection, credentials_t *credentials,
                   params_t *params, cmd_response_data_t* response_data)
{
  return upload_config (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create config, get all configs, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_config_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *no_redirect, *name, *comment, *base, *scanner = NULL;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  base = params_value (params, "base");

  CHECK_PARAM_INVALID (name, "New Config", "new_config");
  CHECK_PARAM_INVALID (comment, "New Config", "new_config");
  CHECK_PARAM_INVALID (base, "New Config", "new_config");
  if (!strcmp (base, "0"))
    {
      scanner = params_value (params, "scanner_id");
      CHECK_PARAM_INVALID (scanner, "New Config", "new_config");
    }

  /* Create the config. */
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<create_config>"
                "<name>%s</name>"
                "<copy>%s</copy>"
                "<comment>%s</comment>"
                "<scanner>%s</scanner>"
                "</create_config>",
                name, base, comment,
                scanner ?: ""))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new config. "
                            "No new config was created. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_configs", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new config. "
                            "It is unclear whether the config has been created or not. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_configs", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new config. "
                            "It is unclear whether the config has been created or not. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=get_configs", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "config_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_configs",
                               NULL, "new_config",
                               "Create Config", response_data);

  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Import config, get all configs, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
import_config_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  const char *no_redirect;
  gchar *command, *html, *response;
  entity_t entity;
  int ret;

  no_redirect = params_value (params, "no_redirect");

  /* Create the config. */

  response = NULL;
  entity = NULL;
  command = g_strdup_printf ("<create_config>"
                             "%s"
                             "</create_config>",
                             params_value (params, "xml_file"));
  ret = omp (connection, credentials, &response, &entity, response_data,
             command);
  g_free (command);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while importing a config. "
                             "The schedule remains the same. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_configs", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while importing a config. "
                             "It is unclear whether the schedule has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_configs", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while importing a config. "
                             "It is unclear whether the schedule has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_configs", response_data);
    }

  /* Cleanup, and return transformed XML. */

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_configs",
                               NULL, "new_config",
                               "Import Config", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Get all scan configs, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_configs (openvas_connection_t *connection, credentials_t *credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  return get_many (connection, "config", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all scan configs, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_configs_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return get_configs (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[in]  edit           0 for config view page, else config edit page.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_config (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *extra_xml, int edit,
            cmd_response_data_t* response_data)
{
  GString *xml;
  const char *config_id;

  config_id = params_value (params, "config_id");

  if (config_id == NULL)
    return get_configs (connection, credentials, params, extra_xml,
                        response_data);

  xml = g_string_new ("<get_config_response>");
  if (edit) g_string_append (xml, "<edit/>");

  if (extra_xml)
    g_string_append (xml, extra_xml);
  /* Get the config families. */

  if (openvas_connection_sendf (connection,
                                "<get_configs"
                                " config_id=\"%s\""
                                " families=\"1\""
                                " tasks=\"1\""
                                " preferences=\"1\"/>",
                                config_id)
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the config. "
                           "The config is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the config. "
                           "The config is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  /* Get all the families. */

  if (openvas_connection_sendf (connection, "<get_nvt_families/>") == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the config. "
                           "The config is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the config. "
                           "The config is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (edit)
    {
      /* Get OSP scanners */
      if (openvas_connection_sendf (connection, "<get_scanners filter=\"type=1\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message
                  (credentials, "Internal error", __FUNCTION__, __LINE__,
                   "An internal error occurred while getting the config. "
                   "The config is not available. "
                   "Diagnostics: Failure to send command to manager daemon.",
                   "/omp?cmd=get_configs", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message
                  (credentials, "Internal error", __FUNCTION__, __LINE__,
                   "An internal error occurred while getting the config. "
                   "The config is not available. "
                   "Diagnostics: Failure to receive response from manager daemon.",
                   "/omp?cmd=get_configs", response_data);
        }

    }

  /* Get Credentials */
  if (openvas_connection_sendf (connection, "<get_credentials/>") == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message
              (credentials, "Internal error", __FUNCTION__, __LINE__,
               "An internal error occurred while getting the config. "
               "The config is not available. "
               "Diagnostics: Failure to send command to manager daemon.",
               "/omp?cmd=get_configs", response_data);
    }
  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message
              (credentials, "Internal error", __FUNCTION__, __LINE__,
               "An internal error occurred while getting the config. "
               "The config is not available. "
               "Diagnostics: Failure to receive response from manager daemon.",
               "/omp?cmd=get_configs", response_data);
    }

  /* Get the permissions */

  g_string_append (xml, "<permissions>");

  if (openvas_connection_sendf (connection,
                                "<get_permissions"
                                " filter=\"name:^.*(config)s?$"
                                "          and resource_uuid=%s"
                                "          first=1 rows=-1\"/>",
                                config_id)
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting permissions list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting permissions list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  g_string_append (xml, "</permissions>");

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</get_config_response>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Get a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_config_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return get_config (connection, credentials, params, NULL, 0, response_data);
}

/**
 * @brief Get a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
edit_config (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  return get_config (connection, credentials, params, extra_xml, 1,
                     response_data);
}

/**
 * @brief Get a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_config_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return edit_config (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Sync config, get configs, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
sync_config_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  GString *xml;
  const char *config_id, *next;
  char *ret;

  config_id = params_value (params, "config_id");
  CHECK_PARAM (config_id, "Synchronize Config", get_configs);

  if (openvas_connection_sendf (connection, "<sync_config config_id=\"%s\"/>",
                                config_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message
              (credentials, "Internal error", __FUNCTION__, __LINE__,
               "An internal error occurred while synchronizing a config. "
               "The config is not synchronized. "
               "Diagnostics: Failure to send command to manager daemon.",
               "/omp?cmd=get_configs", response_data);
    }

  xml = g_string_new ("");

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message
              (credentials, "Internal error", __FUNCTION__, __LINE__,
               "An internal error occurred while synchronizing a config. "
               "It is unclear whether the config has been synchronized or not. "
               "Diagnostics: Failure to receive response from manager daemon.",
               "/omp?cmd=get_configs", response_data);
    }

  next = params_value (params, "next");
  if (next && !strcmp (next, "get_config"))
    ret = get_config (connection, credentials, params, xml->str, 0,
                      response_data);
  else
    ret = get_configs (connection, credentials, params, xml->str,
                       response_data);
  g_string_free (xml, TRUE);
  return ret;
}


/**
 * @brief Save OSP file preferences.
 *
 * @param[in]   credentials  Username and password for authentication.
 * @param[in]   connection   Connection.
 * @param[in]   params      Request parameters.
 * @param[in]   next        The next command on success.
 * @param[in]   fail_next   The next command on failure.
 * @param[out]  success     Whether the last command was successful.
 * @param[out]  response_data  Extra data return for the HTTP response.
 *
 * @return HTML result of XSL transformation.
 */
static char *
save_osp_prefs (credentials_t *credentials, openvas_connection_t *connection,
                params_t *params, const char *next, const char *fail_next,
                int *success, cmd_response_data_t* response_data)
{
  GHashTableIter iter;
  gpointer param_name, val;
  char *ret;
  const char *config_id;

  config_id = params_value (params, "config_id");
  g_hash_table_iter_init (&iter, params);
  ret = NULL;
  while (g_hash_table_iter_next (&iter, &param_name, &val))
    {
      gchar *value;
      param_t *param = val;

      g_free (ret);
      ret = NULL;

      if (!g_str_has_prefix (param_name, "osp_pref_"))
        continue;
      value = param->value_size ? g_base64_encode ((guchar *) param->value,
                                                   param->value_size)
                                : g_strdup ("");

      /* Send the name without the osp_pref_ prefix. */
      param_name = ((char *) param_name) + 9;
      if (openvas_connection_sendf (connection,
                                    "<modify_config config_id=\"%s\">"
                                    "<preference><name>%s</name>"
                                    "<value>%s</value></preference>"
                                    "</modify_config>",
                                    config_id,
                                    (char *) param_name,
                                    value)
          == -1)
        {
          g_free (value);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message
                  (credentials, "Internal error", __FUNCTION__, __LINE__,
                   "An internal error occurred while saving a config. It is"
                   " unclear whether the entire config has been saved. "
                   "Diagnostics: Failure to send command to manager daemon.",
                   "/omp?cmd=get_configs", response_data);
        }
      g_free (value);

      ret = check_modify_config (credentials, connection, params, next,
                                 fail_next, success, response_data);
      if (*success == 0)
        return ret;
    }
  return ret;
}

/**
 * @brief Save details of an NVT for a config and return the next page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Following page.
 */
char *
save_config_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  int omp_ret;
  char *ret, *osp_ret;
  params_t *preferences, *selects, *trends;
  const char *config_id, *name, *comment, *scanner_id;
  int success;

  config_id = params_value (params, "config_id");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  scanner_id = params_value (params, "scanner_id");

  CHECK_PARAM_INVALID (config_id, "Save Config", "edit_config");
  CHECK_PARAM_INVALID (name, "Save Config", "edit_config");
  CHECK_PARAM_INVALID (comment, "Save Config", "edit_config");

  /* Save name and comment. */

  if (scanner_id)
    omp_ret = openvas_connection_sendf_xml (connection,
                                            "<modify_config config_id=\"%s\">"
                                            "<name>%s</name>"
                                            "<comment>%s</comment>"
                                            "<scanner>%s</scanner>"
                                            "</modify_config>",
                                            params_value (params, "config_id"),
                                            name,
                                            comment,
                                            scanner_id);
  else
    omp_ret = openvas_connection_sendf_xml (connection,
                                            "<modify_config config_id=\"%s\">"
                                            "<name>%s</name>"
                                            "<comment>%s</comment>"
                                            "</modify_config>",
                                            params_value (params, "config_id"),
                                            name,
                                            comment);

  if (omp_ret == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while saving a config. "
                           "It is unclear whether the entire config has been saved. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  ret = check_modify_config (credentials, connection, params,
                             "get_config", "edit_config",
                             &success, response_data);
  if (success == 0)
    {
      return ret;
    }

  /* Save preferences. */

  preferences = params_values (params, "preference:");
  if (preferences)
    {
      params_iterator_t iter;
      char *param_name;
      param_t *param;

      params_iterator_init (&iter, preferences);
      while (params_iterator_next (&iter, &param_name, &param))
        {
          gchar *value;

          value = param->value_size
                  ? g_base64_encode ((guchar *) param->value,
                                     param->value_size)
                  : g_strdup ("");

          if (openvas_connection_sendf (connection,
                                        "<modify_config config_id=\"%s\">"
                                        "<preference>"
                                        "<name>%s</name>"
                                        "<value>%s</value>"
                                        "</preference>"
                                        "</modify_config>",
                                        params_value (params, "config_id"),
                                        param_name,
                                        value)
              == -1)
            {
              g_free (value);
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while saving a config. "
                                   "It is unclear whether the entire config has been saved. "
                                   "Diagnostics: Failure to send command to manager daemon.",
                                   "/omp?cmd=get_configs", response_data);
            }
          g_free (value);
          g_free (ret);

          ret = check_modify_config (credentials, connection, params,
                                     "get_config", "edit_config",
                                     &success, response_data);
          if (success == 0)
            {
              return ret;
            }
        }
    }

  /* OSP config file preference. */
  osp_ret = save_osp_prefs (credentials, connection, params,
                            "get_config", "edit_config",
                            &success, response_data);

  if (osp_ret)
    {
      g_free (ret);
      ret = osp_ret;
    }

  if (success == 0)
    {
      if (osp_ret == NULL)
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving a config. "
                               "It is unclear whether the entire config has been saved. "
                               "Diagnostics: save_osp_prefs returned NULL unexpectedly.",
                               "/omp?cmd=get_configs", response_data);
        }
      return ret;
    }

  /* Update the config. */

  trends = params_values (params, "trend:");
  selects = params_values (params, "select:");

  if (trends || selects || params_value (params, "trend"))
    {
      if (openvas_connection_sendf (connection,
                                    "<modify_config config_id=\"%s\">"
                                    "<family_selection>"
                                    "<growing>%i</growing>",
                                    params_value (params, "config_id"),
                                    trends
                                    && params_value (params, "trend")
                                    && strcmp (params_value (params, "trend"), "0"))
          == -1)
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving a config. "
                               "It is unclear whether the entire config has been saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_configs", response_data);
        }

      if (selects)
        {
          gchar *family;
          params_iterator_t iter;
          param_t *param;

          params_iterator_init (&iter, selects);
          while (params_iterator_next (&iter, &family, &param))
            if (openvas_connection_sendf (connection,
                                          "<family>"
                                          "<name>%s</name>"
                                          "<all>1</all>"
                                          "<growing>%i</growing>"
                                          "</family>",
                                          family,
                                          trends && member1 (trends, family))
                == -1)
              {
                response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
                return gsad_message (credentials,
                                     "Internal error", __FUNCTION__, __LINE__,
                                     "An internal error occurred while saving a config. "
                                     "It is unclear whether the entire config has been saved. "
                                     "Diagnostics: Failure to send command to manager daemon.",
                                     "/omp?cmd=get_configs", response_data);
              }
        }

      if (trends)
        {
          gchar *family;
          params_iterator_t iter;
          param_t *param;

          params_iterator_init (&iter, trends);
          while (params_iterator_next (&iter, &family, &param))
            {
              if (param->value_size == 0) continue;
              if (param->value[0] == '0') continue;
              if (selects && member (selects, family)) continue;
              if (openvas_connection_sendf (connection,
                                            "<family>"
                                            "<name>%s</name>"
                                            "<all>0</all>"
                                            "<growing>1</growing>"
                                            "</family>",
                                            family)
                  == -1)
                {
                  response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
                  return gsad_message (credentials,
                                       "Internal error", __FUNCTION__, __LINE__,
                                       "An internal error occurred while saving a config. "
                                       "It is unclear whether the entire config has been saved. "
                                       "Diagnostics: Failure to send command to manager daemon.",
                                       "/omp?cmd=get_configs", response_data);
                }
            }
        }

      if (openvas_connection_sendf (connection,
                                    "</family_selection>"
                                    "</modify_config>")
          == -1)
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving a config. "
                               "It is unclear whether the entire config has been saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_configs", response_data);
        }

      g_free (ret);
      ret = check_modify_config (credentials, connection, params,
                                "get_config", "edit_config",
                                NULL, response_data);
    }
  return ret;
}

/**
 * @brief Get details of a family for a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  edit           0 for config view page, else config edit page.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_config_family (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params, int edit,
                   cmd_response_data_t* response_data)
{
  GString *xml;
  const char *config_id, *name, *family, *sort_field, *sort_order;

  config_id = params_value (params, "config_id");
  name = params_value (params, "name");
  family = params_value (params, "family");

  if ((config_id == NULL) || (name == NULL) || (family == NULL))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting config family. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_configs", response_data);
    }

  xml = g_string_new ("<get_config_family_response>");
  if (edit) g_string_append (xml, "<edit/>");
  /* @todo Would it be better include this in the get_nvts response? */
  g_string_append_printf (xml,
                          "<config id=\"%s\">"
                          "<name>%s</name><family>%s</family>"
                          "</config>",
                          config_id,
                          name,
                          family);

  /* Get the details for all NVT's in the config in the family. */

  sort_field = params_value (params, "sort_field");
  sort_order = params_value (params, "sort_order");

  if (openvas_connection_sendf (connection,
                                "<get_nvts"
                                " config_id=\"%s\" details=\"1\""
                                " family=\"%s\" timeout=\"1\" preference_count=\"1\""
                                " sort_field=\"%s\" sort_order=\"%s\"/>",
                                config_id,
                                family,
                                sort_field ? sort_field : "nvts.name",
                                sort_order ? sort_order : "ascending")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting list of configs. "
                           "The current list of configs is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting list of configs. "
                           "The current list of configs is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (edit)
    {
      /* Get the details for all NVT's in the family. */

      g_string_append (xml, "<all>");

      if (openvas_connection_sendf (connection,
                                    "<get_nvts"
                                    " details=\"1\""
                                    " timeout=\"1\""
                                    " family=\"%s\""
                                    " preferences_config_id=\"%s\""
                                    " preference_count=\"1\""
                                    " sort_field=\"%s\""
                                    " sort_order=\"%s\"/>",
                                    family,
                                    config_id,
                                    sort_field ? sort_field : "nvts.name",
                                    sort_order ? sort_order : "ascending")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting list of configs. "
                               "The current list of configs is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_configs", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting list of configs. "
                               "The current list of configs is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_configs", response_data);
        }

      g_string_append (xml, "</all>");
    }

  g_string_append (xml, "</get_config_family_response>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Get details of a family for a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_config_family_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  return get_config_family (connection, credentials, params, 0, response_data);
}

/**
 * @brief Get details of a family for editing a config, XSL transform result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_config_family_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  return get_config_family (connection, credentials, params, 1, response_data);
}

/**
 * @brief Get details of an NVT for a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_config_family_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  char *ret;
  const char *config_id, *family;
  params_t *nvts;

  config_id = params_value (params, "config_id");
  family = params_value (params, "family");

  if ((config_id == NULL) || (family == NULL))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while saving getting config family. "
                           "The config has not been saved. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_configs", response_data);
    }

  /* Set the NVT selection. */

  if (openvas_connection_sendf (connection,
                                "<modify_config config_id=\"%s\">"
                                "<nvt_selection>"
                                "<family>%s</family>",
                                config_id,
                                family)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while saving a config. "
                           "It is unclear whether the entire config has been saved. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  nvts = params_values (params, "nvt:");
  if (nvts)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, nvts);
      while (params_iterator_next (&iter, &name, &param))
        if (openvas_connection_sendf (connection,
                                      "<nvt oid=\"%s\"/>",
                                      name)
            == -1)
          {
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while saving a config. "
                                 "It is unclear whether the entire config has been saved. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_configs", response_data);
          }
    }

  if (openvas_connection_sendf (connection,
                                "</nvt_selection>"
                                "</modify_config>")
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while saving a config. "
                           "It is unclear whether the entire config has been saved. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  ret = check_modify_config (credentials, connection, params,
                             "get_config_family", "edit_config_family",
                             NULL, response_data);

  return ret;
}

/**
 * @brief Get details of an NVT for a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  edit           0 for config view page, else config edit page.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_config_nvt (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, int edit, cmd_response_data_t* response_data)
{
  GString *xml;
  const char *config_id, *name, *family, *sort_field, *sort_order, *nvt;

  config_id = params_value (params, "config_id");
  name = params_value (params, "name");
  family = params_value (params, "family");
  nvt = params_value (params, "oid");

  if ((config_id == NULL) || (name == NULL))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting config family. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_configs", response_data);
    }

  xml = g_string_new ("<get_config_nvt_response>");
  if (edit) g_string_append (xml, "<edit/>");
  /* @todo Would it be better include this in the get_nvts response? */
  g_string_append_printf (xml,
                          "<config id=\"%s\">"
                          "<name>%s</name><family>%s</family>"
                          "</config>",
                          config_id,
                          name,
                          family ? family : "");

  sort_field = params_value (params, "sort_field");
  sort_order = params_value (params, "sort_order");

  if (openvas_connection_sendf (connection,
                                "<get_nvts"
                                " config_id=\"%s\" nvt_oid=\"%s\""
                                " details=\"1\" preferences=\"1\""
                                " sort_field=\"%s\" sort_order=\"%s\"/>",
                                config_id,
                                nvt,
                                sort_field ? sort_field : "nvts.name",
                                sort_order ? sort_order : "ascending")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting list of configs. "
                           "The current list of configs is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting list of configs. "
                           "The current list of configs is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  g_string_append (xml, "</get_config_nvt_response>");

  if (openvas_connection_sendf (connection,
                                "<get_notes"
                                " nvt_oid=\"%s\""
                                " sort_field=\"notes.text\"/>",
                                nvt)
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting list of notes. "
                           "The current list of notes is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting list of notes. "
                           "The current list of notes is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (openvas_connection_sendf (connection,
                                "<get_overrides"
                                " nvt_oid=\"%s\""
                                " sort_field=\"overrides.text\"/>",
                                nvt)
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting list of overrides. "
                           "The current list of overrides is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting list of overrides. "
                           "The current list of overrides is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_configs", response_data);
    }

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Get details of an NVT for a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_config_nvt_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  return get_config_nvt (connection, credentials, params, 0, response_data);
}

/**
 * @brief Edit details of an NVT for a config, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_config_nvt_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  return get_config_nvt (connection, credentials, params, 1, response_data);
}

/**
 * @brief Save NVT prefs for a config, get NVT details, XSL transform result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_config_nvt_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  params_t *preferences;
  const char *config_id;
  int success;
  char *modify_config_ret;

  modify_config_ret = NULL;
  config_id = params_value (params, "config_id");

  preferences = params_values (params, "preference:");
  if (preferences)
    {
      param_t *preference;
      gchar *preference_name;
      params_iterator_t iter;

      /* Save preferences. */

      params_iterator_init (&iter, preferences);
      while (params_iterator_next (&iter, &preference_name, &preference))
        {
          int type_start, type_end, count, ret, is_timeout = 0;
          gchar *value;

          g_free (modify_config_ret);
          modify_config_ret = NULL;

          /* Passwords and files have checkboxes to control whether they
           * must be reset.  This works around the need for the Manager to
           * send the actual password or show the actual file. */

          /* LDAPsearch[entry]:Timeout value */
          count = sscanf (preference_name,
                          "%*[^[][%n%*[^]]%n]:",
                          &type_start,
                          &type_end);
          if (count == 0 && type_start > 0 && type_end > 0)
            {
              if (strncmp (preference_name + type_start,
                           "password",
                           type_end - type_start)
                  == 0)
                {
                  int found = 0;
                  params_t *passwords;

                  passwords = params_values (params, "password:");
                  if (passwords)
                    {
                      param_t *password;
                      gchar *password_name;
                      params_iterator_t password_params;

                      params_iterator_init (&password_params, passwords);
                      while (params_iterator_next (&password_params,
                                                   &password_name,
                                                   &password))
                        if (strcmp (password_name, preference_name) == 0)
                          {
                            found = 1;
                            break;
                          }
                    }
                  if (found == 0)
                    /* Skip modifying the password preference. */
                    continue;
                }
              else if (strncmp (preference_name + type_start,
                                "file",
                                type_end - type_start)
                       == 0)
                {
                  int found = 0;
                  params_t *files;

                  files = params_values (params, "file:");
                  if (files)
                    {
                      param_t *file;
                      gchar *file_name;
                      params_iterator_t file_params;

                      params_iterator_init (&file_params, files);
                      while (params_iterator_next (&file_params,
                                                   &file_name,
                                                   &file))
                        if (strcmp (file_name, preference_name) == 0)
                          {
                            found = 1;
                            break;
                          }
                    }
                  if (found == 0)
                    /* Skip modifying the file preference. */
                    continue;
                }
              else if (strncmp (preference_name + type_start,
                                "scanner",
                                type_end - type_start)
                       == 0)
                {
                  /* Presume it's the timeout. */
                  is_timeout = 1;
                }
            }

          value = preference->value_size
                  ? g_base64_encode ((guchar *) preference->value,
                                     preference->value_size)
                  : g_strdup ("");

          if (is_timeout)
            {
              const char *timeout;
              gchar *preference_name_escaped;

              timeout = params_value (params, "timeout");

              if (timeout == NULL)
                {
                  g_free (value);
                  response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
                  return gsad_message (credentials,
                                       "Internal error", __FUNCTION__, __LINE__,
                                       "An internal error occurred while saving a config. "
                                       "It is unclear whether the entire config has been saved. "
                                       "Diagnostics: Required parameter was NULL.",
                                       "/omp?cmd=get_configs", response_data);
                }

              preference_name_escaped = g_markup_escape_text (preference_name,
                                                              -1);

              if (strcmp (timeout, "0") == 0)
                /* Leave out the value to clear the preference. */
                ret = openvas_connection_sendf (connection,
                                                "<modify_config"
                                                " config_id=\"%s\">"
                                                "<preference>"
                                                "<name>%s</name>"
                                                "</preference>"
                                                "</modify_config>",
                                                config_id,
                                                preference_name_escaped);
              else
                ret = openvas_connection_sendf (connection,
                                                "<modify_config"
                                                " config_id=\"%s\">"
                                                "<preference>"
                                                "<name>%s</name>"
                                                "<value>%s</value>"
                                                "</preference>"
                                                "</modify_config>",
                                                config_id,
                                                preference_name_escaped,
                                                value);

              g_free (preference_name_escaped);
            }
          else
            {
              gchar *preference_name_escaped;
              preference_name_escaped = g_markup_escape_text (preference_name,
                                                              -1);
              ret = openvas_connection_sendf (connection,
                                              "<modify_config"
                                              " config_id=\"%s\">"
                                              "<preference>"
                                              "<nvt oid=\"%s\"/>"
                                              "<name>%s</name>"
                                              "<value>%s</value>"
                                              "</preference>"
                                              "</modify_config>",
                                              config_id,
                                              params_value (params, "oid"),
                                              preference_name_escaped,
                                              value);
              g_free (preference_name_escaped);
            }

          if (ret == -1)
            {
              g_free (value);
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while saving a config. "
                                   "It is unclear whether the entire config has been saved. "
                                   "Diagnostics: Failure to send command to manager daemon.",
                                   "/omp?cmd=get_configs", response_data);
            }
          g_free (value);

          modify_config_ret = check_modify_config (credentials, connection,
                                                   params,
                                                   "get_config_nvt",
                                                   "edit_config_nvt",
                                                   &success, response_data);
          if (success == 0)
            {
              return modify_config_ret;
            }
        }
    }

  return modify_config_ret;
}

/**
 * @brief Delete config, get all configs, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_config_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  return delete_resource (connection, "config", credentials, params, 0,
                          "get_configs", response_data);
}

/**
 * @brief Export a config.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content dispositions return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Config XML on success.  HTML result of XSL transformation on error.
 */
char *
export_config_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   enum content_type * content_type, char **content_disposition,
                   gsize *content_length, cmd_response_data_t* response_data)
{
  return export_resource (connection, "config", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of scan configs.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Scan configs XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_configs_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    enum content_type * content_type, char **content_disposition,
                    gsize *content_length, cmd_response_data_t* response_data)
{
  return export_many (connection, "config", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Export a note.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Note XML on success.  HTML result of XSL transformation on error.
 */
char *
export_note_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, enum content_type * content_type,
                 char **content_disposition, gsize *content_length,
                 cmd_response_data_t* response_data)
{
  return export_resource (connection, "note", credentials, params, content_type,
                          content_disposition, content_length, response_data);
}

/**
 * @brief Export a list of notes.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Notes XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_notes_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, enum content_type * content_type,
                  char **content_disposition, gsize *content_length,
                  cmd_response_data_t* response_data)
{
  return export_many (connection, "note", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Export an override.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Override XML on success.  HTML result of XSL transformation on error.
 */
char *
export_override_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     enum content_type * content_type,
                     char **content_disposition, gsize *content_length,
                     cmd_response_data_t* response_data)
{
  return export_resource (connection, "override", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of overrides.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Overrides XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_overrides_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      enum content_type * content_type,
                      char **content_disposition, gsize *content_length,
                      cmd_response_data_t* response_data)
{
  return export_many (connection, "override", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Export a Port List.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Port List XML on success.  HTML result of XSL transformation on
 *         error.
 */
char *
export_port_list_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      enum content_type * content_type,
                      char **content_disposition, gsize *content_length,
                      cmd_response_data_t* response_data)
{
  return export_resource (connection, "port_list", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of Port Lists.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Port Lists XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_port_lists_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       enum content_type * content_type,
                       char **content_disposition, gsize *content_length,
                       cmd_response_data_t* response_data)
{
  return export_many (connection, "port_list", credentials, params,
                      content_type, content_disposition, content_length,
                      response_data);
}

/**
 * @brief Export a file preference.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content dispositions return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Config XML on success.  HTML result of XSL transformation on error.
 */
char *
export_preference_file_omp (openvas_connection_t *connection,
                            credentials_t * credentials, params_t *params,
                            enum content_type * content_type,
                            char **content_disposition, gsize *content_length,
                            cmd_response_data_t* response_data)
{
  GString *xml;
  entity_t entity, preference_entity, value_entity;
  const char *config_id, *oid, *preference_name;

  *content_length = 0;

  config_id = params_value (params, "config_id");
  oid = params_value (params, "oid");
  preference_name = params_value (params, "preference_name");

  xml = g_string_new ("<get_preferences_response>");

  if (config_id == NULL || oid == NULL || preference_name == NULL)
    g_string_append (xml, GSAD_MESSAGE_INVALID_PARAM ("Export Preference File"));
  else
    {
      if (openvas_connection_sendf (connection,
                                    "<get_preferences"
                                    " config_id=\"%s\""
                                    " nvt_oid=\"%s\""
                                    " preference=\"%s\"/>",
                                    config_id,
                                    oid,
                                    preference_name)
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a preference file. "
                               "The file could not be delivered. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      entity = NULL;
      if (read_entity_c (connection, &entity))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a preference file. "
                               "The file could not be delivered. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      preference_entity = entity_child (entity, "preference");
      if (preference_entity != NULL
          && (value_entity = entity_child (preference_entity, "value")))
        {
          char *content = strdup (entity_text (value_entity));
          *content_type = GSAD_CONTENT_TYPE_OCTET_STREAM;
          *content_disposition = g_strdup_printf ("attachment; filename=\"pref_file.bin\"");
          *content_length = strlen (content);
          free_entity (entity);
          g_string_free (xml, TRUE);
          return content;
        }
      else
        {
          free_entity (entity);
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a preference file. "
                               "The file could not be delivered. "
                               "Diagnostics: Failure to receive file from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  g_string_append (xml, "</get_preferences_response>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Export a report format.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Report format XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_report_format_omp (openvas_connection_t *connection,
                          credentials_t * credentials, params_t *params,
                          enum content_type * content_type,
                          char **content_disposition, gsize *content_length,
                          cmd_response_data_t* response_data)
{
  return export_resource (connection, "report_format", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of Report Formats.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Report Formats XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_report_formats_omp (openvas_connection_t *connection,
                           credentials_t * credentials, params_t *params,
                           enum content_type * content_type,
                           char **content_disposition, gsize *content_length,
                           cmd_response_data_t* response_data)
{
  return export_many (connection, "report_format", credentials, params,
                      content_type, content_disposition, content_length,
                      response_data);
}

/**
 * @brief Delete report, get task status, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_report_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  return delete_resource (connection, "report", credentials, params, 0, NULL,
                          response_data);
}

/**
 * @brief Get a report and return the result.
 *
 * @param[in]  connection           Connection to manager
 * @param[in]  credentials          Username and password for authentication.
 * @param[in]  params               Request parameters.
 * @param[in]  commands             Extra commands to run before the others.
 * @param[out] report_len           Length of report.
 * @param[out] content_type         Content type if known, else NULL.
 * @param[out] content_disposition  Content disposition, if content_type set.
 * @param[in]  extra_xml            Extra XML to insert inside page element.
 * @param[out] error                Set to 1 if error, else 0.
 * @param[out] response_data        Extra data return for the HTTP response.
 *
 * @return Report.
 */
char *
get_report (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *commands,
            gsize *report_len, gchar **content_type, char **content_disposition,
            const char *extra_xml, int *error,
            cmd_response_data_t* response_data)
{
  GString *xml, *commands_xml;
  entity_t entity;
  entity_t report_entity;
  unsigned int first, max;
  GString *levels, *delta_states;
  const char *alert_id, *search_phrase, *min_qod, *type, *zone;
  const char *autofp, *autofp_value, *notes, *overrides, *result_hosts_only;
  const char *apply_overrides;
  const char *report_id, *sort_field, *sort_order, *result_id, *delta_report_id;
  const char *format_id, *first_result, *max_results, *host, *pos;
  const char *given_filt_id, *filt_id, *filter, *apply_filter, *report_section;
  const char *build_filter, *filter_extra;
  const char *host_search_phrase, *host_levels;
  const char *host_first_result, *host_max_results;
  int ret;
  int ignore_filter, ignore_pagination;
  gchar *built_filter;
  gchar *fname_format, *esc_response;

  build_filter = params_value (params, "build_filter");

  if (params_given (params, "apply_filter")
      && params_valid (params, "apply_filter"))
    apply_filter = params_value (params, "apply_filter");
  else
    apply_filter = "no_pagination";

  if (params_given (params, "report_section")
      && params_valid (params, "report_section"))
    report_section = params_value (params, "report_section");
  else
    report_section = "";

  ignore_filter = (strcmp (apply_filter, "full")
                   && strcmp (apply_filter, "no_pagination")
                   && strcmp (report_section, "")
                   && strcmp (report_section, "results")
                   && strcmp (report_section, "summary"));

  if (params_given (params, "ignore_pagination"))
    {
      const char *ignore_pagination_str = params_value (params,
                                                        "ignore_pagination");
      ignore_pagination = (ignore_pagination_str
                           && strcmp (ignore_pagination_str, "")
                           && strcmp (ignore_pagination_str, "0"));
    }
  else
    {
      ignore_pagination = (strcmp (apply_filter, "full")
                          && strcmp (report_section, "")
                          && strcmp (report_section, "results")
                          && strcmp (report_section, "summary"));
    }

  alert_id = params_value (params, "alert_id");
  if (alert_id == NULL)
    params_given (params, "alert_id") || (alert_id = "0");

  search_phrase = params_value (params, "search_phrase");
  if (search_phrase == NULL)
    params_given (params, "search_phrase") || (search_phrase = "");

  zone = params_value (params, "timezone");
  if (zone == NULL)
    params_given (params, "zone") || (zone = "");

  min_qod = params_value (params, "min_qod");

  type = params_value (params, "type");
  host = params_value (params, "host");
  pos = params_value (params, "pos");

  autofp = params_value (params, "autofp");
  if (autofp == NULL)
    params_given (params, "autofp") || (autofp = "0");

  autofp_value = params_value (params, "autofp_value");
  if (autofp_value == NULL)
    params_given (params, "autofp_value") || (autofp_value = "1");

  notes = params_value (params, "notes");
  if (notes == NULL)
    {
      if (params_given (params, "max_results"))
        /* Use the max_results param to determine if the request is from
         * the Result Filtering form, because the notes param is only sent
         * when the checkbox is ticked. */
        notes = "0";
      else
        params_given (params, "notes") || (notes = "1");
    }

  overrides = params_value (params, "overrides");
  if (overrides == NULL)
    {
      if (params_given (params, "max_results"))
        /* Use the max_results param to check for filtering form as above */
        overrides = "0";
      else
        params_given (params, "overrides") || (overrides = "1");
    }

  apply_overrides = params_value (params, "apply_overrides");
  if (apply_overrides == NULL)
    {
      if (params_given (params, "max_results"))
        /* Use the max_results param to check for filtering form as above */
        apply_overrides = "0";
      else
        params_given (params, "apply_overrides") || (apply_overrides = "1");
    }

  result_hosts_only = params_value (params, "result_hosts_only");
  if (result_hosts_only == NULL)
    {
      if (params_given (params, "max_results"))
        /* Use the max_results params to determine if the request is from
         * the Result Filtering form, because the result_hosts_only param is
         * only sent when the checkbox is ticked. */
        result_hosts_only = "0";
      else
        params_given (params, "result_hosts_only") || (result_hosts_only = "1");
    }

  if (content_type) *content_type = NULL;
  if (report_len) *report_len = 0;

  if (autofp == NULL || strlen (autofp) == 0) autofp = "0";

  if (autofp_value == NULL || strlen (autofp_value) == 0) autofp_value = "1";

  if (strcmp (autofp, "2") == 0)
    autofp_value = "2";

  if (notes == NULL || strlen (notes) == 0) notes = "1";

  if (overrides == NULL || strlen (overrides) == 0) overrides = "1";

  if (result_hosts_only == NULL || strlen (result_hosts_only) == 0)
    result_hosts_only = "1";

  /* Run any extra commands. */

  commands_xml = g_string_new ("");
  if (commands)
    {
      if (openvas_connection_sendf (connection, "%s", commands)
          == -1)
        {
          g_string_free (commands_xml, TRUE);
          if (error) *error = 1;
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a report. "
                               "The report could not be delivered. "
                               "Diagnostics: Failure to send extra commands to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &commands_xml))
        {
          g_string_free (commands_xml, TRUE);
          if (error) *error = 1;
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a report. "
                               "The report could not be delivered. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  /* Get the report. */

  if (params_value (params, "delta_states"))
    delta_states = g_string_new (params_value (params, "delta_states"));
  else
    {
      delta_states = g_string_new ("");
      if (params_value (params, "delta_state_changed")
          && atoi (params_value (params, "delta_state_changed")))
        g_string_append (delta_states, "c");
      if (params_value (params, "delta_state_gone")
          && atoi (params_value (params, "delta_state_gone")))
        g_string_append (delta_states, "g");
      if (params_value (params, "delta_state_new")
          && atoi (params_value (params, "delta_state_new")))
        g_string_append (delta_states, "n");
      if (params_value (params, "delta_state_same")
          && atoi (params_value (params, "delta_state_same")))
        g_string_append (delta_states, "s");
    }

  if (strlen (delta_states->str) == 0) g_string_append (delta_states, "gn");

  if (params_value (params, "levels"))
    levels = g_string_new (params_value (params, "levels"));
  else
    {
      levels = g_string_new ("");
      if (params_value (params, "level_high")
          && atoi (params_value (params, "level_high")))
        g_string_append (levels, "h");
      if (params_value (params, "level_medium")
          && atoi (params_value (params, "level_medium")))
        g_string_append (levels, "m");
      if (params_value (params, "level_low")
          && atoi (params_value (params, "level_low")))
        g_string_append (levels, "l");
      if (params_value (params, "level_log")
          && atoi (params_value (params, "level_log")))
        g_string_append (levels, "g");
      if (params_value (params, "level_false_positive")
          && atoi (params_value (params, "level_false_positive")))
        g_string_append (levels, "f");
    }

  if (type && (strcmp (type, "assets") == 0))
    {
      if (strlen (levels->str) == 0)
        g_string_append (levels, "");
    }
  else if (strlen (levels->str) == 0)
    g_string_append (levels, "hml");

  sort_field = params_value (params, "sort_field");
  sort_order = params_value (params, "sort_order");
  report_id = params_value (params, "report_id");

  if (report_id == NULL
      && (type == NULL
          || (strcmp (type, "prognostic")
              && strcmp (type, "assets"))))
    return get_reports (connection, credentials, params, extra_xml,
                        response_data);

  if (strcmp (alert_id, "0"))
    {
      const char *status, *esc_filter;

      esc_filter = params_value (params, "esc_filter");
      if (esc_filter == NULL)
        params_given (params, "esc_filter")
          || (esc_filter = "first=1 rows=-1"
                           "  result_hosts_only=0"
                           "  apply_overrides=1"
                           "  notes=1 overrides=1"
                           "  sort-reverse=severity");

      if (ignore_filter)
        ret = openvas_connection_sendf_xml (connection,
                                            "<get_reports"
                                            " report_id=\"%s\""
                                            " filter=\"first=1 rows=-1"
                                            "  result_hosts_only=0"
                                            "  apply_overrides=1"
                                            "  notes=1 overrides=1"
                                            "  sort-reverse=severity\""
                                            " alert_id=\"%s\"/>",
                                            report_id,
                                            alert_id);
      else
        ret = openvas_connection_sendf_xml (connection,
                                            "<get_reports"
                                            " report_id=\"%s\""
                                            " ignore_pagination=\"%d\""
                                            " filter=\"%s\""
                                            " alert_id=\"%s\"/>",
                                            report_id,
                                            ignore_pagination,
                                            esc_filter ? esc_filter : "",
                                            alert_id);
      if (ret == -1)
        {
          g_string_free (commands_xml, TRUE);
          g_string_free (delta_states, TRUE);
          g_string_free (levels, TRUE);
          if (error) *error = 1;
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a report. "
                               "The report could not be delivered. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_entity_and_text_c (connection, &entity, &esc_response))
        {
          g_string_free (commands_xml, TRUE);
          g_string_free (delta_states, TRUE);
          g_string_free (levels, TRUE);
          if (error) *error = 1;
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a report. "
                               "The report could not be delivered. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
      status = entity_attribute (entity, "status");
      if ((status == NULL)
          || (strlen (status) == 0))
        {
          free_entity (entity);
          g_string_free (commands_xml, TRUE);
          g_string_free (delta_states, TRUE);
          if (error) *error = 1;
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a report. "
                               "The report could not be delivered. "
                               "Diagnostics: Failure to parse response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
      free_entity (entity);
    }
  else
    esc_response = NULL;

  result_id = params_value (params, "result_id");
  delta_report_id = params_value (params, "delta_report_id");
  format_id = params_value (params, "report_format_id");

  first_result = params_value (params, "first_result");
  if (first_result == NULL
      || sscanf (first_result, "%u", &first) != 1)
    first_result = "1";

  max_results = params_value (params, "max_results");
  if (max_results == NULL
      || sscanf (max_results, "%u", &max) != 1)
    max_results = G_STRINGIFY (RESULTS_PER_PAGE);

  if (openvas_connection_sendf (connection,
                                "<get_reports"
                                "%s%s"
                                " details=\"%i\""
                                "%s%s%s",
                                (type && (strcmp (type, "prognostic") == 0))
                                 ? " type=\"prognostic\""
                                 : "",
                                (type && (strcmp (type, "assets") == 0))
                                 ? " type=\"assets\""
                                 : "",
                                (type
                                 && (strcmp (type, "assets") == 0)
                                 && host)
                                || delta_report_id
                                || strcmp (report_section, "summary"),
                                host ? " host=\"" : "",
                                host ? host : "",
                                host ? "\"" : "")
      == -1)
    {
      g_string_free (delta_states, TRUE);
      g_string_free (commands_xml, TRUE);
      g_string_free (levels, TRUE);
      if (error) *error = 1;
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a report. "
                           "The report could not be delivered. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  given_filt_id = params_value (params, "filt_id");
  filter = params_value (params, "filter");
  filter_extra = params_value (params, "filter_extra");

  if (params_given (params, "filt_id"))
    {
      g_tree_replace (credentials->last_filt_ids, g_strdup ("report_result"),
                      g_strdup (given_filt_id));
      filt_id = given_filt_id;
    }
  else if (filter == NULL || strcmp (filter, "") == 0)
    filt_id = g_tree_lookup (credentials->last_filt_ids, "report_result");
  else
    filt_id = NULL;

  if (filter == NULL)
    filter = "";

  if ((build_filter && (strcmp (build_filter, "1") == 0))
      || ((filter == NULL || strcmp (filter, "") == 0)
          && (filter_extra == NULL || strcmp (filter_extra, "") == 0)))
    {
      GString *filter_buffer;
      filter_buffer = g_string_new ("");

      g_string_append_printf (filter_buffer,
                              "autofp=%s"
                              " apply_overrides=%i"
                              " notes=%i"
                              " overrides=%i"
                              " result_hosts_only=%i"
                              " first=%s"
                              " rows=%s"
                              " sort%s=%s"
                              " levels=%s",
                              strcmp (autofp, "0") ? autofp_value : "0",
                              apply_overrides
                                ? (strcmp (apply_overrides, "0") ? 1 : 0)
                                : 1,
                              strcmp (notes, "0") ? 1 : 0,
                              strcmp (overrides, "0") ? 1 : 0,
                              strcmp (result_hosts_only, "0") ? 1 : 0,
                              first_result,
                              max_results,
                              sort_order
                                ? strcmp (sort_order, "ascending")
                                    ? "-reverse"
                                    : ""
                                : ((sort_field == NULL
                                    || strcmp (sort_field, "type") == 0
                                    || strcmp (sort_field, "severity") == 0)
                                    ? "-reverse"
                                    : ""),
                              sort_field ? sort_field : "severity",
                              levels->str);

      if (search_phrase && strcmp (search_phrase, ""))
        {
          gchar *search_phrase_escaped;
          search_phrase_escaped = g_markup_escape_text (search_phrase, -1);
          g_string_append_printf (filter_buffer,
                                  " \"%s\"",
                                  search_phrase_escaped);
          g_free (search_phrase_escaped);
        }

      if (delta_states->str && strcmp (delta_states->str, "")
          && delta_report_id && strcmp (delta_report_id, ""))
        g_string_append_printf (filter_buffer,
                                " delta_states=%s",
                                delta_states->str);

      if (min_qod && strcmp (min_qod, ""))
        g_string_append_printf (filter_buffer,
                                " min_qod=%s",
                                min_qod);

      if (zone && strcmp (zone, ""))
        g_string_append_printf (filter_buffer,
                                " timezone=%s",
                                zone);

      if (filter && strcmp (filter, ""))
        g_string_append_printf (filter_buffer,
                                " %s",
                                filter);

      built_filter = g_string_free (filter_buffer, FALSE);
    }
  else if (filter || filter_extra)
    built_filter = g_strdup_printf ("%s%s%s",
                                    filter ? filter : "",
                                    filter && filter_extra ? " " : "",
                                    filter_extra ? filter_extra : "");
  else
    built_filter = NULL;

  if (type && (strcmp (type, "prognostic") == 0))
    {
      host_search_phrase = params_value (params, "host_search_phrase");
      if (host_search_phrase == NULL)
        params_given (params, "host_search_phrase")
          || (host_search_phrase = "");

      host_levels = params_value (params, "host_levels");
      if (host_levels == NULL)
        params_given (params, "host_levels")
          || (host_levels = "");

      host_first_result = params_value (params, "host_first_result");
      if (host_first_result == NULL
          || sscanf (host_first_result, "%u", &first) != 1)
        host_first_result = "1";

      host_max_results = params_value (params, "host_max_results");
      if (host_max_results == NULL
          || sscanf (host_max_results, "%u", &max) != 1)
        host_max_results = G_STRINGIFY (RESULTS_PER_PAGE);

      if (host_search_phrase == NULL)
        {
          g_string_free (delta_states, TRUE);
          g_string_free (commands_xml, TRUE);
          g_string_free (levels, TRUE);
          xml = g_string_new ("");
          g_string_append_printf (xml, GSAD_MESSAGE_INVALID,
                                  "Given host search_phrase was invalid",
                                  "Get Report");
          if (error) *error = 1;
          response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
          return g_string_free (xml, FALSE);
        }

      if (openvas_connection_sendf_xml (connection,
                                        " host_search_phrase=\"%s\""
                                        " host_levels=\"%s\""
                                        " host_first_result=\"%s\""
                                        " host_max_results=\"%s\"",
                                        host_search_phrase,
                                        host_levels,
                                        host_first_result,
                                        host_max_results))
        {
          g_string_free (delta_states, TRUE);
          g_string_free (commands_xml, TRUE);
          g_string_free (levels, TRUE);
          if (error) *error = 1;
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a report. "
                               "The report could not be delivered. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }
  else
    {
      host_search_phrase = NULL;
      host_levels = NULL;
      host_first_result = NULL;
      host_max_results = NULL;
    }

  /* Don't apply default filter when applying result filter checkboxes/textboxes
   */
  if (sort_field == NULL && sort_order == NULL)
    if ((filt_id == NULL || strcmp (filt_id, "") == 0)
        && (filter == NULL || strcmp (filter, "") == 0))
      filt_id = "-2";

  if (ignore_filter)
    ret = openvas_connection_sendf_xml (connection,
                                        " filt_id=\"0\""
                                        " filter=\"first=1 rows=-1"
                                        "  result_hosts_only=0 apply_overrides=1"
                                        "  notes=1 overrides=1"
                                        "  sort-reverse=severity\""
                                        " report_id=\"%s\""
                                        " delta_report_id=\"%s\""
                                        " format_id=\"%s\"/>",
                                        (type && ((strcmp (type, "assets") == 0)
                                                  || (strcmp (type, "prognostic")
                                                      == 0)))
                                          ? ""
                                          : report_id,
                                        delta_report_id ? delta_report_id : "0",
                                        format_id
                                         ? format_id
                                         : "a994b278-1f62-11e1-96ac-406186ea4fc5");
  else
    ret = openvas_connection_sendf_xml (connection,
                                        " ignore_pagination=\"%d\""
                                        " filt_id=\"%s\""
                                        " filter=\"%s\""
                                        " pos=\"%s\""
                                        " notes_details=\"1\""
                                        " overrides_details=\"1\""
                                        " report_id=\"%s\""
                                        " delta_report_id=\"%s\""
                                        " format_id=\"%s\"/>",
                                        ignore_pagination,
                                        filt_id ? filt_id : "0",
                                        built_filter ? built_filter : "",
                                        pos ? pos : "1",
                                        (type && ((strcmp (type, "assets") == 0)
                                                  || (strcmp (type, "prognostic")
                                                      == 0)))
                                         ? ""
                                         : report_id,
                                        delta_report_id ? delta_report_id : "0",
                                        format_id
                                         ? format_id
                                         : "a994b278-1f62-11e1-96ac-406186ea4fc5",
                                        first_result,
                                        max_results,
                                        sort_field ? sort_field : "severity",
                                        sort_order
                                         ? sort_order
                                         : ((sort_field == NULL
                                            || strcmp (sort_field, "type") == 0
                                            || strcmp (sort_field, "severity") == 0)
                                           ? "descending"
                                           : "ascending"),
                                        levels->str,
                                        delta_states->str,
                                        search_phrase,
                                        min_qod,
                                        zone);
  if (ret == -1)
    {
      g_string_free (delta_states, TRUE);
      g_string_free (commands_xml, TRUE);
      g_string_free (levels, TRUE);
      if (error) *error = 1;
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a report. "
                           "The report could not be delivered. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  g_string_free (delta_states, TRUE);

  if (format_id)
    {
      g_string_free (commands_xml, TRUE);
      g_string_free (levels, TRUE);
      if ((strcmp (format_id, "a994b278-1f62-11e1-96ac-406186ea4fc5") == 0)
          || strcmp (format_id, "5057e5cc-b825-11e4-9d0e-28d24461215b") == 0)
        {
          const char *extension, *requested_content_type;
          /* Manager sends XML report as plain XML. */

          if (read_entity_c (connection, &entity))
            {
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to receive response from manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }
          entity_t report = entity_child (entity, "report");
          if (report == NULL)
            {
              free_entity (entity);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Response from manager daemon did not contain a report.",
                                   "/omp?cmd=get_tasks", response_data);
            }
          extension = entity_attribute (report, "extension");
          requested_content_type = entity_attribute (report, "content_type");
          if (extension && requested_content_type && content_type
              && content_disposition)
            {
              gchar *file_name;
              ret = setting_get_value (connection,
                                       "e1a2ae0b-736e-4484-b029-330c9e15b900",
                                       &fname_format,
                                       response_data);
              if (ret)
                {
                  switch (ret)
                    {
                      case 1:
                        response_data->http_status_code
                          = MHD_HTTP_INTERNAL_SERVER_ERROR;
                        return gsad_message (credentials,
                                            "Internal error", __FUNCTION__, __LINE__,
                                            "An internal error occurred while getting a setting. "
                                            "The setting could not be delivered. "
                                            "Diagnostics: Failure to send command to manager daemon.",
                                            "/omp?cmd=get_tasks",
                                             response_data);
                      case 2:
                        response_data->http_status_code
                          = MHD_HTTP_INTERNAL_SERVER_ERROR;
                        return gsad_message (credentials,
                                            "Internal error", __FUNCTION__, __LINE__,
                                            "An internal error occurred while getting a setting. "
                                            "The setting could not be delivered. "
                                            "Diagnostics: Failure to receive response from manager daemon.",
                                            "/omp?cmd=get_tasks",
                                             response_data);
                      default:
                        response_data->http_status_code
                          = MHD_HTTP_INTERNAL_SERVER_ERROR;
                        return gsad_message (credentials,
                                            "Internal error", __FUNCTION__, __LINE__,
                                            "An internal error occurred while getting a setting. "
                                            "The setting could not be delivered. "
                                            "Diagnostics: Internal error.",
                                            "/omp?cmd=get_tasks",
                                             response_data);
                    }
                }

              if (fname_format == NULL)
                {
                  g_warning ("%s : File name format setting not found.",
                              __FUNCTION__);
                  fname_format = "%T-%U";
                }

              file_name = format_file_name (fname_format,
                                            credentials,
                                            "report",
                                            (type
                                             && ((strcmp (type, "assets") == 0)
                                                 || (strcmp (type, "prognostic")
                                                     == 0)))
                                            ? type
                                            : report_id,
                                            report);
              if (file_name == NULL)
                file_name = g_strdup_printf ("%s-%s",
                                            "report",
                                            (type
                                             && ((strcmp (type, "assets") == 0)
                                                 || (strcmp (type, "prognostic")
                                                     == 0)))
                                              ? type
                                              : report_id);

              *content_type = g_strdup (requested_content_type);
              *content_disposition
                = g_strdup_printf ("attachment; filename=\"%s.%s\"",
                                   file_name,
                                   extension);

              g_free (file_name);
            }
          xml = g_string_new ("");
          print_entity_to_string (report, xml);
          free_entity (entity);
          if (error) *error = 1;
          return g_string_free (xml, FALSE);
        }
      else
        {
          /* "nbe", "pdf", "dvi", "html", "html-pdf"... */

          if (report_len == NULL)
            {
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Parameter error.",
                                   "/omp?cmd=get_tasks", response_data);
            }

          entity = NULL;
          if (read_entity_c (connection, &entity))
            {
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to receive response from manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }

          report_entity = entity_child (entity, "report");
          if (report_entity != NULL)
            {
              const char *extension, *requested_content_type;
              char *report_encoded;
              gchar *report_decoded;
              extension = entity_attribute (report_entity, "extension");
              requested_content_type = entity_attribute (report_entity,
                                                         "content_type");
              report_encoded = entity_text (report_entity);
              report_decoded =
                (gchar *) g_base64_decode (report_encoded, report_len);
              /* g_base64_decode can return NULL (Glib 2.12.4-2), at least
               * when *report_len is zero. */
              if (report_decoded == NULL)
                {
                  report_decoded = g_strdup ("");
                  *report_len = 0;
                }
              if (extension && requested_content_type && content_type
                  && content_disposition)
                {
                  gchar *file_name;
                  const char *id;
                  if (report_id)
                    id = report_id;
                  else if (type && (strcmp (type, "prognostic") == 0))
                    id = "prognostic";
                  else
                    id = "ERROR";

                  ret = setting_get_value
                          (connection,
                           "e1a2ae0b-736e-4484-b029-330c9e15b900",
                           &fname_format,
                           response_data);
                  if (ret)
                    {
                      switch (ret)
                        {
                          case 1:
                            response_data->http_status_code
                              = MHD_HTTP_INTERNAL_SERVER_ERROR;
                            return gsad_message (credentials,
                                                "Internal error", __FUNCTION__, __LINE__,
                                                "An internal error occurred while getting a setting. "
                                                "The setting could not be delivered. "
                                                "Diagnostics: Failure to send command to manager daemon.",
                                                "/omp?cmd=get_tasks",
                                                 response_data);
                          case 2:
                            response_data->http_status_code
                              = MHD_HTTP_INTERNAL_SERVER_ERROR;
                            return gsad_message (credentials,
                                                "Internal error", __FUNCTION__, __LINE__,
                                                "An internal error occurred while getting a setting. "
                                                "The setting could not be delivered. "
                                                "Diagnostics: Failure to receive response from manager daemon.",
                                                "/omp?cmd=get_tasks",
                                                 response_data);
                          default:
                            response_data->http_status_code
                              = MHD_HTTP_INTERNAL_SERVER_ERROR;
                            return gsad_message (credentials,
                                                "Internal error", __FUNCTION__, __LINE__,
                                                "An internal error occurred while getting a setting. "
                                                "The setting could not be delivered. "
                                                "Diagnostics: Internal error.",
                                                "/omp?cmd=get_tasks",
                                                 response_data);
                        }
                    }

                  if (fname_format == NULL)
                    {
                      g_warning ("%s : File name format setting not found.",
                                  __FUNCTION__);
                      fname_format = "%T-%U";
                    }

                  file_name = format_file_name (fname_format, credentials,
                                                "report", id, report_entity);
                  if (file_name == NULL)
                    file_name = g_strdup_printf ("%s-%s",
                                                "report", id);

                  *content_type = g_strdup (requested_content_type);
                  *content_disposition
                    = g_strdup_printf ("attachment; filename=\"%s.%s\"",
                                      file_name,
                                      extension);

                  g_free (file_name);
                }
              free_entity (entity);
              if (error) *error = 1;
              return report_decoded;
            }
          else
            {
              free_entity (entity);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to receive report from manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }
        }
    }
  else
    {
      gchar *task_id;

      task_id = NULL;

      /* Format is NULL, send XSL transformed XML. */

      if (delta_report_id && result_id && strcmp (result_id, "0"))
        xml = g_string_new ("<get_delta_result>");
      else if (host || (type && (strcmp (type, "prognostic") == 0)))
        {
          if (type && (strcmp (type, "prognostic") == 0))
            {
              xml = g_string_new ("<get_prognostic_report>");

              xml_string_append (xml,
                                 "<host_search_phrase>"
                                 "%s"
                                 "</host_search_phrase>"
                                 "<host_levels>%s</host_levels>"
                                 "<results start=\"%s\" max=\"%s\"/>",
                                 host_search_phrase,
                                 host_levels,
                                 host_first_result,
                                 host_max_results);
            }
          else
            xml = g_string_new ("<get_asset>");
          xml_string_append (xml,
                             "<search_phrase>%s</search_phrase>"
                             "<levels>%s</levels>"
                             "<hosts start=\"%s\" max=\"%s\"/>",
                             search_phrase,
                             levels->str,
                             first_result,
                             max_results);
        }
      else
        xml = g_string_new ("<get_report>");

      if (extra_xml)
        g_string_append (xml, extra_xml);

      if (commands)
        g_string_append (xml, commands_xml->str);
      g_string_free (commands_xml, TRUE);
      g_string_free (levels, TRUE);

      if (strcmp (alert_id, "0"))
        {
          g_string_append_printf (xml, "<get_reports_alert_response>");
          if (esc_response)
            {
              g_string_append (xml, esc_response);
              g_free (esc_response);
            }
          g_string_append_printf (xml, "</get_reports_alert_response>");
        }
      else if (delta_report_id)
        g_string_append_printf (xml,
                                "<delta>%s</delta>"
                                "<result id=\"%s\"/>",
                                delta_report_id,
                                result_id ? result_id : "0");

      entity = NULL;
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          if (error) *error = 1;
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting a report. "
                               "The report could not be delivered. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if ((filt_id == NULL) && (params_value (params, "filter") == NULL))
        {
          entity_t term;

          /* Add the filter from the report as a param, because it's easier to
           * get from the envelope for things like the New Note icon. */

          term = entity_child (entity, "report");
          if (term
              && ((term = entity_child (term, "report")))
              && ((term = entity_child (term, "filters")))
              && ((term = entity_child (term, "term"))))
            {
              param_t *param;
              param = params_add (params, "filter", entity_text (term));
              param->valid = 1;
              param->valid_utf8 = g_utf8_validate (param->value, -1, NULL);
            }
        }

      if ((type && (strcmp (type, "prognostic") == 0))
          && (command_enabled (credentials, "GET_REPORT_FORMATS")))
        {
          if (openvas_connection_sendf
               (connection,
                "<get_report_formats"
                " filter=\"rows=-1 sort=name\"/>")
              == -1)
            {
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to send command to manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }

          if (read_string_c (connection, &xml))
            {
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to receive response from manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }
        }

      if (type && (strcmp (type, "prognostic") == 0))
        {
          if (command_enabled (credentials, "GET_FILTERS"))
            {
              /* Get the filters. */

              g_string_append (xml, "<filters>");

              if (openvas_connection_sendf_xml (connection,
                                                "<get_filters"
                                                " filter=\"type=result\"/>")
                  == -1)
                {
                  g_string_free (xml, TRUE);
                  if (error) *error = 1;
                  response_data->http_status_code
                    = MHD_HTTP_INTERNAL_SERVER_ERROR;
                  return gsad_message (credentials,
                                       "Internal error", __FUNCTION__, __LINE__,
                                       "An internal error occurred while getting the filter list. "
                                       "The current list of filters is not available. "
                                       "Diagnostics: Failure to send command to manager daemon.",
                                       "/omp?cmd=get_tasks", response_data);
                }

              if (read_string_c (connection, &xml))
                {
                  g_string_free (xml, TRUE);
                  if (error) *error = 1;
                  response_data->http_status_code
                    = MHD_HTTP_INTERNAL_SERVER_ERROR;
                  return gsad_message (credentials,
                                       "Internal error", __FUNCTION__, __LINE__,
                                       "An internal error occurred while getting the filter list. "
                                       "The current list of filters is not available. "
                                       "Diagnostics: Failure to receive response from manager daemon.",
                                       "/omp?cmd=get_tasks", response_data);
                }

              g_string_append (xml, "</filters>");
            }

          g_string_append (xml, "</get_prognostic_report>");
          return g_string_free (xml, FALSE);
        }

      if (type && (strcmp (type, "assets") == 0))
        {
          if (host)
            g_string_append (xml, "</get_asset>");
          else
            g_string_append (xml, "</get_report>");
          return g_string_free (xml, FALSE);
        }

      report_entity = entity_child (entity, "report");
      if (report_entity)
        report_entity = entity_child (report_entity, "report");
      if (report_entity)
        {
          const char *id;
          entity_t task_entity, name;

          id = NULL;
          task_entity = entity_child (report_entity, "task");
          if (task_entity)
            {
              id = entity_attribute (task_entity, "id");
              name = entity_child (task_entity, "name");
            }
          else
            name = NULL;
          if (id)
            task_id = g_strdup (id);
          if (delta_report_id && result_id && id && name)
            g_string_append_printf (xml,
                                    "<task id=\"%s\"><name>%s</name></task>",
                                    id,
                                    entity_text (name));

          free_entity (entity);
        }

      if (task_id)
        {
          if (openvas_connection_sendf (connection,
                                        "<get_tasks task_id=\"%s\" details=\"0\" />",
                                        task_id)
              == -1)
            {
              g_free (task_id);
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to send command to manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }

          if (read_string_c (connection, &xml))
            {
              g_free (task_id);
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to send command to manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }

          g_free (task_id);
        }

      if (delta_report_id && result_id && strcmp (result_id, "0"))
        {
          g_string_append (xml, "</get_delta_result>");
          return g_string_free (xml, FALSE);
        }

      if (command_enabled (credentials, "GET_REPORT_FORMATS"))
        {
          gchar *default_report_format, *err;

          /* Get Default Report Format. */

          err = setting_get_value_error (credentials,
                                         connection,
                                         "353304fc-645e-11e6-ba7a-28d24461215b",
                                         &default_report_format,
                                         response_data);
          if (err)
            {
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              return err;
            }

          g_string_append_printf (xml,
                                  "<report_format_id>%s</report_format_id>",
                                  default_report_format);

          /* Get all the report formats. */

          if (openvas_connection_sendf
               (connection,
                "<get_report_formats"
                " filter=\"rows=-1 sort=name\"/>")
              == -1)
            {
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to send command to manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }

          if (read_string_c (connection, &xml))
            {
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to receive response from manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }
        }

      if (command_enabled (credentials, "GET_ALERTS"))
        {
          if (openvas_connection_sendf
               (connection,
                "<get_alerts"
                " filter=\"rows=-1 sort=name\"/>")
              == -1)
            {
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to send command to manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }

          if (read_string_c (connection, &xml))
            {
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting a report. "
                                   "The report could not be delivered. "
                                   "Diagnostics: Failure to receive response from manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }
        }

      if (command_enabled (credentials, "GET_FILTERS"))
        {
          /* Get the filters. */

          g_string_append (xml, "<filters>");

          if (openvas_connection_sendf_xml (connection,
                                            "<get_filters"
                                            " filter=\"type=result\"/>")
              == -1)
            {
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting the filter list. "
                                   "The current list of filters is not available. "
                                   "Diagnostics: Failure to send command to manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }

          if (read_string_c (connection, &xml))
            {
              g_string_free (xml, TRUE);
              if (error) *error = 1;
              response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
              return gsad_message (credentials,
                                   "Internal error", __FUNCTION__, __LINE__,
                                   "An internal error occurred while getting the filter list. "
                                   "The current list of filters is not available. "
                                   "Diagnostics: Failure to receive response from manager daemon.",
                                   "/omp?cmd=get_tasks", response_data);
            }

          g_string_append (xml, "</filters>");
        }

      /* Get tag names */

      if (openvas_connection_sendf (connection,
                                    "<get_tags"
                                    " filter=\"resource_type=report"
                                    "          first=1"
                                    "          rows=-1\""
                                    " names_only=\"1\""
                                    "/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while getting tag names list. "
                              "The current list of resources is not available. "
                              "Diagnostics: Failure to send command to manager daemon.",
                              "/omp?cmd=get_resources", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while getting tag names list. "
                              "The current list of resources is not available. "
                              "Diagnostics: Failure to receive response from manager daemon.",
                              "/omp?cmd=get_resources", response_data);
        }

      g_string_append (xml, "</get_report>");
      return g_string_free (xml, FALSE);
    }
}

/**
 * @brief Get a report and XSL transform the result.
 *
 * @param[in]  connection           Connection to manager
 * @param[in]  credentials          Username and password for authentication.
 * @param[in]  params               Request parameters.
 * @param[out] report_len           Length of report.
 * @param[out] content_type         Content type if known, else NULL.
 * @param[out] content_disposition  Content disposition, if content_type set.
 * @param[out] response_data        Extra data return for the HTTP response.
 *
 * @return Report.
 */
char *
get_report_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, gsize *report_len, gchar ** content_type,
                char **content_disposition, cmd_response_data_t* response_data)
{
  char *result;
  int error = 0;

  result = get_report (connection, credentials, params, NULL, report_len,
                       content_type, content_disposition, NULL, &error,
                       response_data);

  return error ? result : xsl_transform_omp (connection, credentials, params,
                                             result, response_data);
}

/**
 * @brief Get all reports, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_reports (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  const char *overrides;

  overrides = params_value (params, "overrides");
  if (overrides)
    /* User toggled overrides.  Set the overrides value in the filter. */
    params_toggle_overrides (params, overrides);

  return get_many (connection, "report", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all reports, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_reports_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return get_reports (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get the hosts for a report, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_report_section (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    const char *extra_xml, cmd_response_data_t* response_data)
{
  GString *xml;
  const char *report_id, *report_section, *type;
  char *result;
  int error = 0;

  report_section = params_value (params, "report_section");
  report_id = params_value (params, "report_id");
  type = params_value (params, "type");

  if (report_section == NULL)
    report_section = "results";

  if (report_id == NULL && (type == NULL || strcmp (type, "prognostic")))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred."
                           " Diagnostics: report_id was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (!strcmp (report_section, "results"))
    {
      char *result;

      result = get_report (connection, credentials, params, NULL, NULL, NULL,
                           NULL, extra_xml, &error, response_data);

      return error ? result : xsl_transform_omp (connection, credentials,
                                                 params, result, response_data);
    }

  result = get_report (connection, credentials, params, NULL, NULL, NULL,
                       NULL, NULL, &error, response_data);
  if (error)
    return result;

  xml = g_string_new ("");
  g_string_append_printf (xml, "<get_report_%s_response>", report_section);
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, result);
  if (strcmp (params_value (params, "report_section"), "topology") == 0)
    {
      int ret;
      char *response;

      ret = omp (connection, credentials,
                 &response,
                 NULL,
                 response_data,
                 "<get_report_formats"
                 " filter=\"rows=-1\"/>");

      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            g_string_free (xml, TRUE);
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting the "
                                "result formats list. "
                                "Diagnostics: Failure to send command to manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          case 2:
            g_string_free (xml, TRUE);
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting the "
                                "result formats list. "
                                "Diagnostics: Failure to receive response from manager daemon.",
                                "/omp?cmd=get_tasks", response_data);
          default:
            g_string_free (xml, TRUE);
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting the "
                                "result formats list. "
                                "Diagnostics: Internal Error.",
                                "/omp?cmd=get_tasks", response_data);
        }

      g_string_append (xml, response);
      g_free (response);
    }

  g_string_append_printf (xml, "</get_report_%s_response>", report_section);

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Get a report section, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_report_section_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  return get_report_section (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get an SSL Certificate.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  response_size  Size of cert.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return SSL Certificate.
 */
char *
download_ssl_cert (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   gsize *response_size, cmd_response_data_t* response_data)
{
  const char *ssl_cert;
  gchar *cert;
  char *unescaped;

  ssl_cert = params_value (params, "ssl_cert");
  if (ssl_cert == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred."
                           " Diagnostics: ssl_cert was NULL.",
                           "/omp?cmd=get_reports", response_data);
    }
  /* The Base64 comes URI escaped as it may contain special characters. */
  unescaped = g_uri_unescape_string (ssl_cert, NULL);

  cert = g_strdup_printf ("-----BEGIN CERTIFICATE-----\n"
                          "%s\n-----END CERTIFICATE-----\n",
                          unescaped);

  *response_size = strlen (cert);

  g_free (unescaped);
  return cert;
}

/**
 * @brief Get a Scanner's CA Certificate.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  response_size  Size of cert.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return CA Certificate.
 */
char *
download_ca_pub (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, gsize *response_size,
                 cmd_response_data_t* response_data)
{
  const char *ca_pub;
  char *unescaped;

  ca_pub = params_value (params, "ca_pub");
  if (ca_pub == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred."
                           " Diagnostics: ca_pub was NULL.",
                           "/omp?cmd=get_reports", response_data);
    }
  /* The Base64 comes URI escaped as it may contain special characters. */
  unescaped = g_uri_unescape_string (ca_pub, NULL);
  *response_size = strlen (unescaped);
  return unescaped;
}

/**
 * @brief Get a Scanner's Certificate.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  response_size  Size of cert.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Certificate.
 */
char *
download_key_pub (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, gsize *response_size,
                  cmd_response_data_t* response_data)
{
  const char *key_pub;
  char *unescaped;

  key_pub = params_value (params, "key_pub");
  if (key_pub == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred."
                           " Diagnostics: key_pub was NULL.",
                           "/omp?cmd=get_reports", response_data);
    }

  /* The Base64 comes URI escaped as it may contain special characters. */
  unescaped = g_uri_unescape_string (key_pub, NULL);
  *response_size = strlen (unescaped);
  return unescaped;
}

/**
 * @brief Export a result.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Result XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_result_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   enum content_type * content_type, char **content_disposition,
                   gsize *content_length, cmd_response_data_t* response_data)
{
  return export_resource (connection, "result", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of results.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Results XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_results_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    enum content_type * content_type,
                    char **content_disposition, gsize *content_length,
                    cmd_response_data_t* response_data)
{
  return export_many (connection, "result", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Get all results, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_results (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  const char *overrides;
  overrides = params_value (params, "overrides");

  if (overrides)
    /* User toggled overrides.  Set the overrides value in the filter. */
    params_toggle_overrides (params, overrides);

  return get_many (connection, "result", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all results, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_results_omp (openvas_connection_t *connection, credentials_t *credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return get_results (connection, credentials,
                      params,
                      NULL,
                      response_data);
}

/**
 * @brief Get one result, XSL transform the result.
 *
 * @param[in]  connection       Connection to manager
 * @param[in]  credentials      Username and password for authentication.
 * @param[in]  params           Request parameters.
 * @param[in]  result_id        Result UUID.
 * @param[in]  task_id          Result task UUID.
 * @param[in]  apply_overrides  Whether to apply overrides.
 * @param[in]  commands         Extra commands to run before the others.
 * @param[in]  report_id        ID of report.
 * @param[in]  autofp           Auto FP filter flag.
 * @param[in]  extra_xml        Extra XML to insert inside page element.
 * @param[out] response_data    Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_result (openvas_connection_t *connection, credentials_t *credentials,
            params_t *params, const char *result_id, const char *task_id,
            const char *task_name, const char *apply_overrides,
            const char *commands, const char *report_id, const char *autofp,
            const char *extra_xml, cmd_response_data_t* response_data)
{
  GString *xml;

  if (apply_overrides == NULL)
    apply_overrides = "1";

  if (autofp == NULL)
    autofp = "0";

  xml = g_string_new ("<get_result>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  xml_string_append (xml,
                     "<task id=\"%s\"><name>%s</name></task>"
                     "<report id=\"%s\"/>",
                     task_id,
                     task_name,
                     report_id);

  /* Get the result. */

  if (openvas_connection_sendf (connection,
                                "<commands>"
                                "%s"
                                "<get_results"
                                " result_id=\"%s\""
                                " get_counts=\"0\""
                                "%s%s%s"
                                " filter=\"autofp=%s"
                                " apply_overrides=%s"
                                " overrides=%s"
                                " notes=1\""
                                " overrides_details=\"1\""
                                " notes_details=\"1\""
                                " details=\"1\"/>"
                                "</commands>",
                                commands ? commands : "",
                                result_id,
                                task_id ? " task_id=\"" : "",
                                task_id ? task_id : "",
                                task_id ? "\"" : "",
                                autofp,
                                apply_overrides,
                                apply_overrides)
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a result. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a result. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Get tag names */

  if (openvas_connection_sendf (connection,
                                "<get_tags"
                                " filter=\"resource_type=result"
                                "          first=1"
                                "          rows=-1\""
                                " names_only=\"1\""
                                "/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting tag names list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting tag names list. "
                           "The current list of resources is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_resources", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</get_result>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Get one result, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_result_omp (openvas_connection_t *connection, credentials_t *credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return get_result (connection, credentials, params,
                     params_value (params, "result_id"),
                     params_value (params, "task_id"),
                     params_value (params, "name"),
                     params_value (params, "apply_overrides"),
                     NULL,
                     params_value (params, "report_id"),
                     params_value (params, "autofp"),
                     NULL,
                     response_data);
}

/**
 * @brief Get result details page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_result_page (openvas_connection_t *connection, credentials_t *credentials,
                 params_t *params, const char *extra_xml,
                 cmd_response_data_t* response_data)
{
  return get_result (connection, credentials, params,
                     params_value (params, "result_id"),
                     params_value (params, "task_id"),
                     params_value (params, "name"),
                     params_value (params, "apply_overrides"),
                     NULL,
                     params_value (params, "report_id"),
                     params_value (params, "autofp"),
                     extra_xml,
                     response_data);

}

/**
 * @brief Get all notes, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_notes (openvas_connection_t *connection, credentials_t *credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  return get_many (connection, "note", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all notes, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_notes_omp (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return get_notes (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get a note, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_note (openvas_connection_t *connection, credentials_t *credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  return get_one (connection, "note", credentials, params, extra_xml, NULL,
                  response_data);
}

/**
 * @brief Get a note, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_note_omp (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return get_note (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Return the new notes page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_note (openvas_connection_t *connection, credentials_t *credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  GString *xml;
  const char *oid, *hosts, *port, *severity, *task_id, *task_name, *result_id;
  const char *next;
  /* Passthroughs. */
  const char *report_id, *first_result, *max_results, *sort_field;
  const char *sort_order, *levels, *autofp, *notes;
  const char *overrides, *result_hosts_only, *search_phrase;

  result_id = params_value (params, "result_id");
  task_id = params_value (params, "task_id");

  next = params_value (params, "next");
  first_result = params_value (params, "first_result");
  max_results = params_value (params, "max_results");
  levels = params_value (params, "levels");
  autofp = params_value (params, "autofp");
  notes = params_value (params, "notes");
  report_id = params_value (params, "report_id");
  search_phrase = params_value (params, "search_phrase");
  sort_field = params_value (params, "sort_field");
  sort_order = params_value (params, "sort_order");
  task_name = params_value (params, "name");
  severity = params_value (params, "severity");
  result_hosts_only = params_value (params, "result_hosts_only");

  hosts = params_value (params, "hosts");
  oid = params_value (params, "oid");
  port = params_value (params, "port");
  overrides = params_value (params, "overrides");

  if (result_id == NULL || task_id == NULL)
    {
      xml = g_string_new ("");

      xml_string_append (xml,
                         "<new_note>"
                         "<nvt id=\"%s\"/>"
                         "<next>%s</next>",
                         oid ? oid : "0",
                         next ? next : "");

      if (extra_xml)
        g_string_append (xml, extra_xml);

      if (openvas_connection_sendf (connection,
                                    "<get_tasks"
                                    " schedules_only=\"1\""
                                    " details=\"0\"/>")
          == -1)
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while creating a new note. "
                               "No new note was created. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_notes", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while creating a new note. "
                               "No new note was created. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_notes", response_data);
        }

      g_string_append (xml, "</new_note>");
      return xsl_transform_omp (connection, credentials, params,
                                g_string_free (xml, FALSE), response_data);
    }

  if (openvas_connection_sendf (connection,
                                "<get_results"
                                " result_id=\"%s\""
                                " task_id=\"%s\""
                                " notes_details=\"1\""
                                " notes=\"1\""
                                " result_hosts_only=\"1\"/>",
                                result_id,
                                task_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while creating a new note. "
                           "No new note was created. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_notes", response_data);
    }

  xml = g_string_new ("");

  xml_string_append (xml,
                     "<new_note>"
                     "<nvt id=\"%s\"/>"
                     "<hosts>%s</hosts>"
                     "<port>%s</port>"
                     "<severity>%s</severity>"
                     "<task id=\"%s\">"
                     "<name>%s</name>"
                     "</task>"
                     "<result id=\"%s\"/>"
                     "<next>%s</next>"
                     /* Passthroughs. */
                     "<report id=\"%s\"/>"
                     "<first_result>%s</first_result>"
                     "<max_results>%s</max_results>"
                     "<sort_field>%s</sort_field>"
                     "<sort_order>%s</sort_order>"
                     "<levels>%s</levels>"
                     "<autofp>%s</autofp>"
                     "<notes>%s</notes>"
                     "<overrides>%s</overrides>"
                     "<result_hosts_only>%s</result_hosts_only>"
                     "<search_phrase>%s</search_phrase>",
                     oid,
                     hosts,
                     /* port is NULL for CVE scan results. */
                     port ? port : "",
                     severity,
                     task_id,
                     task_name,
                     result_id,
                     next ? next : "",
                     report_id,
                     first_result,
                     max_results,
                     sort_field,
                     sort_order,
                     levels,
                     autofp,
                     notes,
                     overrides,
                     result_hosts_only,
                     search_phrase);

  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while creating a new note. "
                           "It is unclear whether the note has been created or not. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_notes", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</new_note>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the new notes page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_note_omp (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return new_note (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create a note, get report, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_note_omp (openvas_connection_t *connection, credentials_t *credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  char *ret;
  gchar *response;
  const char *no_redirect, *oid, *severity, *port, *hosts;
  const char *text, *task_id, *note_result_id;
  /* For get_report. */
  const char *active, *days;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  oid = params_value (params, "oid");
  CHECK_PARAM_INVALID (oid, "Create Note", "new_note");

  if (params_valid (params, "severity"))
    severity = params_value (params, "severity");
  else if (params_given (params, "severity")
           && strcmp (params_original_value (params, "severity"), ""))
    severity = NULL;
  else
    severity = "";
  CHECK_PARAM_INVALID (severity, "Create Note", "new_note");

  port = params_value (params, "port");
  if (port == NULL)
    port = "";
  if (strcmp (port, "--") == 0)
    {
      int num = -1;

      port = params_value (params, "port_manual");
      if (port)
        num = atoi (port);
      if (num < 0 || num > 65535)
        port = NULL;
    }
  CHECK_PARAM_INVALID (port, "Create Note", "new_note");

  if (params_valid (params, "hosts"))
    {
      hosts = params_value (params, "hosts");
      if (strcmp (hosts, "--") == 0)
        {
          if (params_valid (params, "hosts_manual"))
            hosts = params_value (params, "hosts_manual");
          else if (params_given (params, "hosts_manual")
                   && strcmp (params_original_value (params, "hosts_manual"),
                              ""))
            hosts = NULL;
          else
            hosts = "";
        }
    }
  else if (strcmp (params_original_value (params, "hosts"), ""))
    hosts = NULL;
  else
    hosts = "";
  CHECK_PARAM_INVALID (hosts, "Create Note", "new_note");

  if (params_valid (params, "note_task_id"))
    {
      task_id = params_value (params, "note_task_id");
      if (task_id && (strcmp (task_id, "0") == 0))
        task_id = params_value (params, "note_task_uuid");
    }
  else if (params_given (params, "note_task_id")
           && strcmp (params_original_value (params, "note_task_id"), ""))
    task_id = NULL;
  else
    task_id = "";

  active = params_value (params, "active");
  CHECK_PARAM_INVALID (active, "Create Note", "new_note");

  text = params_value (params, "text");
  days = params_value (params, "days");

  note_result_id = params_value (params, "note_result_id");
  if (note_result_id && (strcmp (note_result_id, "0") == 0))
    note_result_id = params_value (params, "note_result_uuid");

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<create_note>"
                "<active>%s</active>"
                "<nvt oid=\"%s\"/>"
                "<hosts>%s</hosts>"
                "<port>%s</port>"
                "<severity>%s</severity>"
                "<text>%s</text>"
                "<task id=\"%s\"/>"
                "<result id=\"%s\"/>"
                "</create_note>",
                strcmp (active, "1")
                 ? active
                 : (days ? days : "-1"),
                oid,
                hosts,
                port,
                severity,
                text ? text : "",
                task_id,
                note_result_id))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new note. "
                             "No new note was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_notes", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new note. "
                             "It is unclear whether the note has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_notes", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new note. "
                             "It is unclear whether the note has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_notes", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "note_id", entity_attribute (entity, "id"));
  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_notes",
                              NULL, "new_note",
                              "Create Note", response_data);
  free_entity (entity);
  g_free (response);
  return ret;
}

/**
 * @brief Delete note, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_note_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return delete_resource (connection, "note", credentials, params, 0, NULL,
                          response_data);
}

/**
 * @brief Delete a note, get all notes, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_note_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  return delete_resource (connection, "note", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Edit note, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_note (openvas_connection_t *connection, credentials_t *credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  GString *xml;
  const char *note_id;

  note_id = params_value (params, "note_id");

  if (openvas_connection_sendf (connection,
                            "<get_notes"
                            " note_id=\"%s\""
                            " details=\"1\""
                            " result=\"1\"/>",
                            note_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing a note. "
                           "The note remains as it was. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_notes", response_data);
    }

  xml = g_string_new ("");

  xml_string_append (xml, "<edit_note>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing a note. "
                           "The note remains as it was. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_notes", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</edit_note>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Edit note, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_note_omp (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return edit_note (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Save note, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_note_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  gchar *response;
  entity_t entity;
  const char *no_redirect;
  const char *note_id, *text, *hosts, *port, *severity, *note_task_id;
  const char *note_result_id, *active, *days;
  char *ret;

  no_redirect = params_value (params, "no_redirect");
  note_id = params_value (params, "note_id");

  text = params_value (params, "text");
  if (text == NULL)
    params_given (params, "text") || (text = "");

  if (params_valid (params, "hosts"))
    hosts = params_value (params, "hosts");
  else if (strcmp (params_original_value (params, "hosts"), ""))
    hosts = NULL;
  else
    hosts = "";

  if (params_valid (params, "port"))
    port = params_value (params, "port");
  else if (strcmp (params_original_value (params, "port"), ""))
    port = NULL;
  else
    port = "";

  if (params_valid (params, "severity"))
    severity = params_value (params, "severity");
  else if (strcmp (params_original_value (params, "severity"), ""))
    severity = NULL;
  else
    severity = "";

  note_task_id = params_value (params, "note_task_id");
  note_result_id = params_value (params, "note_result_id");

  active = params_value (params, "active");
  days = params_value (params, "days");

  CHECK_PARAM_INVALID (note_task_id, "Save Note", "edit_note");
  CHECK_PARAM_INVALID (note_result_id, "Save Note", "edit_note");
  CHECK_PARAM_INVALID (active, "Save Note", "edit_note");
  CHECK_PARAM_INVALID (note_id, "Save Note", "edit_note");
  CHECK_PARAM_INVALID (text, "Save Note", "edit_note");
  CHECK_PARAM_INVALID (hosts, "Save Note", "edit_note");
  CHECK_PARAM_INVALID (port, "Save Note", "edit_note");
  CHECK_PARAM_INVALID (severity, "Save Note", "edit_note");
  CHECK_PARAM_INVALID (days, "Save Note", "edit_note");

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<modify_note note_id=\"%s\">"
                "<active>%s</active>"
                "<hosts>%s</hosts>"
                "<port>%s</port>"
                "<severity>%s</severity>"
                "<text>%s</text>"
                "<task id=\"%s\"/>"
                "<result id=\"%s\"/>"
                "</modify_note>",
                note_id,
                strcmp (active, "1")
                 ? active
                 : (days ? days : "-1"),
                hosts ? hosts : "",
                port ? port : "",
                severity ? severity : "",
                text ? text : "",
                note_task_id,
                note_result_id))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a note. "
                             "The note remains the same. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_notes", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a note. "
                             "It is unclear whether the note has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_notes", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a note. "
                             "It is unclear whether the note has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_notes", response_data);
    }

  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_notes",
                              NULL, "edit_note",
                              "Save Note", response_data);

  free_entity (entity);
  g_free (response);
  return ret;
}

/**
 * @brief Get all overrides, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_overrides (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, const char *extra_xml,
               cmd_response_data_t* response_data)
{
  return get_many (connection, "override", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all overrides, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_overrides_omp (openvas_connection_t *connection, credentials_t *credentials,
                   params_t *params, cmd_response_data_t* response_data)
{
  return get_overrides (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get a override, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_override (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, const char *extra_xml,
              cmd_response_data_t* response_data)
{
  return get_one (connection, "override", credentials, params, extra_xml, NULL,
                  response_data);
}

/**
 * @brief Get an override, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_override_omp (openvas_connection_t *connection, credentials_t *credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  return get_override (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Return the new overrides page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_override (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, const char *extra_xml,
              cmd_response_data_t* response_data)
{
  GString *xml;
  const char *oid, *hosts, *port, *severity, *task_id, *task_name, *result_id;
  const char *next;
  /* Passthroughs. */
  const char *report_id, *first_result, *max_results, *sort_field;
  const char *sort_order, *levels, *autofp, *notes;
  const char *overrides, *result_hosts_only, *search_phrase;

  result_id = params_value (params, "result_id");
  task_id = params_value (params, "task_id");

  next = params_value (params, "next");
  first_result = params_value (params, "first_result");
  max_results = params_value (params, "max_results");
  levels = params_value (params, "levels");
  autofp = params_value (params, "autofp");
  notes = params_value (params, "notes");
  report_id = params_value (params, "report_id");
  search_phrase = params_value (params, "search_phrase");
  sort_field = params_value (params, "sort_field");
  sort_order = params_value (params, "sort_order");
  task_name = params_value (params, "name");
  severity = params_value (params, "severity");
  result_hosts_only = params_value (params, "result_hosts_only");

  hosts = params_value (params, "hosts");
  oid = params_value (params, "oid");
  port = params_value (params, "port");
  overrides = params_value (params, "overrides");

  if (result_id == NULL || task_id == NULL)
    {
      xml = g_string_new ("");

      xml_string_append (xml,
                         "<new_override>"
                         "<nvt id=\"%s\"/>"
                         "<next>%s</next>",
                         oid ? oid : "0",
                         next ? next : "");

      if (extra_xml)
        g_string_append (xml, extra_xml);

      if (openvas_connection_sendf (connection,
                                    "<get_tasks"
                                    " schedules_only=\"1\""
                                    " details=\"0\"/>")
          == -1)
        {
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while creating a new override. "
                               "No new override was created. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_overrides", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while creating a new override. "
                               "No new override was created. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_overrides", response_data);
        }

      g_string_append (xml, "</new_override>");
      return xsl_transform_omp (connection, credentials, params,
                                g_string_free (xml, FALSE), response_data);
    }

  if (openvas_connection_sendf (connection,
                                "<get_results"
                                " result_id=\"%s\""
                                " task_id=\"%s\""
                                " notes_details=\"1\""
                                " notes=\"1\""
                                " overrides_details=\"1\""
                                " overrides=\"1\""
                                " result_hosts_only=\"1\"/>",
                                result_id,
                                task_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while creating a new override. "
                           "No new override was created. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_overrides", response_data);
    }

  xml = g_string_new ("");

  xml_string_append (xml,
                     "<new_override>"
                     "<nvt id=\"%s\"/>"
                     "<hosts>%s</hosts>"
                     "<port>%s</port>"
                     "<severity>%s</severity>"
                     "<task id=\"%s\">"
                     "<name>%s</name>"
                     "</task>"
                     "<result id=\"%s\"/>"
                     "<next>%s</next>"
                     /* Passthroughs. */
                     "<report id=\"%s\"/>"
                     "<first_result>%s</first_result>"
                     "<max_results>%s</max_results>"
                     "<sort_field>%s</sort_field>"
                     "<sort_order>%s</sort_order>"
                     "<levels>%s</levels>"
                     "<autofp>%s</autofp>"
                     "<notes>%s</notes>"
                     "<overrides>%s</overrides>"
                     "<result_hosts_only>%s</result_hosts_only>"
                     "<search_phrase>%s</search_phrase>",
                     oid,
                     hosts,
                     /* port is NULL for CVE scan results. */
                     port ? port : "",
                     severity,
                     task_id,
                     task_name,
                     result_id,
                     next ? next : "",
                     report_id,
                     first_result,
                     max_results,
                     sort_field,
                     sort_order,
                     levels,
                     autofp,
                     notes,
                     overrides,
                     result_hosts_only,
                     search_phrase);

  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while creating a new override. "
                           "It is unclear whether the override has been created or not. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_overrides", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</new_override>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the new overrides page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_override_omp (openvas_connection_t *connection, credentials_t *credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  return new_override (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create an override, get report, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_override_omp (openvas_connection_t *connection,
                     credentials_t *credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  char *ret;
  gchar *response;
  const char *no_redirect;
  const char *oid, *severity, *custom_severity, *new_severity, *port, *hosts;
  const char *text, *task_id, *override_result_id;
  /* For get_report. */
  const char *active, *days;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  oid = params_value (params, "oid");
  CHECK_PARAM_INVALID (oid, "Create Override", "new_override");

  if (params_valid (params, "severity"))
    severity = params_value (params, "severity");
  else if (params_given (params, "severity")
           && strcmp (params_original_value (params, "severity"), ""))
    severity = NULL;
  else
    severity = "";
  CHECK_PARAM_INVALID (severity, "Create Override", "new_override");

  custom_severity = params_value (params, "custom_severity");
  CHECK_PARAM_INVALID (custom_severity, "Create Override", "new_override");

  if (custom_severity != NULL && strcmp (custom_severity, "0"))
    {
      if (params_valid (params, "new_severity"))
        new_severity = params_value (params, "new_severity");
      else if (params_original_value (params, "new_severity") == NULL
               || strcmp (params_original_value (params, "new_severity"), ""))
        new_severity = NULL;
      else
        new_severity = "";
      CHECK_PARAM_INVALID (new_severity, "Create Override", "new_override");
    }
  else
    {
      if (params_valid (params, "new_severity_from_list"))
        new_severity = params_value (params, "new_severity_from_list");
      else if (params_original_value (params, "new_severity_from_list") == NULL
               || strcmp (params_original_value (params,
                                                 "new_severity_from_list"),
                          ""))
        new_severity = NULL;
      else
        new_severity = "";
      CHECK_PARAM_INVALID (new_severity, "Create Override", "new_override");
    }

  port = params_value (params, "port");
  if (port == NULL)
    port = "";
  if (strcmp (port, "--") == 0)
    {
      int num = -1;

      port = params_value (params, "port_manual");
      if (port)
        num = atoi (port);
      if (num < 0 || num > 65535)
        port = NULL;
    }
  CHECK_PARAM_INVALID (port, "Create Override", "new_override");

  if (params_valid (params, "hosts"))
    {
      hosts = params_value (params, "hosts");
      if (strcmp (hosts, "--") == 0)
        {
          if (params_valid (params, "hosts_manual"))
            hosts = params_value (params, "hosts_manual");
          else if (params_given (params, "hosts_manual")
                   && strcmp (params_original_value (params, "hosts_manual"),
                              ""))
            hosts = NULL;
          else
            hosts = "";
        }
    }
  else if (strcmp (params_original_value (params, "hosts"), ""))
    hosts = NULL;
  else
    hosts = "";
  CHECK_PARAM_INVALID (hosts, "Create Override", "new_override");

  if (params_valid (params, "override_task_id"))
    {
      task_id = params_value (params, "override_task_id");
      if (task_id && (strcmp (task_id, "0") == 0))
        task_id = params_value (params, "override_task_uuid");
    }
  else
    task_id = "";

  active = params_value (params, "active");
  CHECK_PARAM_INVALID (active, "Create Override", "new_override");

  text = params_value (params, "text");
  days = params_value (params, "days");

  override_result_id = params_value (params, "override_result_id");
  if (override_result_id && (strcmp (override_result_id, "0") == 0))
    override_result_id = params_value (params, "override_result_uuid");

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<create_override>"
                "<active>%s</active>"
                "<nvt oid=\"%s\"/>"
                "<hosts>%s</hosts>"
                "<port>%s</port>"
                "<severity>%s</severity>"
                "<new_severity>%s</new_severity>"
                "<text>%s</text>"
                "<task id=\"%s\"/>"
                "<result id=\"%s\"/>"
                "</create_override>",
                strcmp (active, "1")
                 ? active
                 : (days ? days : "-1"),
                oid,
                hosts,
                port,
                severity,
                new_severity,
                text ? text : "",
                task_id,
                override_result_id))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new override. "
                             "No new override was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_overrides", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new override. "
                             "It is unclear whether the override has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_overrides", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new override. "
                             "It is unclear whether the override has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_overrides", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "override_id", entity_attribute (entity, "id"));
  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_overrides",
                              NULL, "new_override",
                              "Create Override", response_data);
  free_entity (entity);
  g_free (response);
  return ret;
}

/**
 * @brief Delete override, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_override_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  return delete_resource (connection, "override", credentials, params, 0, NULL,
                          response_data);
}

/**
 * @brief Delete a override, get all overrides, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_override_omp (openvas_connection_t *connection,
                           credentials_t * credentials, params_t *params,
                           cmd_response_data_t* response_data)
{
  return delete_resource (connection, "override", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Edit override, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_override (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, const char *extra_xml,
               cmd_response_data_t* response_data)
{
  GString *xml;
  const char *override_id;

  override_id = params_value (params, "override_id");

  if (openvas_connection_sendf (connection,
                                "<get_overrides"
                                " override_id=\"%s\""
                                " details=\"1\""
                                " result=\"1\"/>",
                                override_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing an override. "
                           "The override remains as it was. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_overrides", response_data);
    }

  xml = g_string_new ("");

  xml_string_append (xml, "<edit_override>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing an override. "
                           "The override remains as it was. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_overrides", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</edit_override>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Edit override, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_override_omp (openvas_connection_t *connection, credentials_t *credentials,
                   params_t *params, cmd_response_data_t* response_data)
{
  return edit_override (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Save override, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_override_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  gchar *response;
  entity_t entity;
  const char *no_redirect, *override_id, *text, *hosts, *port;
  const char *severity, *custom_severity, *new_severity;
  const char *override_task_id, *override_result_id, *active, *days;
  char *ret;

  no_redirect = params_value (params, "no_redirect");
  override_id = params_value (params, "override_id");

  text = params_value (params, "text");
  if (text == NULL)
    params_given (params, "text") || (text = "");

  if (params_valid (params, "hosts"))
    hosts = params_value (params, "hosts");
  else if (strcmp (params_original_value (params, "hosts"), ""))
    hosts = NULL;
  else
    hosts = "";

  if (params_valid (params, "port"))
    port = params_value (params, "port");
  else if (strcmp (params_original_value (params, "port"), ""))
    port = NULL;
  else
    port = "";

  if (params_valid (params, "severity"))
    severity = params_value (params, "severity");
  else if (strcmp (params_original_value (params, "severity"), ""))
    severity = NULL;
  else
    severity = "";

  custom_severity = params_value (params, "custom_severity");
  if (custom_severity && strcmp (custom_severity, "0") != 0)
    new_severity = params_value (params, "new_severity");
  else
    new_severity = params_value (params, "new_severity_from_list");

  override_task_id = params_value (params, "override_task_id");
  override_result_id = params_value (params, "override_result_id");

  active = params_value (params, "active");
  days = params_value (params, "days");

  CHECK_PARAM_INVALID (override_task_id, "Save Override", "edit_override");
  CHECK_PARAM_INVALID (override_result_id, "Save Override", "edit_override");
  CHECK_PARAM_INVALID (active, "Save Override", "edit_override");
  CHECK_PARAM_INVALID (override_id, "Save Override", "edit_override");
  CHECK_PARAM_INVALID (text, "Save Override", "edit_override");
  CHECK_PARAM_INVALID (hosts, "Save Override", "edit_override");
  CHECK_PARAM_INVALID (port, "Save Override", "edit_override");
  CHECK_PARAM_INVALID (severity, "Save Override", "edit_override");
  CHECK_PARAM_INVALID (new_severity, "Save Override", "edit_override");
  CHECK_PARAM_INVALID (days, "Save Override", "edit_override");

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<modify_override override_id=\"%s\">"
                "<active>%s</active>"
                "<hosts>%s</hosts>"
                "<port>%s</port>"
                "<severity>%s</severity>"
                "<new_severity>%s</new_severity>"
                "<text>%s</text>"
                "<task id=\"%s\"/>"
                "<result id=\"%s\"/>"
                "</modify_override>",
                override_id,
                strcmp (active, "1")
                 ? active
                 : (days ? days : "-1"),
                hosts ? hosts : "",
                port ? port : "",
                severity ? severity : "",
                new_severity,
                text ? text : "",
                override_task_id,
                override_result_id))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a override. "
                             "The override remains the same. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_overrides", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a override. "
                             "It is unclear whether the override has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_overrides", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a override. "
                             "It is unclear whether the override has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_overrides", response_data);
    }

  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_overrides",
                              NULL, "edit_override",
                              "Save Override", response_data);

  free_entity (entity);
  g_free (response);
  return ret;
}


/* Scanners. */

/**
 * @brief Get all scanners, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_scanners (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, const char *extra_xml,
              cmd_response_data_t* response_data)
{
  return get_many (connection, "scanner", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all scanners, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_scanners_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  return get_scanners (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get one scanner, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_scanner (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  return get_one (connection, "scanner", credentials, params, extra_xml, NULL,
                  response_data);
}

/**
 * @brief Get one scanner, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_scanner_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return get_scanner (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Export a scanner.
 *
 * @param[in]  connection            Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Scanner XML on success.  HTML result of XSL transformation on error.
 */
char *
export_scanner_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    enum content_type * content_type,
                    char **content_disposition, gsize *content_length,
                    cmd_response_data_t* response_data)
{
  return export_resource (connection, "scanner", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of scanners.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Scanners XML on success. HTML result of XSL transformation on error.
 */
char *
export_scanners_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     enum content_type * content_type,
                     char **content_disposition, gsize *content_length,
                     cmd_response_data_t* response_data)
{
  return export_many (connection, "scanner", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Returns page to create a new scanner.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_scanner (openvas_connection_t *connection, credentials_t *credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  GString *xml;

  if (openvas_connection_sendf (connection,
                                "<get_credentials"
                                " filter=\"first=1 rows=-1\" />")
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the credentials list. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  xml = g_string_new ("<new_scanner>");
  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the credentials list. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  g_string_append (xml, "</new_scanner>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the new scanner page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_scanner_omp (openvas_connection_t *connection, credentials_t *credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return new_scanner (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Verify scanner, get scanners, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
verify_scanner_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *scanner_id, *next;
  int ret;
  entity_t entity;

  scanner_id = params_value (params, "scanner_id");
  CHECK_PARAM (scanner_id, "Verify Scanner", get_scanners);


  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<verify_scanner scanner_id=\"%s\"/>",
              scanner_id);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while verifying a scanner. "
                             "The scanner was not verified. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_scanners", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while verifying a scanner. "
                             "It is unclear whether the scanner was verified or not. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_scanners", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while verifying a scanner. "
                             "It is unclear whether the scanner was verified or not. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_scanners", response_data);
    }

  if (omp_success (entity))
    {
      html = next_page (connection, credentials, params, response,
                        response_data);
      if (html == NULL)
        {
          free_entity (entity);
          g_free (response);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while verifying a scanner. "
                               "It is unclear whether the scanner was verified or not. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_scanners", response_data);
        }
    }
  else
    {
      set_http_status_from_entity (entity, response_data);
      next = params_value (params, "next");
      if (next && !strcmp (next, "get_scanner"))
        html = get_scanner (connection, credentials, params, response,
                            response_data);
      else
        html = get_scanners (connection, credentials, params, response,
                             response_data);
    }

  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Create a scanner, get all scanners, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_scanner_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  int ret;
  char *html;
  gchar *response = NULL;
  const char *no_redirect;
  const char *name, *comment, *host, *port, *type, *ca_pub, *credential_id;
  entity_t entity = NULL;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  host = params_value (params, "scanner_host");
  port = params_value (params, "port");
  type = params_value (params, "scanner_type");
  ca_pub = params_value (params, "ca_pub");
  credential_id = params_value (params, "credential_id");
  CHECK_PARAM_INVALID (name, "Create Scanner", "new_scanner");
  CHECK_PARAM_INVALID (comment, "Create Scanner", "new_scanner");
  CHECK_PARAM_INVALID (host, "Create Scanner", "new_scanner");
  CHECK_PARAM_INVALID (port, "Create Scanner", "new_scanner");
  CHECK_PARAM_INVALID (type, "Create Scanner", "new_scanner");
  if (params_given (params, "ca_pub"))
    CHECK_PARAM_INVALID (ca_pub, "Create Scanner", "new_scanner");
  CHECK_PARAM_INVALID (credential_id, "Create Scanner", "new_scanner");

  if (ca_pub)
    ret = ompf (connection, credentials, &response, &entity, response_data,
                "<create_scanner>"
                "<name>%s</name><comment>%s</comment>"
                "<host>%s</host><port>%s</port><type>%s</type>"
                "<ca_pub>%s</ca_pub>"
                "<credential id=\"%s\"/>"
                "</create_scanner>",
                name, comment, host, port, type, ca_pub, credential_id);
  else
    ret = ompf (connection, credentials, &response, &entity, response_data,
                "<create_scanner>"
                "<name>%s</name><comment>%s</comment>"
                "<host>%s</host><port>%s</port><type>%s</type>"
                "<credential id=\"%s\"/>"
                "</create_scanner>",
                name, comment, host, port, type, credential_id);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message
                (credentials, "Internal error", __FUNCTION__, __LINE__,
                 "An internal error occurred while creating a new scanner. "
                 "No new scanner was created. "
                 "Diagnostics: Failure to send command to manager daemon.",
                 "/omp?cmd=get_scanners", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message
                (credentials, "Internal error", __FUNCTION__, __LINE__,
                 "An internal error occurred while creating a new scanner. "
                 "It is unclear whether the scanner has been created or not. "
                 "Diagnostics: Failure to receive response from manager daemon.",
                 "/omp?cmd=get_scanners", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message
                (credentials, "Internal error", __FUNCTION__, __LINE__,
                 "An internal error occurred while creating a new scanner. "
                 "It is unclear whether the scanner has been created or not. "
                 "Diagnostics: Internal Error.",
                 "/omp?cmd=get_scanners", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "scanner_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_scanners",
                               NULL, "new_scanner",
                               "Create Scanner", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Delete a scanner, get all scanners, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_scanner_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  return delete_resource (connection, "scanner", credentials, params, 0,
                          "get_scanners", response_data);
}

/**
 * @brief Delete a trash scanner, get all scanners, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_scanner_omp (openvas_connection_t *connection,
                          credentials_t * credentials, params_t *params,
                          cmd_response_data_t* response_data)
{
  return delete_resource (connection, "scanner", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Setup edit_scanner XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_scanner (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params, const char *extra_xml,
              cmd_response_data_t* response_data)
{
  GString *xml;
  const char *scanner_id, *next;

  scanner_id = params_value (params, "scanner_id");
  next = params_value (params, "next");

  if (scanner_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing a scanner. "
                           "The scanner remains as it was. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (next == NULL)
    next = "get_scanner";

  if (openvas_connection_sendf (connection,
                                "<commands>"
                                "<get_scanners scanner_id=\"%s\" details=\"1\" />"
                                "<get_credentials filter=\"first=1 rows=-1\" />"
                                "</commands>",
                                scanner_id)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting scanner info. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  xml = g_string_new ("");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  g_string_append_printf (xml,
                          "<edit_scanner>"
                          "<scanner id=\"%s\"/>"
                          /* Page that follows. */
                          "<next>%s</next>",
                          scanner_id,
                          next);

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting scanner info. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</edit_scanner>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup edit_scanner XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_scanner_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  return edit_scanner (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Save scanner, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_scanner_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  gchar *response = NULL;
  entity_t entity = NULL;
  const char *no_redirect;
  const char *scanner_id, *name, *comment, *port, *host, *type, *ca_pub;
  const char *credential_id, *which_cert;
  char *html;
  int ret, is_unix_socket, in_use;

  no_redirect = params_value (params, "no_redirect");
  scanner_id = params_value (params, "scanner_id");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  host = params_value (params, "scanner_host");
  is_unix_socket = (host && *host == '/') ? 1 : 0;
  port = params_value (params, "port");
  type = params_value (params, "scanner_type");
  which_cert = params_value (params, "which_cert");
  ca_pub = params_value (params, "ca_pub");
  credential_id = params_value (params, "credential_id");
  CHECK_PARAM_INVALID (scanner_id, "Edit Scanner", "edit_scanner");
  CHECK_PARAM_INVALID (name, "Edit Scanner", "edit_scanner");
  if (params_given (params, "scanner_host") == 0)
    in_use = 1;
  else
   {
     in_use = 0;
     CHECK_PARAM_INVALID (host, "Edit Scanner", "edit_scanner");
     CHECK_PARAM_INVALID (port, "Edit Scanner", "edit_scanner");
     CHECK_PARAM_INVALID (type, "Edit Scanner", "edit_scanner");
   }
  if (is_unix_socket == 0)
    {
      CHECK_PARAM_INVALID (ca_pub, "Edit Scanner", "edit_scanner");
      CHECK_PARAM_INVALID (credential_id, "Edit Scanner", "edit_scanner");
      CHECK_PARAM_INVALID (which_cert, "Edit Scanner", "edit_scanner");
    }

  if (is_unix_socket)
    {
      ret = ompf (connection, credentials, &response, &entity, response_data,
                  "<modify_scanner scanner_id=\"%s\">"
                  "<name>%s</name>"
                  "<comment>%s</comment>"
                  "</modify_scanner>",
                  scanner_id, name, comment ?: "");
    }
  else if (strcmp (which_cert, "new") == 0
           || strcmp (which_cert, "default") == 0)
    {
      if (ca_pub == NULL)
        ca_pub = "";
      if (in_use)
        ret = ompf (connection, credentials, &response, &entity, response_data,
                    "<modify_scanner scanner_id=\"%s\">"
                    "<name>%s</name>"
                    "<comment>%s</comment>"
                    "<ca_pub>%s</ca_pub>"
                    "<credential id=\"%s\"/>"
                    "</modify_scanner>",
                    scanner_id, name, comment ?: "",
                    strcmp (which_cert, "new") == 0 ? ca_pub : "",
                    credential_id);
      else
        ret = ompf (connection, credentials, &response, &entity, response_data,
                    "<modify_scanner scanner_id=\"%s\">"
                    "<name>%s</name>"
                    "<comment>%s</comment>"
                    "<host>%s</host>"
                    "<port>%s</port>"
                    "<type>%s</type>"
                    "<ca_pub>%s</ca_pub>"
                    "<credential id=\"%s\"/>"
                    "</modify_scanner>",
                    scanner_id, name, comment ?: "", host, port, type,
                    strcmp (which_cert, "new") == 0 ? ca_pub : "",
                    credential_id);
    }
  else
    {
      /* Using existing CA cert. */
      if (in_use)
        ret = ompf (connection, credentials, &response, &entity, response_data,
                    "<modify_scanner scanner_id=\"%s\">"
                    "<name>%s</name>"
                    "<comment>%s</comment>"
                    "<credential id=\"%s\"/>"
                    "</modify_scanner>",
                    scanner_id, name, comment ?: "", credential_id);
      else
        ret = ompf (connection, credentials, &response, &entity, response_data,
                    "<modify_scanner scanner_id=\"%s\">"
                    "<name>%s</name>"
                    "<comment>%s</comment>"
                    "<host>%s</host>"
                    "<port>%s</port>"
                    "<type>%s</type>"
                    "<credential id=\"%s\"/>"
                    "</modify_scanner>",
                    scanner_id, name, comment ?: "", host, port, type,
                    credential_id);
    }

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message
                (credentials, "Internal error", __FUNCTION__, __LINE__,
                 "An internal error occurred while saving a scanner. "
                 "The scanner remains the same. "
                 "Diagnostics: Failure to send command to manager daemon.",
                 "/omp?cmd=get_scanners", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message
                (credentials, "Internal error", __FUNCTION__, __LINE__,
                 "An internal error occurred while saving a scanner. "
                 "It is unclear whether the scanner has been saved or not. "
                 "Diagnostics: Failure to receive response from manager daemon.",
                 "/omp?cmd=get_scanners", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message
                (credentials, "Internal error", __FUNCTION__, __LINE__,
                 "An internal error occurred while saving a scanner. "
                 "It is unclear whether the scanner has been saved or not. "
                 "Diagnostics: Internal Error.",
                 "/omp?cmd=get_scanners", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_scanners",
                               NULL, "edit_scanner",
                               "Save Scanner", response_data);

  free_entity (entity);
  g_free (response);
  return html;
}


/* Schedules. */

/**
 * @brief Get one schedule, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_schedule (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params, const char *extra_xml,
              cmd_response_data_t* response_data)
{
  return get_one (connection, "schedule", credentials, params, extra_xml,
                  "tasks=\"1\"", response_data);
}

/**
 * @brief Get one schedule, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_schedule_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  return get_schedule (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all schedules, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_schedules (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, const char *extra_xml,
               cmd_response_data_t* response_data)
{
  return get_many (connection, "schedule", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all schedules, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_schedules_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  return get_schedules (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Returns page to create a new schedule.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_schedule (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, const char *extra_xml,
              cmd_response_data_t* response_data)
{
  GString *xml;
  time_t now;
  struct tm *now_broken;
  xml = g_string_new ("<new_schedule>");
  now = time (NULL);
  now_broken = localtime (&now);
  g_string_append_printf (xml,
                          "<time>"
                          "<minute>%s%i</minute>"
                          "<hour>%s%i</hour>"
                          "<day_of_month>%s%i</day_of_month>"
                          "<month>%s%i</month>"
                          "<year>%i</year>"
                          "</time>",
                          (now_broken->tm_min > 9 ? "" : "0"),
                          now_broken->tm_min,
                          (now_broken->tm_hour > 9 ? "" : "0"),
                          now_broken->tm_hour,
                          (now_broken->tm_mday > 9 ? "" : "0"),
                          now_broken->tm_mday,
                          ((now_broken->tm_mon + 1) > 9 ? "" : "0"),
                          (now_broken->tm_mon + 1),
                          (now_broken->tm_year + 1900));

  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_schedule>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the new schedule page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_schedule_omp (openvas_connection_t *connection, credentials_t *credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  return new_schedule (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create a schedule, get all schedules, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_schedule_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  char *ret;
  gchar *response;
  const char *no_redirect;
  const char *name, *comment, *hour, *minute, *day_of_month, *month, *year;
  const char *period, *period_unit, *duration, *duration_unit, *timezone;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  hour = params_value (params, "hour");
  minute = params_value (params, "minute");
  day_of_month = params_value (params, "day_of_month");
  duration = params_value (params, "duration");
  duration_unit = params_value (params, "duration_unit");
  month = params_value (params, "month");
  period = params_value (params, "period");
  period_unit = params_value (params, "period_unit");
  year = params_value (params, "year");
  timezone = params_value (params, "timezone");

  CHECK_PARAM_INVALID (name, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (comment, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (hour, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (minute, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (day_of_month, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (duration, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (duration_unit, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (month, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (period, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (period_unit, "period_unit", "new_schedule");
  CHECK_PARAM_INVALID (year, "Create Schedule", "new_schedule");
  CHECK_PARAM_INVALID (timezone, "Create Schedule", "new_schedule");

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<create_schedule>"
                "<name>%s</name>"
                "<comment>%s</comment>"
                "<first_time>"
                "<hour>%s</hour>"
                "<minute>%s</minute>"
                "<day_of_month>%s</day_of_month>"
                "<month>%s</month>"
                "<year>%s</year>"
                "</first_time>"
                "<period>"
                "<unit>%s</unit>"
                "%s"
                "</period>"
                "<duration>"
                "<unit>%s</unit>"
                "%s"
                "</duration>"
                "<timezone>%s</timezone>"
                "</create_schedule>",
                name,
                comment,
                hour,
                minute,
                day_of_month,
                month,
                year,
                (strcmp (period_unit, "")
                  ? period_unit
                  : "second"),
                period,
                (strcmp (duration_unit, "")
                  ? duration_unit
                  : "second"),
                duration,
                timezone))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new schedule. "
                             "No new schedule was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_schedules", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new schedule. "
                             "It is unclear whether the schedule has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_schedules", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new schedule. "
                             "It is unclear whether the schedule has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_schedules", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "schedule_id", entity_attribute (entity, "id"));
  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_schedules",
                              NULL, "new_schedule",
                              "Create Schedule", response_data);
  free_entity (entity);
  g_free (response);
  return ret;
}

/**
 * @brief Delete a schedule, get all schedules, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_schedule_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  return delete_resource (connection, "schedule", credentials, params, 0,
                          "get_schedules", response_data);
}

/**
 * @brief Get all system reports, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_system_reports_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  GString *xml;
  time_t now, duration, duration_start;
  struct tm start_time, end_time;

  const char *slave_id, *given_duration, *range_type;
  const char *start_year, *start_month, *start_day, *start_hour, *start_minute;
  const char *end_year, *end_month, *end_day, *end_hour, *end_minute;

  slave_id = params_value (params, "slave_id");

  now = time (NULL);

  given_duration = params_value (params, "duration");
  range_type = params_value (params, "range_type");
  if (!range_type)
    range_type = "duration";

  duration = given_duration ? atoi (given_duration) : 86400;
  duration_start = now - duration;

  xml = g_string_new ("<get_system_reports>");

  g_string_append_printf (xml,
                          "<slave id=\"%s\"/>",
                          slave_id ? slave_id : "0");
  if (strcmp (range_type, "duration") == 0)
    {
      struct tm *time_broken;
      time_broken = localtime (&now);
      end_time.tm_year = time_broken->tm_year;
      end_time.tm_mon = time_broken->tm_mon;
      end_time.tm_mday = time_broken->tm_mday;
      end_time.tm_hour = time_broken->tm_hour;
      end_time.tm_min = time_broken->tm_min;

      time_broken = localtime (&duration_start);
      start_time.tm_year = time_broken->tm_year;
      start_time.tm_mon = time_broken->tm_mon;
      start_time.tm_mday = time_broken->tm_mday;
      start_time.tm_hour = time_broken->tm_hour;
      start_time.tm_min = time_broken->tm_min;

      g_string_append_printf (xml,
                              "<duration>%ld</duration>",
                              duration);
    }
  else
    {
      struct tm *time_broken;
      time_broken = localtime (&now);

      start_year = params_value (params, "start_year");
      start_month = params_value (params, "start_month");
      start_day = params_value (params, "start_day");
      start_hour = params_value (params, "start_hour");
      start_minute = params_value (params, "start_minute");

      end_year = params_value (params, "end_year");
      end_month = params_value (params, "end_month");
      end_day = params_value (params, "end_day");
      end_hour = params_value (params, "end_hour");
      end_minute = params_value (params, "end_minute");

      start_time.tm_year = start_year ? atoi (start_year) - 1900
                                      : time_broken->tm_year;
      start_time.tm_mon = start_month ? atoi (start_month) - 1
                                      : time_broken->tm_mon;
      start_time.tm_mday = start_day ? atoi (start_day)
                                     : time_broken->tm_mday;
      start_time.tm_hour = start_hour ? atoi (start_hour)
                                      : time_broken->tm_hour;
      start_time.tm_min = start_minute ? atoi (start_minute)
                                       : time_broken->tm_min;

      end_time.tm_year = end_year ? atoi (end_year) - 1900
                                  : time_broken->tm_year;
      end_time.tm_mon = end_month ? atoi (end_month) - 1
                                  : time_broken->tm_mon;
      end_time.tm_mday = end_day ? atoi (end_day)
                                 : time_broken->tm_mday;
      end_time.tm_hour = end_hour ? atoi (end_hour)
                                  : time_broken->tm_hour;
      end_time.tm_min = end_minute ? atoi (end_minute)
                                   : time_broken->tm_min;
    }

  g_string_append_printf (xml,
                          "<start_time>"
                          "<minute>%i</minute>"
                          "<hour>%i</hour>"
                          "<day_of_month>%i</day_of_month>"
                          "<month>%i</month>"
                          "<year>%i</year>"
                          "</start_time>",
                          start_time.tm_min,
                          start_time.tm_hour,
                          start_time.tm_mday,
                          start_time.tm_mon + 1,
                          start_time.tm_year + 1900);

  g_string_append_printf (xml,
                          "<end_time>"
                          "<minute>%i</minute>"
                          "<hour>%i</hour>"
                          "<day_of_month>%i</day_of_month>"
                          "<month>%i</month>"
                          "<year>%i</year>"
                          "</end_time>",
                          end_time.tm_min,
                          end_time.tm_hour,
                          end_time.tm_mday,
                          end_time.tm_mon + 1,
                          end_time.tm_year + 1900);

  /* Get the system reports. */

  if (openvas_connection_sendf (connection,
                                "<get_system_reports brief=\"1\" slave_id=\"%s\"/>",
                                slave_id ? slave_id : "0")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the system reports. "
                           "The current list of system reports is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the system reports. "
                           "The current list of system reports is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (command_enabled (credentials, "GET_SCANNERS"))
    {
      /* Get the OMP scanners. */

      if (openvas_connection_sendf (connection,
                                    "<get_scanners"
                                    " filter=\"sort=name rows=-1 type=4\"/>")
          == -1)
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the system reports. "
                               "The current list of system reports is not available. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }

      if (read_string_c (connection, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting the system reports. "
                               "The current list of system reports is not available. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</get_system_reports>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return system report image.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Credentials of user issuing the action.
 * @param[in]   url                  URL of report image.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Image, or NULL.
 */
char *
get_system_report_omp (openvas_connection_t *connection,
                       credentials_t *credentials, const char *url,
                       params_t *params,
                       enum content_type *content_type,
                       gsize *content_length,
                       cmd_response_data_t* response_data)
{
  entity_t entity;
  entity_t report_entity;
  char name[501];
  time_t now;
  struct tm *now_broken;
  const char *slave_id, *duration;
  const char *start_year, *start_month, *start_day, *start_hour, *start_minute;
  const char *end_year, *end_month, *end_day, *end_hour, *end_minute;
  struct tm start_time, end_time;
  gchar *start_time_str, *end_time_str;
  gchar *omp_command;

  *content_length = 0;

  if (url == NULL)
    return NULL;

  slave_id = params_value (params, "slave_id");

  /* fan/report.png */
  if (sscanf (url, "%500[^ /]./report.png", name) == 1)
    {
      duration = params_value (params, "duration");

      if (duration && strcmp (duration, ""))
        {
          omp_command = g_markup_printf_escaped ("<get_system_reports"
                                                 " name=\"%s\""
                                                 " duration=\"%s\""
                                                 " slave_id=\"%s\"/>",
                                                 name,
                                                 duration,
                                                 slave_id ? slave_id : "0");
        }
      else
        {
          now = time (NULL);
          now_broken = localtime (&now);

          start_year = params_value (params, "start_year");
          start_month = params_value (params, "start_month");
          start_day = params_value (params, "start_day");
          start_hour = params_value (params, "start_hour");
          start_minute = params_value (params, "start_minute");

          end_year = params_value (params, "end_year");
          end_month = params_value (params, "end_month");
          end_day = params_value (params, "end_day");
          end_hour = params_value (params, "end_hour");
          end_minute = params_value (params, "end_minute");

          start_time.tm_year = start_year ? atoi (start_year) - 1900
                                          : now_broken->tm_year;
          start_time.tm_mon = start_month ? atoi (start_month) - 1
                                          : now_broken->tm_mon;
          start_time.tm_mday = start_day ? atoi (start_day)
                                         : now_broken->tm_mday;
          start_time.tm_hour = start_hour ? atoi (start_hour)
                                          : now_broken->tm_hour;
          start_time.tm_min = start_minute ? atoi (start_minute)
                                           : now_broken->tm_min;
          start_time.tm_zone = now_broken->tm_zone;

          end_time.tm_year = end_year ? atoi (end_year) - 1900
                                        : now_broken->tm_year;
          end_time.tm_mon = end_month ? atoi (end_month) - 1
                                        : now_broken->tm_mon;
          end_time.tm_mday = end_day ? atoi (end_day) : now_broken->tm_mday;
          end_time.tm_hour = end_hour ? atoi (end_hour) : now_broken->tm_hour;
          end_time.tm_min = end_minute ? atoi (end_minute) : now_broken->tm_min;
          end_time.tm_zone = now_broken->tm_zone;



          start_time_str
          = g_strdup_printf ("%04d-%02d-%02dT%02d:%02d:00",
                              start_time.tm_year + 1900,
                              start_time.tm_mon + 1,
                              start_time.tm_mday,
                              start_time.tm_hour,
                              start_time.tm_min);

          end_time_str
          = g_strdup_printf ("%04d-%02d-%02dT%02d:%02d:00",
                              end_time.tm_year + 1900,
                              end_time.tm_mon + 1,
                              end_time.tm_mday,
                              end_time.tm_hour,
                              end_time.tm_min);

          omp_command
          = g_markup_printf_escaped ("<get_system_reports"
                                      " name=\"%s\""
                                      " start_time=\"%s\""
                                      " end_time=\"%s\""
                                      " slave_id=\"%s\"/>",
                                      name,
                                      start_time_str,
                                      end_time_str,
                                      slave_id ? slave_id : "0");
          g_free (start_time_str);
          g_free (end_time_str);
        }

      if (openvas_connection_sendf (connection,
                                    "%s",
                                    omp_command)
          == -1)
        {
          g_free (omp_command);
          return NULL;
        }
      g_free (omp_command);

      entity = NULL;
      if (read_entity_c (connection, &entity))
        {
          return NULL;
        }

      report_entity = entity_child (entity, "system_report");
      if (report_entity == NULL)
        {
          free_entity (entity);
          return NULL;
        }

      report_entity = entity_child (report_entity, "report");
      if (report_entity == NULL)
        {
          free_entity (entity);
          return NULL;
        }
      else
        {
          char *content_64 = entity_text (report_entity);
          char *content = NULL;

          if (content_64 && strlen (content_64))
            {
              content = (char *) g_base64_decode (content_64,
                                                  content_length);

#if 1
              *content_type = GSAD_CONTENT_TYPE_IMAGE_PNG;
              //*content_disposition = g_strdup_printf ("attachment; filename=\"xxx.png\"");
#else
              g_free (content);
              content = g_strdup ("helo");
#endif
            }

          free_entity (entity);
          return content;
       }
    }

  return NULL;
}

/**
 * @brief Get one report format, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_report_format (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   const char *extra_xml, cmd_response_data_t* response_data)
{
  return get_one (connection, "report_format", credentials, params, extra_xml,
                  "alerts =\"1\" params=\"1\"", response_data);
}

/**
 * @brief Get one report format, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_report_format_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  return get_report_format (connection, credentials, params, NULL,
                            response_data);
}

/**
 * @brief Get all Report Formats, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_report_formats (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    const char *extra_xml, cmd_response_data_t* response_data)
{
  return get_many (connection, "report_format", credentials, params, extra_xml,
                   NULL, response_data);
}

/**
 * @brief Get all Report Formats, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_report_formats_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  return get_report_formats (connection, credentials, params, NULL,
                             response_data);
}

/**
 * @brief Returns page to create a new report format.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_report_format (openvas_connection_t *connection, credentials_t *credentials,
                   params_t *params, const char *extra_xml,
                   cmd_response_data_t* response_data)
{
  GString *xml;
  xml = g_string_new ("<new_report_format>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_report_format>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the new report format page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_report_format_omp (openvas_connection_t *connection,
                       credentials_t *credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  return new_report_format (connection, credentials, params, NULL,
                            response_data);
}

/**
 * @brief Delete report format, get report formats, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_report_format_omp (openvas_connection_t *connection,
                          credentials_t * credentials, params_t *params,
                          cmd_response_data_t* response_data)
{
  return delete_resource (connection, "report_format", credentials, params, 0,
                          "get_report_formats", response_data);
}

/**
 * @brief Setup edit_report_format XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
edit_report_format (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    const char *extra_xml, cmd_response_data_t* response_data)
{
  gchar *all_rfs_response, *response, *ext_extra_xml;

  if (simple_ompf (connection, "getting Report Formats",
                   credentials, &all_rfs_response, response_data,
                   "<get_report_formats"
                   " filter=\"rows=-1\"/>"))
    {
      return all_rfs_response;
    }

  ext_extra_xml = g_strdup_printf ("%s"
                                   "<all_formats>%s</all_formats>",
                                   extra_xml ? extra_xml : "",
                                   all_rfs_response);
  g_free (all_rfs_response);

  response = edit_resource (connection, "report_format", credentials, params,
                            NULL, ext_extra_xml, response_data);
  g_free (ext_extra_xml);
  return response;
}

/**
 * @brief Setup edit_report_format XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_report_format_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  return edit_report_format (connection, credentials, params, NULL,
                             response_data);
}

/**
 * @brief Import report format, get all report formats, XSL transform result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
import_report_format_omp (openvas_connection_t *connection,
                          credentials_t * credentials, params_t *params,
                          cmd_response_data_t* response_data)
{
  const char* no_redirect;
  gchar *command, *html, *response;
  entity_t entity;
  int ret;

  no_redirect = params_value (params, "no_redirect");

  /* Create the report format. */

  response = NULL;
  entity = NULL;
  command = g_strdup_printf ("<create_report_format>"
                             "%s"
                             "</create_report_format>",
                             params_value (params, "xml_file"));
  ret = omp (connection, credentials, &response, &entity, response_data,
             command);
  g_free (command);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while importing a report format. "
                             "The schedule remains the same. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_report_formats", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while importing a report format. "
                             "It is unclear whether the schedule has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_report_formats", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while importing a report format. "
                             "It is unclear whether the schedule has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_report_formats", response_data);
    }

  /* Cleanup, and return transformed XML. */

  if (entity_attribute (entity, "id"))
    params_add (params, "report_format_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_report_formats",
                               NULL, "new_report_format",
                               "Create Report Format", response_data);

  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Save report_format, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_report_format_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  params_t *preferences, *id_list_params, *include_id_lists;
  const char *no_redirect, *report_format_id, *name, *summary, *enable;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  report_format_id = params_value (params, "report_format_id");
  name = params_value (params, "name");
  summary = params_value (params, "summary");
  enable = params_value (params, "enable");

  CHECK_PARAM_INVALID (report_format_id, "Save Report Format",
                        "edit_report_format");
  CHECK_PARAM_INVALID (name, "Save Report Format", "edit_report_format");
  CHECK_PARAM_INVALID (summary, "Save Report Format", "edit_report_format");
  CHECK_PARAM_INVALID (enable, "Save Report Format", "edit_report_format");

  id_list_params = params_values (params, "id_list:");
  include_id_lists = params_values (params, "include_id_list:");
  if (include_id_lists)
    {
      GHashTable *id_lists;
      param_t *param;
      gchar *param_name, *pref_name, *value, *old_values, *new_values;
      params_iterator_t iter;
      GHashTableIter hash_table_iter;

      id_lists = g_hash_table_new_full (g_str_hash, g_str_equal,
                                        g_free, g_free);

      params_iterator_init (&iter, include_id_lists);
      while (params_iterator_next (&iter, &param_name, &param))
        {
          if (param->value == NULL)
            continue;

          g_hash_table_insert (id_lists, g_strdup (param_name), g_strdup (""));
        }

      params_iterator_init (&iter, id_list_params);
      while (params_iterator_next (&iter, &param_name, &param))
        {
          if (param->value == NULL)
            continue;

          gchar *colon_pos = strchr (param->value, ':');

          pref_name = g_strndup (param->value, colon_pos - param->value);
          value = g_strdup (colon_pos + 1);

          old_values = g_hash_table_lookup (id_lists, pref_name);

          if (old_values && strcmp (old_values, ""))
            {
              new_values = g_strdup_printf ("%s,%s", old_values, value);
              g_hash_table_insert (id_lists, pref_name, new_values);
              g_free (value);
            }
          else if (old_values)
            {
              g_hash_table_insert (id_lists, pref_name, value);
            }
        }

      g_hash_table_iter_init (&hash_table_iter, id_lists);
      while (g_hash_table_iter_next (&hash_table_iter,
                                     (void**)&pref_name, (void**)&value))
        {
          gchar *value_64;

          value_64 = strlen (value)
                      ? g_base64_encode ((guchar *) value, strlen (value))
                      : g_strdup ("");

          response = NULL;
          entity = NULL;
          ret = ompf (connection, credentials,
                      &response,
                      &entity,
                      response_data,
                      "<modify_report_format"
                      " report_format_id=\"%s\">"
                      "<param>"
                      "<name>%s</name>"
                      "<value>%s</value>"
                      "</param>"
                      "</modify_report_format>",
                      report_format_id,
                      pref_name,
                      value_64);
          g_free (value_64);
          switch (ret)
            {
              case 0:
                break;
              case 1:
                response_data->http_status_code
                  = MHD_HTTP_INTERNAL_SERVER_ERROR;
                return gsad_message (credentials,
                                      "Internal error", __FUNCTION__, __LINE__,
                                      "An internal error occurred while saving a Report Format. "
                                      "The Report Format was not saved. "
                                      "Diagnostics: Failure to send command to manager daemon.",
                                      "/omp?cmd=get_report_formats",
                                      response_data);
              case 2:
                response_data->http_status_code
                  = MHD_HTTP_INTERNAL_SERVER_ERROR;
                return gsad_message (credentials,
                                      "Internal error", __FUNCTION__, __LINE__,
                                      "An internal error occurred while saving a Report Format. "
                                      "It is unclear whether the Report Format has been saved or not. "
                                      "Diagnostics: Failure to receive response from manager daemon.",
                                      "/omp?cmd=get_report_formats",
                                      response_data);
              case -1:
              default:
                response_data->http_status_code
                  = MHD_HTTP_INTERNAL_SERVER_ERROR;
                return gsad_message (credentials,
                                      "Internal error", __FUNCTION__, __LINE__,
                                      "An internal error occurred while saving a Report Format. "
                                      "It is unclear whether the Report Format has been saved or not. "
                                      "Diagnostics: Internal Error.",
                                      "/omp?cmd=get_report_formats",
                                      response_data);
            }

          /* TODO Check if succeeded.  response_from_entity_if_failed? */
        }
    }

  /* Modify the Report Format. */

  preferences = params_values (params, "preference:");
  if (preferences)
    {
      param_t *param;
      gchar *param_name;
      params_iterator_t iter;

      /* The naming is a bit subtle here, because the HTTP request
       * parameters are called "param"s and so are the OMP report format
       * parameters. */

      params_iterator_init (&iter, preferences);
      while (params_iterator_next (&iter, &param_name, &param))
        {
          int type_start, type_end, count;
          /* LDAPsearch[entry]:Timeout value */
          count = sscanf (param_name,
                          "%*[^[][%n%*[^]]%n]:",
                          &type_start,
                          &type_end);
          if (count == 0 && type_start > 0 && type_end > 0)
            {
              gchar *value;

              value = param->value_size
                      ? g_base64_encode ((guchar *) param->value,
                                         param->value_size)
                      : g_strdup ("");

              response = NULL;
              entity = NULL;
              ret = ompf (connection, credentials,
                          &response,
                          &entity,
                          response_data,
                          "<modify_report_format"
                          " report_format_id=\"%s\">"
                          "<param>"
                          "<name>%s</name>"
                          "<value>%s</value>"
                          "</param>"
                          "</modify_report_format>",
                          report_format_id,
                          param_name + type_end + 2,
                          value);
              g_free (value);
              switch (ret)
                {
                  case 0:
                    break;
                  case 1:
                    response_data->http_status_code
                      = MHD_HTTP_INTERNAL_SERVER_ERROR;
                    return gsad_message (credentials,
                                         "Internal error", __FUNCTION__, __LINE__,
                                         "An internal error occurred while saving a Report Format. "
                                         "The Report Format was not saved. "
                                         "Diagnostics: Failure to send command to manager daemon.",
                                         "/omp?cmd=get_report_formats",
                                         response_data);
                  case 2:
                    response_data->http_status_code
                      = MHD_HTTP_INTERNAL_SERVER_ERROR;
                    return gsad_message (credentials,
                                         "Internal error", __FUNCTION__, __LINE__,
                                         "An internal error occurred while saving a Report Format. "
                                         "It is unclear whether the Report Format has been saved or not. "
                                         "Diagnostics: Failure to receive response from manager daemon.",
                                         "/omp?cmd=get_report_formats",
                                         response_data);
                  case -1:
                  default:
                    response_data->http_status_code
                      = MHD_HTTP_INTERNAL_SERVER_ERROR;
                    return gsad_message (credentials,
                                         "Internal error", __FUNCTION__, __LINE__,
                                         "An internal error occurred while saving a Report Format. "
                                         "It is unclear whether the Report Format has been saved or not. "
                                         "Diagnostics: Internal Error.",
                                         "/omp?cmd=get_report_formats",
                                         response_data);
                }

              /* TODO Check if succeeded.  response_from_entity_if_failed? */
            }
         }
    }

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<modify_report_format"
              " report_format_id=\"%s\">"
              "<name>%s</name>"
              "<summary>%s</summary>"
              "<active>%s</active>"
              "</modify_report_format>",
              report_format_id,
              name,
              summary,
              enable);

  switch (ret)
    {
      case 0:
        break;
      case -1:
        return response;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a Report Format. "
                             "The Report Format was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_report_formats", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a Report Format. "
                             "It is unclear whether the Report Format has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_report_formats", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a Report Format. "
                             "It is unclear whether the Report Format has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_report_formats", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_report_formats",
                               NULL, "edit_report_format",
                               "Save Report Format", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Verify report format, get report formats, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
verify_report_format_omp (openvas_connection_t *connection,
                          credentials_t * credentials, params_t *params,
                          cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *report_format_id;
  entity_t entity;

  report_format_id = params_value (params, "report_format_id");
  if (report_format_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while verifying a report format. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_report_formats", response_data);
    }

  /* Verify the report format. */

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<verify_report_format report_format_id=\"%s\"/>",
              report_format_id);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while verifying a report format. "
                             "The report format was not verified. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_report_formats", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while verifying a report format. "
                             "It is unclear whether the report format was verified or not. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_report_formats", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while verifying a report format. "
                             "It is unclear whether the report format was verified or not. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_report_formats", response_data);
    }

  if (omp_success (entity))
    {
      html = next_page (connection, credentials, params, response,
                        response_data);
      if (html == NULL)
        {
          free_entity (entity);
          g_free (response);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while verifying a report format. "
                               "It is unclear whether the report format was verified or not. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_report_formats", response_data);
        }
    }
  else
    {
      set_http_status_from_entity (entity, response_data);
      html = get_report_formats (connection, credentials, params, response,
                                 response_data);
    }
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Run a wizard and XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
run_wizard_omp (openvas_connection_t *connection, credentials_t *credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  const char *no_redirect, *name;
  int ret;
  GString *run;
  param_t *param;
  gchar *param_name, *html, *response;
  params_iterator_t iter;
  params_t *wizard_params;
  entity_t entity;

  /* The naming is a bit subtle here, because the HTTP request
   * parameters are called "param"s and so are the OMP wizard
   * parameters. */

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  if (name == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while trying to start a wizard. "
                           "Diagnostics: Required parameter 'name' was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }
  run = g_string_new ("<run_wizard>");

  g_string_append_printf (run,
                          "<name>%s</name>"
                          "<params>",
                          name);

  wizard_params = params_values (params, "event_data:");
  if (wizard_params)
    {
      params_iterator_init (&iter, wizard_params);
      while (params_iterator_next (&iter, &param_name, &param))
        xml_string_append (run,
                           "<param>"
                           "<name>%s</name>"
                           "<value>%s</value>"
                           "</param>",
                           param_name,
                           param->value);
    }

  g_string_append (run, "</params></run_wizard>");

  response = NULL;
  entity = NULL;
  ret = omp (connection, credentials, &response, &entity, response_data,
             run->str);
  g_string_free (run, TRUE);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while running a wizard. "
                             "The wizard did not start. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while running a wizard. "
                             "It is unclear whether the wizard started or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while running a wizard. "
                             "It is unclear whether the wizard started or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "wizard",
                               NULL, "wizard",
                               "Run Wizard", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

#define GET_TRASH_RESOURCE(capability, command, name)                         \
  if (command_enabled (credentials, capability))                              \
      {                                                                       \
        if (openvas_connection_sendf                                          \
             (connection,                                                     \
              "<" command                                                     \
              " filter=\"rows=-1 sort=name\""                                 \
              " trash=\"1\"/>")                                               \
            == -1)                                                            \
          {                                                                   \
            g_string_free (xml, TRUE);                                        \
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR; \
            return gsad_message                                               \
                    (credentials,                                             \
                     "Internal error", __FUNCTION__, __LINE__,                \
                     "An internal error occurred while getting "              \
                     name " list for trash."                                  \
                     "Diagnostics: Failure to send command to"                \
                     " manager daemon.",                                      \
                     "/omp?cmd=get_trash", response_data);                    \
          }                                                                   \
                                                                              \
        if (read_string_c (connection, &xml))                                 \
          {                                                                   \
            g_string_free (xml, TRUE);                                        \
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR; \
            return gsad_message                                               \
                    (credentials,                                             \
                     "Internal error", __FUNCTION__, __LINE__,                \
                     "An internal error occurred while getting " name " list."\
                     "Diagnostics: Failure to receive response from"          \
                     " manager daemon.",                                      \
                     "/omp?cmd=get_tasks", response_data);                    \
          }                                                                   \
      }

/**
 * @brief Setup trash page XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_trash (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  GString *xml;

  xml = g_string_new ("<get_trash>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  GET_TRASH_RESOURCE ("GET_AGENTS", "get_agents", "agents");

  GET_TRASH_RESOURCE ("GET_CONFIGS", "get_configs", "configs");

  GET_TRASH_RESOURCE ("GET_CREDENTIALS", "get_credentials", "credentials");

  GET_TRASH_RESOURCE ("GET_ALERTS", "get_alerts", "alerts");

  GET_TRASH_RESOURCE ("GET_GROUPS", "get_groups", "groups");

  GET_TRASH_RESOURCE ("GET_FILTERS", "get_filters", "filters");

  GET_TRASH_RESOURCE ("GET_NOTES", "get_notes", "notes");

  GET_TRASH_RESOURCE ("GET_OVERRIDES", "get_overrides", "overrides");

  GET_TRASH_RESOURCE ("GET_PERMISSIONS", "get_permissions", "permissions");

  GET_TRASH_RESOURCE ("GET_PORT_LISTS", "get_port_lists", "port lists");

  GET_TRASH_RESOURCE ("GET_REPORT_FORMATS", "get_report_formats",
                      "report formats");

  GET_TRASH_RESOURCE ("GET_ROLES", "get_roles", "roles");

  GET_TRASH_RESOURCE ("GET_SCANNERS", "get_scanners", "scanners");

  GET_TRASH_RESOURCE ("GET_SCHEDULES", "get_schedules", "schedules");

  GET_TRASH_RESOURCE ("GET_TAGS", "get_tags", "tags");

  GET_TRASH_RESOURCE ("GET_TARGETS", "get_targets", "targets");

  GET_TRASH_RESOURCE ("GET_TASKS", "get_tasks", "tasks");

  /* Cleanup, and return transformed XML. */

  g_string_append (xml, "</get_trash>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}
#undef GET_TRASH_RESOURCE

/**
 * @brief Get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_trash_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return get_trash (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Returns page with user's settings.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_my_settings (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, const char *extra_xml,
                 cmd_response_data_t* response_data)
{
  GString *xml;

  xml = g_string_new ("<get_my_settings>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  /* Get the settings. */

  if (openvas_connection_sendf (connection,
                                "<get_settings"
                                " sort_field=\"name\""
                                " sort_order=\"ascending\"/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the settings. "
                           "The current list of settings is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the settings. "
                           "The current list of settings is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  buffer_languages_xml (xml);

  g_string_append (xml, "</get_my_settings>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page with user's settings.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_my_settings_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  GString *commands;
  int ret;
  entity_t entity;
  gchar *response;

  commands = g_string_new ("<commands>");
  if (command_enabled (credentials, "GET_ALERTS"))
    g_string_append (commands, "<get_alerts/>");
  if (command_enabled (credentials, "GET_CONFIGS"))
    g_string_append (commands, "<get_configs/>");
  if (command_enabled (credentials, "GET_FILTERS"))
    g_string_append (commands, "<get_filters/>");
  if (command_enabled (credentials, "GET_CREDENTIALS"))
    g_string_append (commands, "<get_credentials/>");
  if (command_enabled (credentials, "GET_PORT_LISTS"))
    g_string_append (commands, "<get_port_lists/>");
  if (command_enabled (credentials, "GET_REPORT_FORMATS"))
    g_string_append (commands, "<get_report_formats/>");
  if (command_enabled (credentials, "GET_SCANNERS"))
    g_string_append (commands, "<get_scanners/>");
  if (command_enabled (credentials, "GET_SCHEDULES"))
    g_string_append (commands, "<get_schedules/>");
  if (command_enabled (credentials, "GET_TARGETS"))
    g_string_append (commands, "<get_targets/>");
  g_string_append (commands, "</commands>");

  /* Get Filters and other resource lists. */
  response = NULL;
  entity = NULL;
  ret = omp (connection, credentials, &response, &entity, response_data,
             commands->str);
  g_string_free (commands, TRUE);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting resources "
                             "for the settings. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_my_settings", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting resources "
                             "for the settings. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_alerts", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting resources "
                             "for the settings. "
                             "It is unclear whether the task has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_alerts", response_data);
    }
  free_entity (entity);

  return get_my_settings (connection, credentials, params, response,
                          response_data);
}

/**
 * @brief Returns page with user's settings, for editing.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
edit_my_settings (openvas_connection_t *connection,
                  credentials_t * credentials, params_t *params,
                  const char *extra_xml, cmd_response_data_t* response_data)
{
  GString *commands, *xml;
  int ret;
  gchar *filters_xml;
  entity_t entity;

  /* Get the Filters and other resources. */
  commands = g_string_new ("<commands>");
  if (command_enabled (credentials, "GET_ALERTS"))
    g_string_append (commands, "<get_alerts/>");
  if (command_enabled (credentials, "GET_CONFIGS"))
    g_string_append (commands, "<get_configs/>");
  if (command_enabled (credentials, "GET_CREDENTIALS"))
    g_string_append (commands, "<get_credentials/>");
  if (command_enabled (credentials, "GET_FILTERS"))
    g_string_append (commands, "<get_filters/>");
  if (command_enabled (credentials, "GET_PORT_LISTS"))
    g_string_append (commands, "<get_port_lists/>");
  if (command_enabled (credentials, "GET_REPORT_FORMAT"))
    g_string_append (commands, "<get_report_formats/>");
  if (command_enabled (credentials, "GET_SCANNERS"))
    g_string_append (commands, "<get_scanners/>");
  if (command_enabled (credentials, "GET_SCHEDULES"))
    g_string_append (commands, "<get_schedules/>");
  if (command_enabled (credentials, "GET_TARGETS"))
    g_string_append (commands, "<get_targets/>");
  g_string_append (commands, "</commands>");

  filters_xml = NULL;
  entity = NULL;
  ret = omp (connection, credentials, &filters_xml, &entity, response_data,
             commands->str);
  g_string_free (commands, TRUE);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting resources "
                             "for the settings. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_my_settings", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting resources "
                             "for the alert. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_my_settings", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting resources "
                             "for the settings. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_my_settings", response_data);
    }
  free_entity (entity);

  xml = g_string_new ("<edit_my_settings>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  g_string_append (xml, filters_xml);
  g_free (filters_xml);

  /* Get the settings. */

  if (openvas_connection_sendf (connection,
                                "<get_settings"
                                " sort_field=\"name\""
                                " sort_order=\"ascending\"/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the settings. "
                           "The current list of settings is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_my_settings", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the settings. "
                           "The current list of settings is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_my_settings", response_data);
    }

  buffer_languages_xml (xml);

  g_string_append (xml, "</edit_my_settings>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page with user's settings, for editing.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_my_settings_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      cmd_response_data_t* response_data)
{
  return edit_my_settings (connection, credentials, params, NULL,
                           response_data);
}

/**
 * @brief Send settings resource filters.
 *
 * @param[in]   connection          Connection to Manager.
 * @param[in]   data                Data.
 * @param[in]   changed             Params indicating which settings changed.
 * @param[out]  xml                 GString to write responses to.
 * @param[out]  modify_failed_flag  Pointer to an int to set to 1 on failure
 *                                  to modify one of the settings.
 * @return 0 on success, -1 on error.
 */
static int
send_settings_filters (openvas_connection_t *connection, params_t *data,
                       params_t *changed, GString *xml, int *modify_failed_flag,
                       cmd_response_data_t* response_data)
{
  if (data)
    {
      params_iterator_t iter;
      char *uuid;
      param_t *param;
      entity_t entity;

      params_iterator_init (&iter, data);
      while (params_iterator_next (&iter, &uuid, &param))
        {
          const char* changed_value = params_value (changed, uuid);
          if (changed_value == NULL
              || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
            {
              gchar *base64;
              if (param->value)
                base64 = g_base64_encode ((guchar*) param->value,
                                          strlen (param->value));
              else
                base64 = g_strdup("");
              if (openvas_connection_sendf_xml (connection,
                                                "<modify_setting setting_id=\"%s\">"
                                                "<value>%s</value>"
                                                "</modify_setting>",
                                                uuid,
                                                base64))
                {
                  g_free (base64);
                  return -1;
                }

              g_free (base64);

              entity = NULL;
              xml_string_append (xml,
                                 "<save_setting id=\"%s\">",
                                 uuid);
              if (read_entity_and_string_c (connection, &entity, &xml))
                {
                  free_entity (entity);
                  return -1;
                }
              xml_string_append (xml, "</save_setting>");
              if (! omp_success (entity))
                {
                  set_http_status_from_entity (entity, response_data);
                  if (modify_failed_flag)
                    *modify_failed_flag = 1;
                }
              free_entity(entity);
            }
        }
    }
  return 0;
}

/**
 * @brief Returns page with user's settings, for editing.
 *
 * @param[in]  connection       Connection to manager
 * @param[in]  credentials      Credentials of user issuing the action.
 * @param[in]  params           Request parameters.
 * @param[in]  accept_language  Accept-Language, from browser.
 * @param[out] timezone         Timezone.  Caller must free.
 * @param[out] password         Password.  Caller must free.
 * @param[out] severity         Severity.  Caller must free.
 * @param[out] language         Language.  Caller must free.
 * @param[out] response_data    Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_my_settings_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      const char *accept_language, char **timezone,
                      char **password, char **severity, char **language,
                      cmd_response_data_t* response_data)
{
  const char *lang, *text, *old_passwd, *passwd, *status, *max;
  const char *details_fname, *list_fname, *report_fname;
  gchar *lang_64, *text_64, *max_64, *fname_64;
  GString *xml;
  entity_t entity;
  params_t *changed, *defaults, *filters;
  int modify_failed = 0;
  const char *changed_value;

  changed = params_values (params, "settings_changed:");
  *timezone = NULL;
  *password = NULL;
  *severity = NULL;
  *language = NULL;

  text = params_value (params, "text");
  old_passwd = params_value (params, "old_password");
  passwd = params_value (params, "password");
  max = params_value (params, "max");
  lang = params_value (params, "lang");
  details_fname = params_value (params, "details_fname");
  list_fname = params_value (params, "list_fname");
  report_fname = params_value (params, "report_fname");
  if ((text == NULL)
      || (passwd == NULL)
      || (old_passwd == NULL)
      || (max == NULL)
      || (lang == NULL)
      || (details_fname == NULL)
      || (list_fname == NULL)
      || (report_fname == NULL))
    return edit_my_settings (connection, credentials, params,
                             GSAD_MESSAGE_INVALID_PARAM
                               ("Save My Settings"),
                             response_data);

  xml = g_string_new ("");

  changed_value = params_value (changed, "password");
  if ((strlen (passwd) || strlen (old_passwd))
      && (changed_value == NULL
          || (strcmp (changed_value, "") && strcmp (changed_value, "0"))))
    {
      gchar *passwd_64;
      omp_authenticate_info_opts_t auth_opts;

      /* Send Password setting */

      auth_opts = omp_authenticate_info_opts_defaults;
      auth_opts.username = credentials->username;
      auth_opts.password = old_passwd;
      switch (omp_authenticate_info_ext_c (connection, auth_opts))
        {
          case 0:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while saving settings. "
                                 "The settings remains the same. "
                                 "Diagnostics: Manager closed connection during authenticate.",
                                 "/omp?cmd=get_my_settings", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
            return gsad_message (credentials,
                                 "Invalid Password", __FUNCTION__, __LINE__,
                                 "You tried to change your password, but the old"
                                 " password was not provided or was incorrect. "
                                 " Please enter the correct old password or remove"
                                 " old and new passwords to apply any other changes"
                                 " of your settings.",
                                 "/omp?cmd=get_my_settings", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred while saving settings. "
                                 "The settings remains the same. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_my_settings", response_data);
        }

      passwd_64 = g_base64_encode ((guchar*) passwd, strlen (passwd));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting>"
                                    "<name>Password</name>"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    passwd_64 ? passwd_64 : "")
          == -1)
        {
          g_free (passwd_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (passwd_64);

      entity = NULL;
      xml_string_append (xml, "<save_setting name=\"Password\">");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");

      status = entity_attribute (entity, "status");
      if (status && (strlen (status) > 0) && (status[0] == '2'))
        {
          g_free (credentials->password);
          credentials->password = g_strdup (passwd);
          *password = g_strdup (passwd);
        }
      else
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send Timezone */
  changed_value = params_value (changed, "timezone");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      text_64 = g_base64_encode ((guchar*) text, strlen (text));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting>"
                                    "<name>Timezone</name>"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    text_64 ? text_64 : "")
          == -1)
        {
          g_free (text_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (text_64);

      entity = NULL;
      xml_string_append (xml, "<save_setting name=\"Timezone\">");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");

      status = entity_attribute (entity, "status");
      if (status && (strlen (status) > 0) && (status[0] == '2'))
        {
          g_free (credentials->timezone);
          credentials->timezone = g_strdup (strlen (text) ? text : "UTC");
          *timezone = g_strdup (strlen (text) ? text : "UTC");

          /* Set the timezone, so that the ENVELOPE/TIME
           * uses the right timezone. */

          if (setenv ("TZ", credentials->timezone, 1) == -1)
            {
              g_critical ("%s: failed to set TZ\n", __FUNCTION__);
              exit (EXIT_FAILURE);
            }
          tzset ();
        }
      else
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send Rows Per Page */
  changed_value = params_value (changed, "max");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      max_64 = g_base64_encode ((guchar*) max, strlen (max));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting"
                                    " setting_id"
                                    "=\"5f5a8712-8017-11e1-8556-406186ea4fc5\">"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    max_64 ? max_64 : "")
          == -1)
        {
          g_free (max_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (max_64);

      entity = NULL;
      xml_string_append (xml,
                         "<save_setting id=\"%s\">",
                         "5f5a8712-8017-11e1-8556-406186ea4fc5");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");
      if (! omp_success (entity))
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send resource details export file name format. */
  changed_value = params_value (changed, "details_fname");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      fname_64 = g_base64_encode ((guchar*) details_fname, strlen (details_fname));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting"
                                    " setting_id"
                                    "=\"a6ac88c5-729c-41ba-ac0a-deea4a3441f2\">"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    fname_64 ? fname_64 : "")
          == -1)
        {
          g_free (fname_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (fname_64);

      entity = NULL;
      xml_string_append (xml,
                         "<save_setting id=\"%s\">",
                         "a6ac88c5-729c-41ba-ac0a-deea4a3441f2");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");
      if (omp_success (entity) != 1)
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send resource list export file name format. */
  changed_value = params_value (changed, "list_fname");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      fname_64 = g_base64_encode ((guchar*) list_fname, strlen (list_fname));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting"
                                    " setting_id"
                                    "=\"0872a6ed-4f85-48c5-ac3f-a5ef5e006745\">"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    fname_64 ? fname_64 : "")
          == -1)
        {
          g_free (fname_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (fname_64);

      entity = NULL;
      xml_string_append (xml,
                         "<save_setting id=\"%s\">",
                         "a6ac88c5-729c-41ba-ac0a-deea4a3441f2");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");
      if (omp_success (entity) != 1)
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send report export file name format. */
  changed_value = params_value (changed, "report_fname");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      fname_64 = g_base64_encode ((guchar*) report_fname, strlen (report_fname));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting"
                                    " setting_id"
                                    "=\"e1a2ae0b-736e-4484-b029-330c9e15b900\">"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    fname_64 ? fname_64 : "")
          == -1)
        {
          g_free (fname_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (fname_64);

      entity = NULL;
      xml_string_append (xml,
                         "<save_setting id=\"%s\">",
                         "e1a2ae0b-736e-4484-b029-330c9e15b900");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");
      if (omp_success (entity) != 1)
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send User Interface Language. */
  changed_value = params_value (changed, "lang");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      lang_64 = g_base64_encode ((guchar*) lang, strlen (lang));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting"
                                    " setting_id"
                                    "=\"6765549a-934e-11e3-b358-406186ea4fc5\">"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    lang_64 ? lang_64 : "")
          == -1)
        {
          g_free (lang_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (lang_64);

      entity = NULL;
      xml_string_append (xml,
                         "<save_setting id=\"%s\">",
                         "6765549a-934e-11e3-b358-406186ea4fc5");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");
      if (omp_success (entity))
        {
          gchar *language_code;
          set_language_code (&language_code, lang);
          if (language_code)
            {
              g_free (credentials->language);
              credentials->language = language_code;
              *language = g_strdup (lang);
            }
          else
            {
              g_free (credentials->language);
              credentials->language = accept_language_to_env_fmt (accept_language);
              *language = NULL;
            }
        }
      else
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send default resources */

  defaults = params_values (params, "settings_default:");
  if (send_settings_filters (connection, defaults, changed, xml,
                             &modify_failed, response_data))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while saving settings. "
                           "It is unclear whether all the settings were saved. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_my_settings", response_data);
    }

  /* Send resources filters */

  filters = params_values (params, "settings_filter:");
  if (send_settings_filters (connection, filters, changed, xml, &modify_failed,
                             response_data))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while saving settings. "
                           "It is unclear whether all the settings were saved. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_my_settings", response_data);
    }

  /* Send Severity Class. */

  changed_value = params_value (changed, "severity_class");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      text = params_value (params, "severity_class");
      text_64 = (text
                    ? g_base64_encode ((guchar*) text, strlen (text))
                    : g_strdup (""));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting"
                                    " setting_id"
                                    "=\"f16bb236-a32d-4cd5-a880-e0fcf2599f59\">"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    text_64 ? text_64 : "")
          == -1)
        {
          g_free (text_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (text_64);

      entity = NULL;
      xml_string_append (xml,
                         "<save_setting id=\"%s\">",
                         "f16bb236-a32d-4cd5-a880-e0fcf2599f59");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");

      status = entity_attribute (entity, "status");
      if (status && (strlen (status) > 0) && (status[0] == '2'))
        {
          g_free (credentials->severity);
          if ((text != NULL) && (strlen (text) > 0))
            {
              credentials->severity = g_strdup (text);
              *severity = g_strdup (text);
            }
        }
      else
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send Dynamic Severity setting. */

  changed_value = params_value (changed, "dynamic_severity");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      text = params_value (params, "dynamic_severity");
      text_64 = (text
                    ? g_base64_encode ((guchar*) text, strlen (text))
                    : g_strdup (""));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting"
                                    " setting_id"
                                    "=\"77ec2444-e7f2-4a80-a59b-f4237782d93f\">"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    text_64 ? text_64 : "")
          == -1)
        {
          g_free (text_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (text_64);

      entity = NULL;
      xml_string_append (xml,
                         "<save_setting id=\"%s\">",
                         "77ec2444-e7f2-4a80-a59b-f4237782d93f");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");
      if (! omp_success (entity))
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send Default Severity setting. */
  changed_value = params_value (changed, "default_severity");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      text = params_value (params, "default_severity");
      text_64 = (text
                    ? g_base64_encode ((guchar*) text, strlen (text))
                    : g_strdup (""));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting"
                                    " setting_id"
                                    "=\"7eda49c5-096c-4bef-b1ab-d080d87300df\">"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    text_64 ? text_64 : "")
          == -1)
        {
          g_free (text_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                              "Internal error", __FUNCTION__, __LINE__,
                              "An internal error occurred while saving settings. "
                              "It is unclear whether all the settings were saved. "
                              "Diagnostics: Failure to send command to manager daemon.",
                              "/omp?cmd=get_my_settings", response_data);
        }
      g_free (text_64);

      entity = NULL;
      xml_string_append (xml,
                         "<save_setting id=\"%s\">",
                         "7eda49c5-096c-4bef-b1ab-d080d87300df");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");
      if (! omp_success (entity))
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  /* Send Auto Cache Rebuild setting. */

  changed_value = params_value (changed, "auto_cache_rebuild");
  if (changed_value == NULL
      || (strcmp (changed_value, "") && strcmp (changed_value, "0")))
    {
      text = params_value (params, "auto_cache_rebuild");
      text_64 = (text
                    ? g_base64_encode ((guchar*) text, strlen (text))
                    : g_strdup (""));

      if (openvas_connection_sendf (connection,
                                    "<modify_setting"
                                    " setting_id"
                                    "=\"a09285b0-2d47-49b6-a4ef-946ee71f1d5c\">"
                                    "<value>%s</value>"
                                    "</modify_setting>",
                                    text_64 ? text_64 : "")
          == -1)
        {
          g_free (text_64);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to send command to manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      g_free (text_64);

      entity = NULL;
      xml_string_append (xml,
                         "<save_setting id=\"%s\">",
                         "a09285b0-2d47-49b6-a4ef-946ee71f1d5c");
      if (read_entity_and_string_c (connection, &entity, &xml))
        {
          g_string_free (xml, TRUE);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while saving settings. "
                               "It is unclear whether all the settings were saved. "
                               "Diagnostics: Failure to receive response from manager daemon.",
                               "/omp?cmd=get_my_settings", response_data);
        }
      xml_string_append (xml, "</save_setting>");
      if (! omp_success (entity))
        {
          set_http_status_from_entity (entity, response_data);
          modify_failed = 1;
        }
    }

  if (modify_failed)
    return edit_my_settings (connection, credentials, params,
                             g_string_free (xml, FALSE), response_data);
  else
    return get_my_settings (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Get OMP doc.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_protocol_doc_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      cmd_response_data_t* response_data)
{
  GString *xml;
  entity_t help_response;

  xml = g_string_new ("");
  g_string_append_printf (xml, "<get_protocol_doc>");

  /* Get the resource. */

  if (openvas_connection_sendf (connection, "<help format=\"XML\"/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the OMP doc. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  help_response = NULL;
  if (read_entity_and_string_c (connection, &help_response, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the OMP doc. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }
  free_entity (help_response);

  /* Cleanup, and return transformed XML. */

  g_string_append_printf (xml, "</get_protocol_doc>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Download the OMP doc.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return XML on success.  HTML result of XSL transformation on error.
 */
char *
export_omp_doc_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    enum content_type * content_type,
                    char **content_disposition, gsize *content_length,
                    cmd_response_data_t* response_data)
{
  entity_t entity, response;
  char *content = NULL;
  const char *format;
  time_t now;
  struct tm *tm;

  *content_length = 0;

  format = params_value (params, "protocol_format")
            ? params_value (params, "protocol_format")
            : "xml";

  if (openvas_connection_sendf (connection,
                                "<help format=\"%s\"/>",
                                format)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting a list. "
                           "The list could not be delivered. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_protocol_doc", response_data);
    }

  response = NULL;
  if (read_entity_and_text_c (connection, &response, &content))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting OMP doc. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_protocol_doc", response_data);
    }

  if (strcmp (format, "xml") == 0)
    *content_length = strlen (content);
  else
    {
      char *content_64;
      entity = entity_child (response, "schema");
      if (entity == NULL)
        {
          free_entity (response);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting OMP doc. "
                               "Diagnostics: Schema element missing.",
                               "/omp?cmd=get_protocol_doc", response_data);
        }

      content_64 = entity_text (entity);
      if (strlen (content_64) == 0)
        {
          free_entity (response);
          response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while getting OMP doc. "
                               "Diagnostics: Schema empty.",
                               "/omp?cmd=get_protocol_doc", response_data);
        }

      content = (char *) g_base64_decode (content_64, content_length);
    }

  now = time (NULL);
  tm = localtime (&now);
  *content_type = GSAD_CONTENT_TYPE_APP_XML;
  *content_disposition = g_strdup_printf ("attachment;"
                                          " filename=\"omp-%d-%d-%d.%s\"",
                                          tm->tm_mday,
                                          tm->tm_mon + 1,
                                          tm->tm_year +1900,
                                          format);
  free_entity (response);
  return content;
}


/* Groups. */

/**
 * @brief Get one group, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_group (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  return get_one (connection, "group", credentials, params, extra_xml, NULL,
                  response_data);
}

/**
 * @brief Get one group, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_group_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return get_group (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all groups, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_groups (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  return get_many (connection, "group", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all groups, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_groups_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return get_groups (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Returns page to create a new group.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_group (openvas_connection_t *connection, credentials_t *credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  GString *xml;
  xml = g_string_new ("<new_group>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_group>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to create a new group.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_group_omp (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return new_group (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Delete a group from trash, get all groups, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_group_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  return delete_resource (connection, "group", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a group, get all groups, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_group_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  return delete_resource (connection, "group", credentials, params, 0,
                          "get_groups", response_data);
}

/**
 * @brief Create a group, get all groups, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_group_omp (openvas_connection_t *connection, credentials_t *credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  gchar *html, *response, *command, *specials_element;
  const char *no_redirect, *name, *comment, *users, *grant_full;
  entity_t entity;
  GString *xml;
  int ret;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  grant_full = params_value (params, "grant_full");
  users = params_value (params, "users");

  CHECK_PARAM_INVALID (name, "Create Group", "new_group");
  CHECK_PARAM_INVALID (comment, "Create Group", "new_group");
  CHECK_PARAM_INVALID (users, "Create Group", "new_group");

  /* Create the group. */

  xml = g_string_new ("");

  xml_string_append (xml,
                     "<name>%s</name>"
                     "<comment>%s</comment>"
                     "<users>%s</users>",
                     name,
                     comment,
                     users);

  if (grant_full)
    specials_element = g_strdup_printf ("<full/>");
  else
    specials_element = NULL;

  command = g_strdup_printf ("<create_group>"
                             "%s"
                             "<specials>"
                             "%s"
                             "</specials>"
                             "</create_group>",
                             xml->str,
                             specials_element);

  g_string_free (xml, TRUE);
  g_free (specials_element);

  ret = omp (connection, credentials, &response, &entity, response_data,
             command);
  g_free (command);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new group. "
                            "No new group was created. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_groups", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new group. "
                            "It is unclear whether the group has been created or not. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_groups", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new group. "
                            "It is unclear whether the group has been created or not. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=get_groups", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "group_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_groups",
                               NULL, "new_group",
                               "Create Group", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Setup edit_group XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_group (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  return edit_resource (connection, "group", credentials, params, NULL,
                        extra_xml, response_data);
}

/**
 * @brief Setup edit_group XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_group_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return edit_group (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Export a group.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Group XML on success.  HTML result of XSL transformation on error.
 */
char *
export_group_omp (openvas_connection_t *connection,
                  credentials_t * credentials, params_t *params,
                  enum content_type * content_type, char **content_disposition,
                  gsize *content_length, cmd_response_data_t* response_data)
{
  return export_resource (connection, "group", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of groups.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Groups XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_groups_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   enum content_type * content_type, char **content_disposition,
                   gsize *content_length, cmd_response_data_t* response_data)
{
  return export_many (connection, "group", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Modify a group, return the next page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_group_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect, *group_id, *name, *comment, *users;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  group_id = params_value (params, "group_id");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  users = params_value (params, "users");

  CHECK_PARAM_INVALID (group_id, "Save Group", "edit_group");
  CHECK_PARAM_INVALID (name, "Save Group", "edit_group");
  CHECK_PARAM_INVALID (comment, "Save Group", "edit_group");
  CHECK_PARAM_INVALID (users, "Save Group", "edit_group");

  /* Modify the Group. */

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<modify_group group_id=\"%s\">"
              "<name>%s</name>"
              "<comment>%s</comment>"
              "<users>%s</users>"
              "</modify_group>",
              group_id,
              name,
              comment,
              users);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a group. "
                             "The group was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_groups", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a group. "
                             "It is unclear whether the group has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_groups", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a group. "
                             "It is unclear whether the group has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_groups", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_groups",
                               NULL, "edit_group",
                               "Save Group", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}


/* Permissions. */

/**
 * @brief Get one permission, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_permission (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, const char *extra_xml,
                cmd_response_data_t* response_data)
{
  return get_one (connection, "permission", credentials, params, extra_xml,
                  "alerts=\"1\"", response_data);
}

/**
 * @brief Get one permission, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_permission_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  return get_permission (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all permissions, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_permissions (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, const char *extra_xml,
                 cmd_response_data_t* response_data)
{
  return get_many (connection, "permission", credentials, params, extra_xml,
                   NULL, response_data);
}

/**
 * @brief Get all permissions, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_permissions_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  return get_permissions (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Delete a permission, get all permissions, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_permission_omp (openvas_connection_t *connection,
                             credentials_t * credentials, params_t *params,
                             cmd_response_data_t* response_data)
{
  return delete_resource (connection, "permission", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a permission, get all permissions, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_permission_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  return delete_resource (connection, "permission", credentials, params, 0,
                          NULL, response_data);
}

/**
 * @brief Setup new_permission XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_permission (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, const char *extra_xml,
                cmd_response_data_t* response_data)
{
  GString *xml;

  xml = g_string_new ("<new_permission>");

  if (command_enabled (credentials, "GET_USERS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_users filter=\"rows=-1 permission=get_users\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_GROUPS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_groups filter=\"rows=-1 permission=get_groups\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_ROLES"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_roles filter=\"rows=-1 permission=get_roles\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  if (extra_xml)
    g_string_append (xml, extra_xml);

  g_string_append (xml, "</new_permission>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup new_permission XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_permission_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  return new_permission (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create a permission, get all permissions, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_permission_omp (openvas_connection_t *connection,
                       credentials_t *credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect, *name, *comment, *resource_id, *resource_type;
  const char *subject_id, *subject_type, *subject_name;
  entity_t entity;

  gchar *subject_response;
  entity_t get_subject_entity = NULL;
  entity_t subject_entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "permission");
  comment = params_value (params, "comment");
  resource_id = params_value (params, "id_or_empty");
  resource_type = params_value (params, "optional_resource_type");
  subject_type = params_value (params, "subject_type");
  subject_name = params_value (params, "subject_name");

  CHECK_PARAM_INVALID (name, "Create Permission", "new_permission");
  CHECK_PARAM_INVALID (comment, "Create Permission", "new_permission");
  if (params_given (params, "id_or_empty"))
    CHECK_PARAM_INVALID (resource_id, "Create Permission", "new_permission");
  CHECK_PARAM_INVALID (subject_type, "Create Permission", "new_permission");
  if (params_given (params, "optional_resource_type"))
    CHECK_PARAM_INVALID (resource_type, "Create Permission", "new_permission");

  if (params_given (params, "subject_name"))
    {
      CHECK_PARAM_INVALID (subject_name,
                            "Create Permission", "new_permission");
      subject_id = NULL;
      ret = ompf (connection, credentials,
                  &subject_response,
                  &get_subject_entity,
                  response_data,
                  "<get_%ss filter=\"rows=1 name=%s\">"
                  "</get_%ss>",
                  subject_type,
                  subject_name,
                  subject_type);

      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting"
                                " the subject for a permission. "
                                "The permission was not created. "
                                "Diagnostics: Failure to send command"
                                " to manager daemon.",
                                "/omp?cmd=get_permissions", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting"
                                " the subject for a permission. "
                                "The permission was not created. "
                                "Diagnostics: Failure to receive response"
                                " from manager daemon.",
                                "/omp?cmd=get_permissions", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting"
                                " the subject for a permission. "
                                "The permission was not created. "
                                "Diagnostics: Internal Error.",
                                "/omp?cmd=get_permissions", response_data);
        }

      subject_entity = entity_child (get_subject_entity, subject_type);

      if (subject_entity)
        subject_id = entity_attribute (subject_entity, "id");

      if (subject_id == NULL)
        {
          gchar *msg;
          msg = g_strdup_printf ("<gsad_msg status_text=\"Subject not found\""
                                 "          operation=\"create_permission\">"
                                 "Could not find a %s with name '%s'."
                                 "</gsad_msg>",
                                 subject_type,
                                 subject_name ? subject_name : "");
          return next_page (connection, credentials, params, msg,
                            response_data);
        }
    }
  else if (strcmp (subject_type, "user") == 0)
    subject_id = params_value (params, "permission_user_id");
  else if (strcmp (subject_type, "group") == 0)
    subject_id = params_value (params, "permission_group_id");
  else if (strcmp (subject_type, "role") == 0)
    subject_id = params_value (params, "permission_role_id");
  else
    subject_id = NULL;
  CHECK_PARAM_INVALID (subject_id, "Create Permission", "new_permission");

  /* Create the permission(s). */

  if (strcmp (name, "task_proxy") == 0)
    {
      response = NULL;
      entity = NULL;
      ret = ompf (connection, credentials,
                  &response,
                  &entity,
                  response_data,
                  "<commands>"
                  "<create_permission>"
                  "<name>get_tasks</name>"
                  "<comment>%s</comment>"
                  "<resource id=\"%s\"/>"
                  "<subject id=\"%s\"><type>%s</type></subject>"
                  "</create_permission>"
                  "<create_permission>"
                  "<name>modify_task</name>"
                  "<comment>%s</comment>"
                  "<resource id=\"%s\"/>"
                  "<subject id=\"%s\"><type>%s</type></subject>"
                  "</create_permission>"
                  "<create_permission>"
                  "<name>start_task</name>"
                  "<comment>%s</comment>"
                  "<resource id=\"%s\"/>"
                  "<subject id=\"%s\"><type>%s</type></subject>"
                  "</create_permission>"
                  "<create_permission>"
                  "<name>stop_task</name>"
                  "<comment>%s</comment>"
                  "<resource id=\"%s\"/>"
                  "<subject id=\"%s\"><type>%s</type></subject>"
                  "</create_permission>"
                  "<create_permission>"
                  "<name>resume_task</name>"
                  "<comment>%s</comment>"
                  "<resource id=\"%s\"/>"
                  "<subject id=\"%s\"><type>%s</type></subject>"
                  "</create_permission>"
                  "</commands>",
                  comment ? comment : "",
                  resource_id ? resource_id : "",
                  subject_id,
                  subject_type,
                  comment ? comment : "",
                  resource_id ? resource_id : "",
                  subject_id,
                  subject_type,
                  comment ? comment : "",
                  resource_id ? resource_id : "",
                  subject_id,
                  subject_type,
                  comment ? comment : "",
                  resource_id ? resource_id : "",
                  subject_id,
                  subject_type,
                  comment ? comment : "",
                  resource_id ? resource_id : "",
                  subject_id,
                  subject_type);

      if (get_subject_entity)
        free_entity (get_subject_entity);

      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while creating a permission. "
                                "The permission was not created. "
                                "Diagnostics: Failure to send command to manager daemon.",
                                "/omp?cmd=get_permissions", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while creating a permission. "
                                "It is unclear whether the permission has been created or not. "
                                "Diagnostics: Failure to receive response from manager daemon.",
                                "/omp?cmd=get_permissions", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while creating a permission. "
                                "It is unclear whether the permission has been created or not. "
                                "Diagnostics: Internal Error.",
                                "/omp?cmd=get_permissions", response_data);
        }

        if (entity_attribute (entity, "id"))
          params_add (params, "permission_id", entity_attribute (entity, "id"));
        html = response_from_entity (connection, credentials, params, entity,
                                     (no_redirect && strcmp (no_redirect, "0")),
                                     NULL, "get_permissions",
                                     NULL, "new_permission",
                                     "Create Permission", response_data);
    }
  else
    {
      response = NULL;
      entity = NULL;
      ret = ompf (connection, credentials,
                  &response,
                  &entity,
                  response_data,
                  "<create_permission>"
                  "<name>%s</name>"
                  "<comment>%s</comment>"
                  "<resource id=\"%s\">"
                  "<type>%s</type>"
                  "</resource>"
                  "<subject id=\"%s\"><type>%s</type></subject>"
                  "</create_permission>",
                  name,
                  comment ? comment : "",
                  resource_id ? resource_id : "",
                  resource_type ? resource_type : "",
                  subject_id,
                  subject_type);

      if (get_subject_entity)
        free_entity (get_subject_entity);

      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while creating a permission. "
                                "The permission was not created. "
                                "Diagnostics: Failure to send command to manager daemon.",
                                "/omp?cmd=get_permissions", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while creating a permission. "
                                "It is unclear whether the permission has been created or not. "
                                "Diagnostics: Failure to receive response from manager daemon.",
                                "/omp?cmd=get_permissions", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while creating a permission. "
                                "It is unclear whether the permission has been created or not. "
                                "Diagnostics: Internal Error.",
                                "/omp?cmd=get_permissions", response_data);
        }

        if (entity_attribute (entity, "id"))
          params_add (params, "permission_id", entity_attribute (entity, "id"));
        html = response_from_entity (connection, credentials, params, entity,
                                     (no_redirect && strcmp (no_redirect, "0")),
                                     NULL, "get_permissions",
                                     NULL, "new_permission",
                                     "Create Permission", response_data);
    }
  free_entity (entity);
  g_free (response);
  return html;
}

#define CHECK_OMPF_RET \
  switch (ret)                                                                \
    {                                                                         \
      case 0:                                                                 \
      case -1:                                                                \
        break;                                                                \
      case 1:                                                                 \
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;     \
        return gsad_message (credentials,                                                    \
                            "Internal error", __FUNCTION__, __LINE__,                        \
                            "An internal error occurred while creating a permission. "       \
                            "The permission was not created. "                               \
                            "Diagnostics: Failure to send command to manager daemon.",       \
                            "/omp?cmd=get_permissions", response_data);                      \
      case 2:                                                                                \
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;                    \
        return gsad_message (credentials,                                                    \
                            "Internal error", __FUNCTION__, __LINE__,                        \
                            "An internal error occurred while creating a permission. "       \
                            "It is unclear whether the permission has been created or not. " \
                            "Diagnostics: Failure to receive response from manager daemon.", \
                            "/omp?cmd=get_permissions", response_data);                      \
      default:                                                                               \
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;                    \
        return gsad_message (credentials,                                                    \
                            "Internal error", __FUNCTION__, __LINE__,                        \
                            "An internal error occurred while creating a permission. "       \
                            "It is unclear whether the permission has been created or not. " \
                            "Diagnostics: Internal Error.",                                  \
                            "/omp?cmd=get_permissions", response_data);                      \
    }                                                                         \
  if (omp_success (entity))                                                   \
    {                                                                         \
      successes ++;                                                           \
      free_entity (entity);                                                   \
      g_free (response);                                                      \
    }                                                                         \
  else                                                                        \
    {                                                                         \
      html                                                                    \
        = response_from_entity (connection, credentials, params, entity,      \
                                (no_redirect && strcmp (no_redirect, "0")),   \
                                NULL, "get_permissions",                      \
                                NULL, "new_permissions",                      \
                                "Create Permissions", response_data);         \
      free_entity (entity);                                                   \
      g_free (response);                                                      \
      return html;                                                            \
    }                                                                         \

/**
 * @brief Setup new_permissions XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_permissions (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, const char *extra_xml,
                 cmd_response_data_t* response_data)
{
  GString *xml;
  const char *resource_id, *restrict_type;
  params_t *related;
  params_iterator_t related_iterator;
  param_t *related_param;
  char *related_id;

  xml = g_string_new ("<new_permissions>");

  if (command_enabled (credentials, "GET_USERS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_users filter=\"rows=-1 permission=get_users\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_GROUPS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_groups filter=\"rows=-1 permission=get_groups\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_ROLES"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_roles filter=\"rows=-1 permission=get_roles\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  resource_id = params_value (params, "resource_id");
  restrict_type = params_value (params, "restrict_type");
  if (resource_id && restrict_type)
    {
      gchar *get_command;
      gchar *response;
      entity_t entity;

      get_command = g_strdup_printf ("get_%ss", restrict_type);
      response = NULL;
      entity = NULL;
      switch (ompf (connection, credentials, &response, &entity, response_data,
                    "<%s %s_id=\"%s\" details=\"0\"/>",
                    get_command, restrict_type, resource_id))
        {
          case 0:
          case -1:
            break;
          case 1:
            g_free (get_command);
            response_data->http_status_code
              = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting a resource. "
                                 "No new permission was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            g_free (get_command);
            response_data->http_status_code
              = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting a resource. "
                                 "No new permission was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            g_free (get_command);
            response_data->http_status_code
              = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting a resource. "
                                 "No new permission was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }
      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  related = params_values (params, "related:");
  if (related)
    {
      params_iterator_init (&related_iterator, related);
    }

  while (related
         && params_iterator_next (&related_iterator,
                                  &related_id, &related_param))
    {
      const char* related_type;
      gchar *get_command;
      gchar *response;
      entity_t entity;

      related_type = related_param->value;

      get_command = g_strdup_printf ("get_%ss", related_type);
      response = NULL;
      entity = NULL;
      switch (ompf (connection, credentials, &response, &entity, response_data,
                    "<%s %s_id=\"%s\" details=\"0\"/>",
                    get_command, related_type, related_id))
        {
          case 0:
          case -1:
            break;
          case 1:
            g_free (get_command);
            response_data->http_status_code
              = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting a resource. "
                                 "No new permission was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            g_free (get_command);
            response_data->http_status_code
              = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting a resource. "
                                 "No new permission was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            g_free (get_command);
            response_data->http_status_code
              = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting a resource. "
                                 "No new permission was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }
      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  if (extra_xml)
    g_string_append (xml, extra_xml);

  g_string_append (xml, "</new_permissions>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup new_permission XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_permissions_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  return new_permissions (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create multiple permission, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_permissions_omp (openvas_connection_t *connection,
                        credentials_t *credentials, params_t *params,
                        cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response, *summary_response, *next_url;
  int successes;
  const char *no_redirect, *permission, *comment, *resource_id, *resource_type;
  const char *subject_id, *subject_type, *subject_name;
  int include_related;

  entity_t entity;

  gchar *subject_response;
  entity_t get_subject_entity = NULL;
  entity_t subject_entity;

  no_redirect = params_value (params, "no_redirect");
  permission = params_value (params, "permission");
  comment = params_value (params, "comment");
  resource_id = params_value (params, "resource_id");
  resource_type = params_value (params, "resource_type");
  subject_type = params_value (params, "subject_type");
  subject_name = params_value (params, "subject_name");

  include_related = atoi (params_value (params, "include_related"));
  CHECK_PARAM (params_value (params, "include_related"),
               "Create Permission", new_permission);

  CHECK_PARAM (permission, "Create Permission", new_permission);
  CHECK_PARAM (comment, "Create Permission", new_permission);
  CHECK_PARAM (resource_id, "Create Permission", new_permission);
  CHECK_PARAM (subject_type, "Create Permission", new_permission);
  CHECK_PARAM (resource_type, "Create Permission", new_permission);

  if (params_given (params, "subject_name"))
    {
      CHECK_PARAM (subject_name, "Create Permission", new_permission);
      subject_id = NULL;
      ret = ompf (connection, credentials,
                  &subject_response,
                  &get_subject_entity,
                  response_data,
                  "<get_%ss filter=\"rows=1 name=%s\">"
                  "</get_%ss>",
                  subject_type,
                  subject_name,
                  subject_type);

      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting"
                                " the subject for a permission. "
                                "The permission was not created. "
                                "Diagnostics: Failure to send command"
                                " to manager daemon.",
                                "/omp?cmd=get_permissions", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting"
                                " the subject for a permission. "
                                "The permission was not created. "
                                "Diagnostics: Failure to receive response"
                                " from manager daemon.",
                                "/omp?cmd=get_permissions", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting"
                                " the subject for a permission. "
                                "The permission was not created. "
                                "Diagnostics: Internal Error.",
                                "/omp?cmd=get_permissions", response_data);
        }

      subject_entity = entity_child (get_subject_entity, subject_type);

      if (subject_entity)
        subject_id = entity_attribute (subject_entity, "id");

      if (subject_id == NULL)
        {
          gchar *msg;
          msg = g_strdup_printf ("<gsad_msg status_text=\"Subject not found\""
                                 "          operation=\"create_permission\">"
                                 "Could not find a %s with name '%s'."
                                 "</gsad_msg>",
                                 subject_type,
                                 subject_name ? subject_name : "");
          return next_page (connection, credentials, params, msg,
                            response_data);
        }
    }
  else if (strcmp (subject_type, "user") == 0)
    subject_id = params_value (params, "permission_user_id");
  else if (strcmp (subject_type, "group") == 0)
    subject_id = params_value (params, "permission_group_id");
  else if (strcmp (subject_type, "role") == 0)
    subject_id = params_value (params, "permission_role_id");
  else
    subject_id = NULL;
  CHECK_PARAM (subject_id, "Create Permission", new_permission);

  successes = 0;

  /* Create the permission(s). */

  // Main resource permissions
  if (include_related != 2)
    {
      if (strcmp (permission, "read") == 0
          || strcmp (permission, "proxy") == 0)
        {
          response = NULL;
          entity = NULL;
          ret = ompf (connection, credentials,
                      &response,
                      &entity,
                      response_data,
                      "<create_permission>"
                      "<name>get_%ss</name>"
                      "<comment>%s</comment>"
                      "<resource id=\"%s\">"
                      "</resource>"
                      "<subject id=\"%s\"><type>%s</type></subject>"
                      "</create_permission>",
                      resource_type,
                      comment ? comment : "",
                      resource_id,
                      subject_id,
                      subject_type);

          CHECK_OMPF_RET
        }

      if ((strcmp (permission, "proxy") == 0)
          && strcmp (resource_type, "result")
          && strcmp (resource_type, "report"))
        {
          response = NULL;
          entity = NULL;
          ret = ompf (connection, credentials,
                      &response,
                      &entity,
                      response_data,
                      "<create_permission>"
                      "<name>modify_%s</name>"
                      "<comment>%s</comment>"
                      "<resource id=\"%s\">"
                      "</resource>"
                      "<subject id=\"%s\"><type>%s</type></subject>"
                      "</create_permission>",
                      resource_type,
                      comment ? comment : "",
                      resource_id,
                      subject_id,
                      subject_type);

          CHECK_OMPF_RET

          if (strcmp (resource_type, "task") == 0)
            {
              response = NULL;
              entity = NULL;
              ret = ompf (connection, credentials,
                          &response,
                          &entity,
                          response_data,
                          "<create_permission>"
                          "<name>start_%s</name>"
                          "<comment>%s</comment>"
                          "<resource id=\"%s\">"
                          "</resource>"
                          "<subject id=\"%s\"><type>%s</type></subject>"
                          "</create_permission>",
                          resource_type,
                          comment ? comment : "",
                          resource_id,
                          subject_id,
                          subject_type);

              CHECK_OMPF_RET

              response = NULL;
              entity = NULL;
              ret = ompf (connection, credentials,
                          &response,
                          &entity,
                          response_data,
                          "<create_permission>"
                          "<name>stop_%s</name>"
                          "<comment>%s</comment>"
                          "<resource id=\"%s\">"
                          "</resource>"
                          "<subject id=\"%s\"><type>%s</type></subject>"
                          "</create_permission>",
                          resource_type,
                          comment ? comment : "",
                          resource_id,
                          subject_id,
                          subject_type);

              CHECK_OMPF_RET

              response = NULL;
              entity = NULL;
              ret = ompf (connection, credentials,
                          &response,
                          &entity,
                          response_data,
                          "<create_permission>"
                          "<name>resume_%s</name>"
                          "<comment>%s</comment>"
                          "<resource id=\"%s\">"
                          "</resource>"
                          "<subject id=\"%s\"><type>%s</type></subject>"
                          "</create_permission>",
                          resource_type,
                          comment ? comment : "",
                          resource_id,
                          subject_id,
                          subject_type);

              CHECK_OMPF_RET
            }

          if (strcmp (resource_type, "alert") == 0)
            {
              response = NULL;
              entity = NULL;
              ret = ompf (connection, credentials,
                          &response,
                          &entity,
                          response_data,
                          "<create_permission>"
                          "<name>test_%s</name>"
                          "<comment>%s</comment>"
                          "<resource id=\"%s\">"
                          "</resource>"
                          "<subject id=\"%s\"><type>%s</type></subject>"
                          "</create_permission>",
                          resource_type,
                          comment ? comment : "",
                          resource_id,
                          subject_id,
                          subject_type);

              CHECK_OMPF_RET
            }

          if (strcmp (resource_type, "agent") == 0
              || strcmp (resource_type, "report_format") == 0
              || strcmp (resource_type, "scanner") == 0)
            {
              response = NULL;
              entity = NULL;
              ret = ompf (connection, credentials,
                          &response,
                          &entity,
                          response_data,
                          "<create_permission>"
                          "<name>verify_%s</name>"
                          "<comment>%s</comment>"
                          "<resource id=\"%s\">"
                          "</resource>"
                          "<subject id=\"%s\"><type>%s</type></subject>"
                          "</create_permission>",
                          resource_type,
                          comment ? comment : "",
                          resource_id,
                          subject_id,
                          subject_type);

              CHECK_OMPF_RET
            }
        }
    }

  // Related permissions
  if (include_related)
    {
      params_t *related;
      related = params_values (params, "related:");
      if (related)
        {
          params_iterator_t iter;
          char *name;
          param_t *param;

          params_iterator_init (&iter, related);
          while (params_iterator_next (&iter, &name, &param))
            {
              char *related_id = name;
              char *related_type = param->value;

              if (strcmp (permission, "read") == 0
                  || strcmp (permission, "proxy") == 0)
                {
                  response = NULL;
                  entity = NULL;
                  ret = ompf (connection, credentials,
                              &response,
                              &entity,
                              response_data,
                              "<create_permission>"
                              "<name>get_%ss</name>"
                              "<comment>%s</comment>"
                              "<resource id=\"%s\">"
                              "</resource>"
                              "<subject id=\"%s\"><type>%s</type></subject>"
                              "</create_permission>",
                              related_type,
                              comment ? comment : "",
                              related_id,
                              subject_id,
                              subject_type);

                  CHECK_OMPF_RET
                }

              if ((strcmp (permission, "proxy") == 0)
                  && strcmp (related_type, "result")
                  && strcmp (related_type, "report"))
                {
                  response = NULL;
                  entity = NULL;
                  ret = ompf (connection, credentials,
                              &response,
                              &entity,
                              response_data,
                              "<create_permission>"
                              "<name>modify_%s</name>"
                              "<comment>%s</comment>"
                              "<resource id=\"%s\">"
                              "</resource>"
                              "<subject id=\"%s\"><type>%s</type></subject>"
                              "</create_permission>",
                              related_type,
                              comment ? comment : "",
                              related_id,
                              subject_id,
                              subject_type);

                  CHECK_OMPF_RET

                  if (strcmp (related_type, "task") == 0)
                    {
                      response = NULL;
                      entity = NULL;
                      ret = ompf (connection, credentials,
                                  &response,
                                  &entity,
                                  response_data,
                                  "<create_permission>"
                                  "<name>start_%s</name>"
                                  "<comment>%s</comment>"
                                  "<resource id=\"%s\">"
                                  "</resource>"
                                  "<subject id=\"%s\"><type>%s</type></subject>"
                                  "</create_permission>",
                                  related_type,
                                  comment ? comment : "",
                                  related_id,
                                  subject_id,
                                  subject_type);

                      CHECK_OMPF_RET

                      response = NULL;
                      entity = NULL;
                      ret = ompf (connection, credentials,
                                  &response,
                                  &entity,
                                  response_data,
                                  "<create_permission>"
                                  "<name>stop_%s</name>"
                                  "<comment>%s</comment>"
                                  "<resource id=\"%s\">"
                                  "</resource>"
                                  "<subject id=\"%s\"><type>%s</type></subject>"
                                  "</create_permission>",
                                  related_type,
                                  comment ? comment : "",
                                  related_id,
                                  subject_id,
                                  subject_type);

                      CHECK_OMPF_RET

                      response = NULL;
                      entity = NULL;
                      ret = ompf (connection, credentials,
                                  &response,
                                  &entity,
                                  response_data,
                                  "<create_permission>"
                                  "<name>resume_%s</name>"
                                  "<comment>%s</comment>"
                                  "<resource id=\"%s\">"
                                  "</resource>"
                                  "<subject id=\"%s\"><type>%s</type></subject>"
                                  "</create_permission>",
                                  related_type,
                                  comment ? comment : "",
                                  related_id,
                                  subject_id,
                                  subject_type);

                      CHECK_OMPF_RET
                    }

                  if (strcmp (related_type, "alert") == 0)
                    {
                      response = NULL;
                      entity = NULL;
                      ret = ompf (connection, credentials,
                                  &response,
                                  &entity,
                                  response_data,
                                  "<create_permission>"
                                  "<name>test_%s</name>"
                                  "<comment>%s</comment>"
                                  "<resource id=\"%s\">"
                                  "</resource>"
                                  "<subject id=\"%s\"><type>%s</type></subject>"
                                  "</create_permission>",
                                  related_type,
                                  comment ? comment : "",
                                  related_id,
                                  subject_id,
                                  subject_type);

                      CHECK_OMPF_RET
                    }

                  if (strcmp (related_type, "agent") == 0
                      || strcmp (related_type, "report_format") == 0
                      || strcmp (related_type, "scanner") == 0)
                    {
                      response = NULL;
                      entity = NULL;
                      ret = ompf (connection, credentials,
                                  &response,
                                  &entity,
                                  response_data,
                                  "<create_permission>"
                                  "<name>verify_%s</name>"
                                  "<comment>%s</comment>"
                                  "<resource id=\"%s\">"
                                  "</resource>"
                                  "<subject id=\"%s\"><type>%s</type></subject>"
                                  "</create_permission>",
                                  related_type,
                                  comment ? comment : "",
                                  related_id,
                                  subject_id,
                                  subject_type);

                      CHECK_OMPF_RET
                    }
                }
            }
        }
    }

  if (get_subject_entity)
    free_entity (get_subject_entity);

  summary_response = g_strdup_printf("Successfully created %i permissions",
                                     successes);

  next_url = next_page_url (credentials, params,
                            NULL, "new_permissions",
                            "Create Permissions",
                            G_STRINGIFY (MHD_HTTP_CREATED),
                            summary_response);

  if (no_redirect)
    {
      html = action_result_page (connection, credentials, params, response_data,
                                 "Create Permissions",
                                 G_STRINGIFY (MHD_HTTP_CREATED),
                                 summary_response,
                                 NULL,
                                 next_url);
      g_free (next_url);
    }
  else
    {
      html = NULL;
      response_data->redirect = next_url;
    }
  return html;
}

#undef CHECK_OMPF_RET

/**
 * @brief Setup edit_permission XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_permission (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, const char *extra_xml,
                 cmd_response_data_t* response_data)
{
  gchar *html;
  GString *extra;

  extra = g_string_new ("");

  if (command_enabled (credentials, "GET_USERS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_users filter=\"rows=-1\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_GROUPS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_groups filter=\"rows=-1\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_ROLES"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_roles filter=\"rows=-1\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (extra_xml)
    g_string_append (extra, extra_xml);
  html = edit_resource (connection, "permission", credentials, params, NULL,
                        extra->str, response_data);
  g_string_free (extra, TRUE);
  return html;
}

/**
 * @brief Setup edit_permission XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_permission_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  return edit_permission (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Export a permission.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Permission XML on success.  HTML result of XSL transformation on error.
 */
char *
export_permission_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       enum content_type * content_type,
                       char **content_disposition, gsize *content_length,
                       cmd_response_data_t* response_data)
{
  return export_resource (connection, "permission", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of permissions.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Permissions XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_permissions_omp (openvas_connection_t *connection,
                        credentials_t * credentials, params_t *params,
                        enum content_type * content_type,
                        char **content_disposition, gsize *content_length,
                        cmd_response_data_t* response_data)
{
  return export_many (connection, "permission", credentials, params,
                      content_type, content_disposition, content_length,
                      response_data);
}

/**
 * @brief Modify a permission, get all permissions, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_permission_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *no_redirect;
  const char *permission_id, *name, *comment, *resource_id, *resource_type;
  const char *subject_id, *subject_type;
  entity_t entity;
  int ret;

  no_redirect = params_value (params, "no_redirect");
  permission_id = params_value (params, "permission_id");
  name = params_value (params, "permission");
  comment = params_value (params, "comment");
  subject_type = params_value (params, "subject_type");
  resource_id = params_value (params, "id_or_empty");
  resource_type = params_value (params, "optional_resource_type");

  CHECK_PARAM_INVALID (permission_id, "Save Permission", "edit_permission");
  CHECK_PARAM_INVALID (name, "Save Permission", "edit_permission");
  CHECK_PARAM_INVALID (comment, "Save Permission", "edit_permission");
  if (params_given (params, "id_or_empty"))
    CHECK_PARAM_INVALID (resource_id, "Save Permission", "edit_permission");
  CHECK_PARAM_INVALID (subject_type, "Save Permission", "edit_permission");
  if (params_given (params, "optional_resource_type"))
    CHECK_PARAM_INVALID (resource_type, "Save Permission", "edit_permission");

  if (strcmp (subject_type, "user") == 0)
    subject_id = params_value (params, "user_id");
  else if (strcmp (subject_type, "group") == 0)
    subject_id = params_value (params, "group_id");
  else if (strcmp (subject_type, "role") == 0)
    subject_id = params_value (params, "role_id");
  else
    subject_id = NULL;
  CHECK_PARAM_INVALID (subject_id, "Save Permission", "edit_permission");

  /* Modify the permission. */

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<modify_permission permission_id=\"%s\">"
              "<name>%s</name>"
              "<comment>%s</comment>"
              "<subject id=\"%s\">"
              "<type>%s</type>"
              "</subject>"
              "<resource id=\"%s\">"
              "<type>%s</type>"
              "</resource>"
              "</modify_permission>",
              permission_id,
              name,
              comment,
              subject_id,
              subject_type,
              (resource_id && strlen (resource_id)) ? resource_id : "0",
              resource_type ? resource_type : "");
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while modifying a permission. "
                             "The permission was not modified. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_permissions", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while modifying a permission. "
                             "It is unclear whether the permission has been modified or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_permissions", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while modifying a permission. "
                             "It is unclear whether the permission has been modified or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_permissions", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_permissions",
                               NULL, "edit_permission",
                               "Save Permission", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}


/* Port lists. */

/**
 * @brief Returns page to create a new Port List.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_port_list (openvas_connection_t *connection, credentials_t *credentials,
               params_t *params, const char *extra_xml,
               cmd_response_data_t* response_data)
{
  GString *xml;
  xml = g_string_new ("<new_port_list>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_port_list>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to upload a new port list.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
upload_port_list (openvas_connection_t *connection, credentials_t *credentials,
                  params_t *params, const char *extra_xml,
                  cmd_response_data_t* response_data)
{
  GString *xml;

  xml = g_string_new ("<upload_port_list>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</upload_port_list>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the upload port list page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
upload_port_list_omp (openvas_connection_t *connection,
                      credentials_t *credentials, params_t *params,
                      cmd_response_data_t* response_data)
{
  return upload_port_list (connection, credentials, params, NULL,
                           response_data);
}

/**
 * @brief Create a port list, get all port lists, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_port_list_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *no_redirect, *name, *comment, *port_range, *from_file;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  port_range = params_value (params, "port_range");
  from_file = params_value (params, "from_file");

  CHECK_PARAM_INVALID (name, "Create Port List", "new_port_list");
  CHECK_PARAM_INVALID (comment, "Create Port List", "new_port_list");
  CHECK_PARAM_INVALID (port_range, "Create Port List", "new_port_list");
  CHECK_PARAM_INVALID (from_file, "Create Port List", "new_port_list");

  /* Create the port_list. */

  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<create_port_list>"
                "<name>%s</name>"
                "<port_range>%s</port_range>"
                "<comment>%s</comment>"
                "</create_port_list>",
                name,
                strcmp (from_file, "0")
                 ? params_value (params, "file")
                 : port_range,
                comment ? comment : ""))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new port list. "
                            "No new port list was created. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_port_lists", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new port list. "
                            "It is unclear whether the port list has been created or not. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_port_lists", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new port list. "
                            "It is unclear whether the port list has been created or not. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=get_port_lists", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "port_list_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_port_lists",
                               NULL, "new_port_list",
                               "Create Port List", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Returns page to create a new Port Range.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_port_range (openvas_connection_t *connection, credentials_t *credentials,
                params_t *params, const char *extra_xml,
                cmd_response_data_t* response_data)
{
  GString *xml;
  xml = g_string_new ("<new_port_range>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_port_range>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the new Port Range page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_port_range_omp (openvas_connection_t *connection,
                    credentials_t *credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  return new_port_range (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Add a range to a port list, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_port_range_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect, *port_list_id, *start, *end, *type;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  port_list_id = params_value (params, "port_list_id");
  start = params_value (params, "port_range_start");
  end = params_value (params, "port_range_end");
  type = params_value (params, "port_type");

  CHECK_PARAM_INVALID (port_list_id, "Create Port Range", "edit_port_list");
  CHECK_PARAM_INVALID (start, "Create Port Range", "edit_port_list");
  CHECK_PARAM_INVALID (end, "Create Port Range", "edit_port_list");
  CHECK_PARAM_INVALID (type, "Create Port Range", "edit_port_list");

  /* Create the port range. */

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<create_port_range>"
              "<port_list id=\"%s\"/>"
              "<start>%s</start>"
              "<end>%s</end>"
              "<type>%s</type>"
              "</create_port_range>",
              port_list_id,
              start,
              end,
              type);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a Port Range. "
                             "The Port Range was not created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_port_lists", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a Port Range. "
                             "It is unclear whether the Port Range has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_port_lists", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a Port Range. "
                             "It is unclear whether the Port Range has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_port_lists", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "edit_port_list",
                               NULL, "edit_port_list",
                               "Create Port Range", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Get one port_list, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  commands       Extra commands to run before the others.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_port_list (openvas_connection_t *connection,
               credentials_t * credentials, params_t *params,
               const char * extra_xml, cmd_response_data_t* response_data)
{
  return get_one (connection, "port_list", credentials, params, extra_xml,
                  "targets=\"1\" details=\"1\"", response_data);
}

/**
 * @brief Get one port_list, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_port_list_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  return get_port_list (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all Port Lists, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_port_lists (openvas_connection_t *connection,
                credentials_t * credentials, params_t *params,
                const char *extra_xml, cmd_response_data_t* response_data)
{
  return get_many (connection, "port_list", credentials, params, extra_xml,
                   NULL, response_data);
}

/**
 * @brief Get all port_lists, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_port_lists_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  return get_port_lists (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Return the new Port List page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_port_list_omp (openvas_connection_t *connection, credentials_t *credentials,
                   params_t *params, cmd_response_data_t* response_data)
{
  return new_port_list (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Setup edit_port_list XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_port_list (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, const char *extra_xml,
                cmd_response_data_t* response_data)
{
  return edit_resource (connection, "port_list", credentials, params, NULL,
                        extra_xml, response_data);
}

/**
 * @brief Setup edit_port_list XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_port_list_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  return edit_port_list (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Modify a port list, get all port list, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_port_list_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect, *port_list_id, *name, *comment;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  port_list_id = params_value (params, "port_list_id");
  name = params_value (params, "name");
  comment = params_value (params, "comment");

  CHECK_PARAM_INVALID (port_list_id, "Save Port List", "edit_port_list");
  CHECK_PARAM_INVALID (name, "Save Port List", "edit_port_list");
  CHECK_PARAM_INVALID (comment, "Save Port List", "edit_port_list");

  /* Modify the Port List. */

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<modify_port_list port_list_id=\"%s\">"
              "<name>%s</name>"
              "<comment>%s</comment>"
              "</modify_port_list>",
              port_list_id,
              name,
              comment);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a Port List. "
                             "The Port List was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_port_lists", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a Port List. "
                             "It is unclear whether the Port List has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_port_lists", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a Port List. "
                             "It is unclear whether the Port List has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_port_lists", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_port_lists",
                               NULL, "edit_port_list",
                               "Save Port List", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Delete a port list, get all port lists, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_port_list_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      cmd_response_data_t* response_data)
{
  return delete_resource (connection, "port_list", credentials, params, 0,
                          "get_port_lists", response_data);
}

/**
 * @brief Delete a trash port list, get all trash, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_port_list_omp (openvas_connection_t *connection,
                            credentials_t * credentials, params_t *params,
                            cmd_response_data_t* response_data)
{
  return delete_resource (connection, "port_list", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a port range, get the port list, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_port_range_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  return delete_resource (connection, "port_range", credentials, params, 1,
                          "edit_port_list", response_data);
}

/**
 * @brief Import port list, get all port_lists, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
import_port_list_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      cmd_response_data_t* response_data)
{
  const char *no_redirect;
  gchar *command, *html, *response;
  entity_t entity;
  int ret;

  no_redirect = params_value (params, "no_redirect");

  /* Create the port list. */

  response = NULL;
  entity = NULL;
  command = g_strdup_printf ("<create_port_list>"
                             "%s"
                             "</create_port_list>",
                             params_value (params, "xml_file"));
  ret = omp (connection, credentials, &response, &entity, response_data,
             command);
  g_free (command);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while importing a port_list. "
                             "The schedule remains the same. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_port_lists",
                             response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while importing a port_list. "
                             "It is unclear whether the schedule has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_port_lists",
                             response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while importing a port_list. "
                             "It is unclear whether the schedule has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_port_lists",
                             response_data);
    }

  /* Cleanup, and return transformed XML. */

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_port_lists",
                               NULL, "new_port_list",
                               "Import Port List", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}


/* Roles. */

/**
 * @brief Returns page to create a new role.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_role (openvas_connection_t *connection, credentials_t *credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  GString *xml;
  xml = g_string_new ("<new_role>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_role>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to create a new role.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_role_omp (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return new_role (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Delete a role from trash, get all roles, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_role_omp (openvas_connection_t *connection,
                       credentials_t * credentials, params_t *params,
                       cmd_response_data_t* response_data)
{
  return delete_resource (connection, "role", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a role, get all roles, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_role_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return delete_resource (connection, "role", credentials, params, 0,
                          "get_roles", response_data);
}

/**
 * @brief Create a role, get all roles, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_role_omp (openvas_connection_t *connection, credentials_t *credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  char *ret;
  gchar *response;
  const char *no_redirect, *name, *comment, *users;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  users = params_value (params, "users");

  CHECK_PARAM_INVALID (name, "Create Role", "new_role");
  CHECK_PARAM_INVALID (comment, "Create Role", "new_role");
  CHECK_PARAM_INVALID (users, "Create Role", "new_role");

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<create_role>"
                "<name>%s</name>"
                "<comment>%s</comment>"
                "<users>%s</users>"
                "</create_role>",
                name,
                comment,
                users))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new role. "
                             "No new role was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_targets", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new role. "
                             "It is unclear whether the role has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_roles", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new role. "
                             "It is unclear whether the role has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_roles", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "role_id", entity_attribute (entity, "id"));
  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_roles",
                              NULL, "new_role",
                              "Create Role", response_data);
  free_entity (entity);
  g_free (response);
  return ret;
}

/**
 * @brief Setup edit_role XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_role (openvas_connection_t *connection,
           credentials_t * credentials, params_t *params,
           const char *extra_xml, cmd_response_data_t* response_data)
{
  gchar *html;
  GString *extra;

  extra = g_string_new ("");

  if (command_enabled (credentials, "GET_PERMISSIONS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (ompf (connection, credentials, &response, &entity, response_data,
                    "<get_permissions"
                    " filter=\"rows=-1 subject_type=role and subject_uuid=%s\"/>",
                    params_value (params, "role_id")))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the permission list. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_roles", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the permission list. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_roles", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the permission list. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_roles", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_GROUPS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (ompf (connection, credentials, &response, &entity, response_data,
                    "<get_groups"
                    " filter=\"rows=-1 owner=%s\"/>",
                    credentials->username))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_roles", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_roles", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_roles", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (extra_xml)
    g_string_append (extra, extra_xml);
  html = edit_resource (connection, "role", credentials, params, NULL,
                        extra->str, response_data);
  g_string_free (extra, TRUE);
  return html;
}

/**
 * @brief Setup edit_role XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_role_omp (openvas_connection_t *connection,
               credentials_t * credentials, params_t *params,
               cmd_response_data_t* response_data)
{
  return edit_role (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get one role, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_role (openvas_connection_t *connection, credentials_t * credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  return get_one (connection, "role", credentials, params, extra_xml, NULL,
                  response_data);
}

/**
 * @brief Get one role, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_role_omp (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return get_role (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all roles, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_roles (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  return get_many (connection, "role", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all roles, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_roles_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return get_roles (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Export a role.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Role XML on success.  HTML result of XSL transformation on error.
 */
char *
export_role_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, enum content_type * content_type,
                 char **content_disposition, gsize *content_length,
                 cmd_response_data_t* response_data)
{
  return export_resource (connection, "role", credentials, params, content_type,
                          content_disposition, content_length, response_data);
}

/**
 * @brief Export a list of roles.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Roles XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_roles_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, enum content_type * content_type,
                  char **content_disposition, gsize *content_length,
                  cmd_response_data_t* response_data)
{
  return export_many (connection, "role", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Modify a role, return the next page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_role_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect, *role_id, *name, *comment, *users;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  role_id = params_value (params, "role_id");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  users = params_value (params, "users");

  CHECK_PARAM_INVALID (role_id, "Save Role", "edit_role");
  CHECK_PARAM_INVALID (name, "Save Role", "edit_role");
  CHECK_PARAM_INVALID (comment, "Save Role", "edit_role");
  CHECK_PARAM_INVALID (users, "Save Role", "edit_role");

  /* Modify the Role. */

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<modify_role role_id=\"%s\">"
              "<name>%s</name>"
              "<comment>%s</comment>"
              "<users>%s</users>"
              "</modify_role>",
              role_id,
              name,
              comment,
              users);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a role. "
                             "The role was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_roles", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a role. "
                             "It is unclear whether the role has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_roles", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a role. "
                             "It is unclear whether the role has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_roles", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_roles",
                               NULL, "edit_role",
                               "Save Role", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}


/* Feeds. */

/**
 * @brief Get descriptions of the feeds connected to the manager.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_feeds_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  entity_t entity;
  char *text = NULL;
  gchar *response;
  time_t now;
  struct tm *tm;
  gchar current_timestamp[30];

  if (openvas_connection_sendf (connection,
                                "<commands>"
                                "<get_feeds/>"
                                "</commands>")
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the feed list. "
                           "The current list of feeds is not available. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (read_entity_and_text_c (connection, &entity, &text))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the feed. "
                           "The current list of feeds is not available. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  time (&now);
  tm = gmtime (&now);
  if (tm == NULL
      || (strftime (current_timestamp,
                    29,
                    "%Y-%m-%dT%H:%M:%S",
                    tm)
          == 0))
    {
      current_timestamp[0] = '\0';
    }

  response = g_strdup_printf ("<get_feeds>"
                              "%s"
                              "<current_time_utc>%s</current_time_utc>"
                              "</get_feeds>",
                              text,
                              current_timestamp);

  g_free (text);

  return xsl_transform_omp (connection, credentials, params, response,
                            response_data);
}

/**
 * @brief Synchronize with a feed and XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication
 * @param[in]  params         Request parameters.
 * @param[in]  sync_cmd       Name of the OMP command used to sync the feed.
 * @param[in]  action         Action shown in gsad status messages.
 * @param[in]  feed_name      Name of the feed shown in error messages.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char*
sync_feed (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, const char *sync_cmd, const char *action,
           const char *feed_name,
           cmd_response_data_t* response_data)
{
  const char *no_redirect;
  entity_t entity;
  char *text = NULL;
  gchar *html, *msg;

  no_redirect = params_value (params, "no_redirect");

  if (openvas_connection_sendf (connection,
                                "<%s/>",
                                sync_cmd)
      == -1)
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;

      msg = g_strdup_printf
              ("An internal error occurred while synchronizing with %s. "
               "Feed synchronization is currently not available. "
               "Diagnostics: Failure to send command to manager daemon.",
               feed_name);
      html = gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           msg, "/omp?cmd=get_tasks", response_data);
      g_free (msg);
      return html;
    }

  if (read_entity_and_text_c (connection, &entity, &text))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;

      msg = g_strdup_printf
              ("An internal error occurred while synchronizing with %s. "
               "Feed synchronization is currently not available. "
               "Diagnostics: Failure to receive response from manager daemon.",
               feed_name);
      html = gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           msg, "/omp?cmd=get_tasks", response_data);
      g_free (msg);
      return html;
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_feeds",
                               NULL, "get_feeds",
                               action, response_data);

  return html;
}

/**
 * @brief Synchronize with an NVT feed and XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
sync_feed_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return sync_feed (connection, credentials, params,
                    "sync_feed", "Synchronize Feed", "the NVT feed",
                    response_data);
}

/**
 * @brief Synchronize with a SCAP feed and XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
sync_scap_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return sync_feed (connection, credentials, params,
                    "sync_scap", "Synchronize Feed", "the SCAP feed",
                    response_data);
}

/**
 * @brief Synchronize with a CERT feed and XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
sync_cert_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return sync_feed (connection, credentials, params,
                    "sync_cert", "Synchronize CERT Feed", "the CERT feed",
                    response_data);
}


/* Filters. */

/**
 * @brief Get one filter, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_filter (openvas_connection_t *connection, credentials_t * credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  return get_one (connection, "filter", credentials, params, extra_xml,
                  "alerts=\"1\"", response_data);
}

/**
 * @brief Get one filter, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_filter_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return get_filter (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all filters, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_filters (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  return get_many (connection, "filter", credentials, params, extra_xml, NULL,
                   response_data);
}

/**
 * @brief Get all filters, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_filters_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return get_filters (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Returns page to create a new filter.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_filter (openvas_connection_t *connection, credentials_t *credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  GString *xml;
  xml = g_string_new ("<new_filter>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_filter>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Create a filter, get all filters, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_filter_omp (openvas_connection_t *connection, credentials_t *credentials,
                   params_t *params, cmd_response_data_t* response_data)
{
  gchar *html, *response;
  const char *no_redirect, *name, *comment, *term, *type;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  term = params_value (params, "term");
  type = params_value (params, "optional_resource_type");

  CHECK_PARAM_INVALID (name, "Create Filter", "new_filter");
  CHECK_PARAM_INVALID (comment, "Create Filter", "new_filter");
  CHECK_PARAM_INVALID (term, "Create Filter", "new_filter");
  CHECK_PARAM_INVALID (type, "Create Filter", "new_filter");

  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<create_filter>"
                "<name>%s</name>"
                "<comment>%s</comment>"
                "<term>%s</term>"
                "<type>%s</type>"
                "</create_filter>",
                name,
                comment,
                term,
                type))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new alert. "
                            "No new alert was created. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_alerts", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new alert. "
                            "It is unclear whether the alert has been created or not. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_alerts", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new alert. "
                            "It is unclear whether the alert has been created or not. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=get_alerts", response_data);
    }

  if (omp_success (entity))
    {
      const char *filter_id;

      filter_id = entity_attribute (entity, "id");
      if (filter_id && strlen (filter_id))
        {
          param_t *param;
          param = params_add (params, "filt_id", filter_id);
          param->valid = 1;
          param->valid_utf8 = g_utf8_validate (param->value, -1, NULL);
        }
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "filter_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_filters",
                               NULL, "new_filter",
                               "Create Filter", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Delete a filter, get all filters, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_trash_filter_omp (openvas_connection_t *connection,
                         credentials_t * credentials, params_t *params,
                         cmd_response_data_t* response_data)
{
  return delete_resource (connection, "filter", credentials, params, 1,
                          "get_trash", response_data);
}

/**
 * @brief Delete a filter, get all filters, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_filter_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  param_t *filt_id, *id;
  GList *list;

  filt_id = params_get (params, "filt_id");
  id = params_get (params, "filter_id");
  if (id && id->value && filt_id && filt_id->value
      && (strcmp (id->value, filt_id->value) == 0))
    // TODO: Add params_remove.
    filt_id->value = NULL;

  /* remove to be deleted key from the user credentials */
  if (id && id->value)
    {
      find_by_value_t find;

      init_find_by_value (&find, id->value);

      g_tree_foreach (credentials->last_filt_ids, (GTraverseFunc)find_by_value,
                      &find);
      if (find.keys != NULL)
        {
          list = g_list_first (find.keys);

          while (list != NULL)
            {
              g_debug ("%s removing filter from last filter ids for %s\n",
                      __FUNCTION__, (char *)list->data);
              g_tree_remove (credentials->last_filt_ids, list->data);
              list = g_list_next (find.keys);
            }
        }

      free_find_by_value(&find);
    }

  return delete_resource (connection, "filter", credentials, params, 0,
                          "get_filters", response_data);
}

/**
 * @brief Setup edit_filter XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_filter (openvas_connection_t *connection, credentials_t * credentials,
             params_t *params, const char *extra_xml,
             cmd_response_data_t* response_data)
{
  return edit_resource (connection, "filter", credentials, params, NULL,
                        extra_xml, response_data);
}

/**
 * @brief Setup edit_filter XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_filter_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return edit_filter (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Export a filter.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Filter XML on success.  HTML result of XSL transformation on error.
 */
char *
export_filter_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   enum content_type * content_type, char **content_disposition,
                   gsize *content_length, cmd_response_data_t* response_data)
{
  return export_resource (connection, "filter", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of filters.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Filters XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_filters_omp (openvas_connection_t *connection,
                    credentials_t * credentials, params_t *params,
                    enum content_type * content_type, char **content_disposition,
                    gsize *content_length, cmd_response_data_t* response_data)
{
  return export_many (connection, "filter", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Returns page to create a new filter.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_filter_omp (openvas_connection_t *connection, credentials_t *credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return new_filter (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Modify a filter, get all filters, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_filter_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  entity_t entity;
  gchar *html, *response;
  const char *no_redirect, *filter_id, *name, *comment, *term, *type;

  no_redirect = params_value (params, "no_redirect");
  filter_id = params_value (params, "filter_id");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  term = params_value (params, "term");
  type = params_value (params, "optional_resource_type");

  CHECK_PARAM_INVALID (filter_id, "Save Filter", "edit_filter");
  CHECK_PARAM_INVALID (name, "Save Filter", "edit_filter");
  CHECK_PARAM_INVALID (comment, "Save Filter", "edit_filter");
  CHECK_PARAM_INVALID (term, "Save Filter", "edit_filter");
  CHECK_PARAM_INVALID (type, "Save Filter", "edit_filter");

  {
    int ret;

    /* Modify the filter. */

    ret = openvas_connection_sendf_xml (connection,
                                        "<modify_filter filter_id=\"%s\">"
                                        "<name>%s</name>"
                                        "<comment>%s</comment>"
                                        "<term>%s</term>"
                                        "<type>%s</type>"
                                        "</modify_filter>",
                                        filter_id,
                                        name,
                                        comment,
                                        term,
                                        type);

    if (ret == -1)
      {
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while modifying a filter. "
                             "The filter was not modified. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_filters", response_data);
      }

    entity = NULL;
    if (read_entity_and_text_c (connection, &entity, &response))
      {
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while modifying a filter. "
                             "It is unclear whether the filter has been modified or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_filters", response_data);
      }

  }

  /* Pass response to handler of following page. */

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_filters",
                               NULL, "edit_filter",
                               "Save Filter", response_data);

  free_entity (entity);
  g_free (response);
  return html;
}


/* Schedules. */

/**
 * @brief Setup edit_schedule XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_schedule (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, const char *extra_xml,
               cmd_response_data_t* response_data)
{
  return edit_resource (connection, "schedule", credentials, params,
                        "tasks=\"1\"", extra_xml, response_data);
}

/**
 * @brief Setup edit_schedule XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_schedule_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  return edit_schedule (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Export a schedule.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Schedule XML on success.  HTML result of XSL transformation on error.
 */
char *
export_schedule_omp (openvas_connection_t *connection,
                     credentials_t * credentials, params_t *params,
                     enum content_type * content_type,
                     char **content_disposition, gsize *content_length,
                     cmd_response_data_t* response_data)
{
  return export_resource (connection, "schedule", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of schedules.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Schedules XML on success. HTML result of XSL transformation on error.
 */
char *
export_schedules_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      enum content_type * content_type,
                      char **content_disposition, gsize *content_length,
                      cmd_response_data_t* response_data)
{
  return export_many (connection, "schedule", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Save schedule, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_schedule_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  gchar *response;
  entity_t entity;
  const char *no_redirect, *schedule_id, *name, *comment;
  const char *hour, *minute, *day_of_month, *month, *year, *timezone;
  const char *period, *period_unit, *duration, *duration_unit;
  char *ret;

  no_redirect = params_value (params, "no_redirect");
  schedule_id = params_value (params, "schedule_id");
  name = params_value (params, "name");
  comment = params_value (params, "comment");
  hour = params_value (params, "hour");
  minute = params_value (params, "minute");
  day_of_month = params_value (params, "day_of_month");
  duration = params_value (params, "duration");
  duration_unit = params_value (params, "duration_unit");
  month = params_value (params, "month");
  period = params_value (params, "period");
  period_unit = params_value (params, "period_unit");
  year = params_value (params, "year");
  timezone = params_value (params, "timezone");

  CHECK_PARAM_INVALID (schedule_id, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (name, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (comment, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (hour, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (minute, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (day_of_month, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (duration, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (duration_unit, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (month, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (period, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (period_unit, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (year, "Save Schedule", "edit_schedule");
  CHECK_PARAM_INVALID (timezone, "Save Schedule", "edit_schedule");

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<modify_schedule schedule_id=\"%s\">"
                "<name>%s</name>"
                "<comment>%s</comment>"
                "<first_time>"
                "<hour>%s</hour>"
                "<minute>%s</minute>"
                "<day_of_month>%s</day_of_month>"
                "<month>%s</month>"
                "<year>%s</year>"
                "</first_time>"
                "<timezone>%s</timezone>"
                "<period>"
                "<unit>%s</unit>"
                "%s"
                "</period>"
                "<duration>"
                "<unit>%s</unit>"
                "%s"
                "</duration>"
                "</modify_schedule>",
                schedule_id,
                name ? name : "",
                comment ? comment : "",
                hour,
                minute,
                day_of_month,
                month,
                year,
                timezone,
                (strcmp (period_unit, "")
                  ? period_unit
                  : "second"),
                period,
                (strcmp (duration_unit, "")
                  ? duration_unit
                  : "second"),
                duration))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a schedule. "
                             "The schedule remains the same. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_schedules", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a schedule. "
                             "It is unclear whether the schedule has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_schedules", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a schedule. "
                             "It is unclear whether the schedule has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_schedules", response_data);
    }

  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_schedules",
                              NULL, "edit_schedule",
                              "Save Schedule", response_data);
  free_entity (entity);
  g_free (response);
  return ret;
}


/* Users. */

/**
 * @brief Returns page to create a new user.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_user (openvas_connection_t *connection, credentials_t *credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  GString *xml;

  xml = g_string_new ("<new_user>");
  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (command_enabled (credentials, "DESCRIBE_AUTH"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<describe_auth/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_GROUPS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_groups filter=\"permission=modify_group\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_ROLES"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_roles/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (xml, response);

      free_entity (entity);
      g_free (response);
    }

  g_string_append (xml, "</new_user>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns page to create a new user.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_user_omp (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return new_user (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Delete a user, get all users, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_user_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  return delete_resource (connection, "user", credentials, params, 0,
                          "get_users", response_data);
}

/**
 * @brief Returns page to create a new user.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
delete_user_confirm (openvas_connection_t *connection,
                     credentials_t *credentials, params_t *params,
                     const char *extra_xml, cmd_response_data_t* response_data)
{
  GString *xml;
  gchar *response = NULL;
  entity_t entity = NULL;

  if (command_enabled (credentials, "GET_USERS"))
    {
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_users filter=\"first=1 rows=-1\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the user list. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }
    }

  xml = g_string_new ("<delete_user>");
  if (extra_xml)
    g_string_append (xml, extra_xml);

  if (response)
    g_string_append (xml, response);
  free_entity (entity);
  g_free (response);

  if (extra_xml)
    g_string_append (xml, extra_xml);

  g_string_append (xml, "</delete_user>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Show confirmation deleting a user, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_user_confirm_omp (openvas_connection_t *connection,
                         credentials_t * credentials, params_t *params,
                         cmd_response_data_t* response_data)
{
  return delete_user_confirm (connection, credentials, params, NULL,
                              response_data);
}

/**
 * @brief Get one user, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_user (openvas_connection_t *connection, credentials_t * credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  gchar *html;
  GString *extra;

  extra = g_string_new ("");
  if (extra_xml)
    g_string_append (extra, extra_xml);
  if (command_enabled (credentials, "DESCRIBE_AUTH"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<describe_auth/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }
  html = get_one (connection, "user", credentials, params, extra->str, NULL,
                  response_data);
  g_string_free (extra, TRUE);
  return html;
}

/**
 * @brief Get one user, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_user_omp (openvas_connection_t *connection, credentials_t * credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return get_user (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Get all users, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_users (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  gchar *html;
  GString *extra;

  extra = g_string_new ("");
  if (command_enabled (credentials, "DESCRIBE_AUTH"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<describe_auth/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }
  if (extra_xml)
    g_string_append (extra, extra_xml);
  html = get_many (connection, "user", credentials, params, extra->str, NULL,
                   response_data);
  g_string_free (extra, TRUE);
  return html;
}

/**
 * @brief Get all users, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_users_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return get_users (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create a user, get all users, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_user_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  const char *no_redirect;
  const char *name, *password, *hosts, *hosts_allow, *ifaces, *ifaces_allow;
  const char *auth_method;
  int ret;
  params_t *groups, *roles;
  GString *group_elements, *role_elements, *string;
  gchar *buf, *response, *html;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  name = params_value (params, "login");
  password = params_value (params, "password");
  hosts = params_value (params, "access_hosts");
  hosts_allow = params_value (params, "hosts_allow");
  ifaces = params_value (params, "access_ifaces");
  ifaces_allow = params_value (params, "ifaces_allow");
  auth_method = params_value (params, "auth_method");

  CHECK_PARAM_INVALID (name, "Create User", "new_user");
  CHECK_PARAM_INVALID (password, "Create User", "new_user");
  CHECK_PARAM_INVALID (hosts, "Create User", "new_user");
  CHECK_PARAM_INVALID (hosts_allow, "Create User", "new_user");
  CHECK_PARAM_INVALID (ifaces, "Create User", "new_user");
  CHECK_PARAM_INVALID (ifaces_allow, "Create User", "new_user");

  /* Create the user. */

  string = g_string_new ("<create_user>");
  buf = g_markup_printf_escaped ("<name>%s</name>"
                                 "<password>%s</password>",
                                 name,
                                 password);

  g_string_append (string, buf);
  g_free (buf);

  group_elements = g_string_new ("<groups>");
  if (params_given (params, "group_id_optional:"))
    groups = params_values (params, "group_id_optional:");
  else
    groups = params_values (params, "group_ids:");

  if (groups)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, groups);
      while (params_iterator_next (&iter, &name, &param))
      {
        if (param->value && strcmp (param->value, "--"))
          g_string_append_printf (group_elements,
                                  "<group id=\"%s\"/>",
                                  param->value ? param->value : "");
      }
    }
  g_string_append (string, group_elements->str);
  g_string_free (group_elements, TRUE);
  g_string_append (string, "</groups>");

  role_elements = g_string_new ("");
  if (params_given (params, "role_id_optional:"))
    roles = params_values (params, "role_id_optional:");
  else
    roles = params_values (params, "role_ids:");

  if (roles)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, roles);
      while (params_iterator_next (&iter, &name, &param))
      {
        if (param->value && strcmp (param->value, "--"))
          g_string_append_printf (role_elements,
                                  "<role id=\"%s\"/>",
                                  param->value ? param->value : "");
      }
    }
  g_string_append (string, role_elements->str);
  g_string_free (role_elements, TRUE);

  buf = g_markup_printf_escaped ("<hosts allow=\"%s\">%s</hosts>"
                                 "<ifaces allow=\"%s\">%s</ifaces>",
                                 hosts_allow, hosts, ifaces_allow, ifaces);
  g_string_append (string, buf);
  g_free (buf);
  if (auth_method && !strcmp (auth_method, "1"))
    g_string_append
     (string, "<sources><source>ldap_connect</source></sources>");
  else if (auth_method && !strcmp (auth_method, "2"))
    g_string_append
     (string, "<sources><source>radius_connect</source></sources>");
  g_string_append (string, "</create_user>");

  buf = g_string_free (string, FALSE);

  response = NULL;
  entity = NULL;
  ret = omp (connection, credentials, &response, &entity, response_data, buf);
  g_free (buf);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new user. "
                             "No new user was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_users", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new user. "
                             "It is unclear whether the user has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_users", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating a new user. "
                             "It is unclear whether the user has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_users", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "user_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_users",
                               NULL, "new_user",
                               "Create User", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Setup edit_user XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_user (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  gchar *html;
  GString *extra;

  extra = g_string_new ("");
  if (command_enabled (credentials, "DESCRIBE_AUTH"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<describe_auth/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_GROUPS"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_groups filter=\"permission=modify_group\"/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the group list. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (command_enabled (credentials, "GET_ROLES"))
    {
      gchar *response;
      entity_t entity;

      response = NULL;
      entity = NULL;
      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<get_roles/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the role list. "
                                 "No new user was created. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }

      g_string_append (extra, response);

      free_entity (entity);
      g_free (response);
    }

  if (extra_xml)
    g_string_append (extra, extra_xml);
  html = edit_resource (connection, "user", credentials, params, NULL,
                        extra->str, response_data);
  g_string_free (extra, TRUE);
  return html;
}

/**
 * @brief Setup edit_user XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_user_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return edit_user (connection, credentials, params, NULL, response_data);
}

char *
auth_settings_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   cmd_response_data_t* response_data)
{
  GString * xml;
  gchar * buf;
  const char *name;

  name = params_value (params, "name");

  CHECK_PARAM_INVALID (name, "Auth settings", "auth_settings");

  xml = g_string_new ("");
  buf = g_markup_printf_escaped ("<auth_settings name=\"%s\">", name);
  g_string_append (xml, buf);
  g_free (buf);

  if (command_enabled (credentials, "DESCRIBE_AUTH"))
    {
      gchar * response = NULL;
      entity_t entity = NULL;

      switch (omp (connection, credentials, &response, &entity, response_data,
                   "<describe_auth/>"))
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Failure to send command to manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Failure to receive response from manager daemon.",
                                 "/omp?cmd=get_users", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                 "Internal error", __FUNCTION__, __LINE__,
                                 "An internal error occurred getting the auth list. "
                                 "Diagnostics: Internal Error.",
                                 "/omp?cmd=get_users", response_data);
        }


      g_string_append (xml, response);
      free_entity (entity);
      g_free (response);
    }

  g_string_append (xml, "</auth_settings>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup edit_user XML, XSL transform the result.
 *
 * @param[in]  credentials  Username and password for authentication.
 * @param[in]  message      Login screen message.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
logout (credentials_t *credentials, const gchar *message,
        cmd_response_data_t *response_data)
{
  time_t now;
  gchar *xml;
  char *res;
  char ctime_now[200];
  int ret;
  const char* xml_flag;
  xml_flag = params_value (credentials->params, "xml");

  if (credentials->token == NULL)
    return NULL;

  ret = token_user_remove (credentials->token);
  if (ret)
    return NULL;

  now = time (NULL);
  ctime_r_strip_newline (&now, ctime_now);

  xml = login_xml (message, NULL, ctime_now, NULL, NULL, NULL);

  if (xml_flag && strcmp (xml_flag, "0"))
    return xml;

  res = xsl_transform (xml, response_data);
  g_free (xml);
  return res;
}

/**
 * @brief Modify a user, get all users, XSL transform the result.
 *
 * @param[in]  connection       Connection to manager
 * @param[in]  credentials      Username and password for authentication.
 * @param[in]  params           Request parameters.
 * @param[out] password_return  Password.  Caller must free.
 * @param[out] modified_user    Name of user modified. Caller must free.
 * @param[out] logout_user      Whether the user should be logged out.
 * @param[out] response_data    Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_user_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, char **password_return, char **modified_user,
               int *logout_user, cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response, *buf;
  const char *no_redirect;
  const char *user_id, *login, *old_login, *modify_password, *password;
  const char *hosts, *hosts_allow, *ifaces, *ifaces_allow;
  entity_t entity;
  GString *command, *group_elements, *role_elements;
  params_t *groups, *roles;
  const char *status;

  *password_return = NULL;
  *modified_user = NULL;
  *logout_user = 0;

  no_redirect = params_value (params, "no_redirect");
  /* List of hosts user has/lacks access rights. */
  hosts = params_value (params, "access_hosts");
  /* Whether hosts grants ("1") or forbids ("0") access.  "2" for all
   * access. */
  hosts_allow = params_value (params, "hosts_allow");
  ifaces = params_value (params, "access_ifaces");
  ifaces_allow = params_value (params, "ifaces_allow");
  login = params_value (params, "login");
  old_login = params_value (params, "old_login");
  modify_password = params_value (params, "modify_password");
  password = params_value (params, "password");
  user_id = params_value (params, "user_id");

  CHECK_PARAM_INVALID (user_id, "Edit User", "edit_user");
  CHECK_PARAM_INVALID (modify_password, "Edit User", "edit_user");
  CHECK_PARAM_INVALID (password, "Edit User", "edit_user");
  CHECK_PARAM_INVALID (hosts, "Edit User", "edit_user");
  CHECK_PARAM_INVALID (hosts_allow, "Edit User", "edit_user");
  CHECK_PARAM_INVALID (ifaces, "Save User", "edit_user");
  CHECK_PARAM_INVALID (ifaces_allow, "Save User", "edit_user");

  if (params_given (params, "login")
      && !(params_given (params, "current_user")))
    {
      CHECK_PARAM_INVALID (login, "Save User", "edit_user");
      CHECK_PARAM_INVALID (old_login, "Save User", "edit_user");
    }

  /* Modify the user. */

  command = g_string_new ("");
  buf = g_markup_printf_escaped ("<modify_user user_id=\"%s\">"
                                 "<password modify=\"%s\">"
                                 "%s</password>",
                                 user_id,
                                 modify_password,
                                 password);
  g_string_append (command, buf);
  g_free (buf);

  if (login)
    {
      buf = g_markup_printf_escaped ("<new_name>%s</new_name>",
                                     login);
      g_string_append (command, buf);
      g_free (buf);
    }

  buf = g_markup_printf_escaped ("<hosts allow=\"%s\">%s</hosts>"
                                 "<ifaces allow=\"%s\">%s</ifaces>",
                                 hosts_allow, hosts, ifaces_allow, ifaces);
  g_string_append (command, buf);
  g_free (buf);

  if (modify_password && !strcmp (modify_password, "2"))
    g_string_append (command, "<sources><source>ldap_connect</source></sources>");
  else if (modify_password && !strcmp (modify_password, "3"))
    g_string_append (command, "<sources><source>radius_connect</source></sources>");
  else
    g_string_append (command, "<sources><source>file</source></sources>");

  group_elements = g_string_new ("<groups>");
  if (params_given (params, "group_id_optional:"))
    groups = params_values (params, "group_id_optional:");
  else
    groups = params_values (params, "group_ids:");

  if (groups)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, groups);
      while (params_iterator_next (&iter, &name, &param))
      {
        if (param->value && strcmp (param->value, "--"))
          g_string_append_printf (group_elements,
                                  "<group id=\"%s\"/>",
                                  param->value ? param->value : "");
      }
    }
  g_string_append (command, group_elements->str);
  g_string_free (group_elements, TRUE);
  g_string_append (command, "</groups>");

  role_elements = g_string_new ("");
  if (params_given (params, "role_id_optional:"))
    roles = params_values (params, "role_id_optional:");
  else
    roles = params_values (params, "role_ids:");

  if (roles)
    {
      params_iterator_t iter;
      char *name;
      param_t *param;

      params_iterator_init (&iter, roles);
      while (params_iterator_next (&iter, &name, &param))
      {
        if (param->value && strcmp (param->value, "--"))
          g_string_append_printf (role_elements,
                                  "<role id=\"%s\"/>",
                                  param->value ? param->value : "");
      }
    }
  else
    g_string_append_printf (role_elements, "<role id=\"0\"/>");

  g_string_append (command, role_elements->str);
  g_string_free (role_elements, TRUE);

  g_string_append (command, "</modify_user>");

  response = NULL;
  entity = NULL;
  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             command->str);
  g_string_free (command, TRUE);
  switch (ret)
    {
      case 0:
        status = entity_attribute (entity, "status");
        if (status && (strlen (status) > 0) && (status[0] == '2'))
          {
            *modified_user
              = g_strdup (old_login ? old_login : credentials->username);

            if (strcmp (modify_password, "0")
                || (login && *modified_user && strcmp (*modified_user, login)))
              *logout_user = 1;

            if (strcmp (modify_password, "0")
                && strcmp (modify_password, "2")
                && strcmp (modify_password, "3")
                && params_given (params, "current_user"))
              {
                g_free (credentials->password);
                credentials->password = g_strdup (password);
                *password_return = g_strdup (password);
              }
          }
        break;
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a user. "
                             "The user was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_users", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a user. "
                             "It is unclear whether the user has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_users", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving a user. "
                             "It is unclear whether the user has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_users", response_data);
    }

  if (omp_success (entity)
      && (!strcmp (modify_password, "2")
          || !strcmp (modify_password, "3"))
      && params_given (params, "current_user"))
    {
      free_entity (entity);
      g_free (response);
      html = logout (credentials,
                     "Authentication method changed."
                     "  Please login with LDAP password.",
                     response_data);
    }
  else
    html = response_from_entity (connection, credentials, params, entity,
                                 (no_redirect && strcmp (no_redirect, "0")),
                                 NULL, "get_users",
                                 NULL, "edit_user",
                                 "Save User", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Export a user.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Note XML on success.  HTML result of XSL transformation on error.
 */
char *
export_user_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, enum content_type * content_type,
                 char **content_disposition, gsize *content_length,
                 cmd_response_data_t* response_data)
{
  return export_resource (connection, "user", credentials, params, content_type,
                          content_disposition, content_length, response_data);
}

/**
 * @brief Export a list of users.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Users XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_users_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, enum content_type * content_type,
                  char **content_disposition, gsize *content_length,
                  cmd_response_data_t* response_data)
{
  return export_many (connection, "user", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

char *
cvss_calculator (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  GString *xml;
  const char *cvss_av, *cvss_au, *cvss_ac, *cvss_c, *cvss_i, *cvss_a;
  const char *cvss_vector, *name;

  cvss_av = params_value (params, "cvss_av");
  cvss_au = params_value (params, "cvss_au");
  cvss_ac = params_value (params, "cvss_ac");
  cvss_c = params_value (params, "cvss_c");
  cvss_i = params_value (params, "cvss_i");
  cvss_a = params_value (params, "cvss_a");
  cvss_vector = params_value (params, "cvss_vector");
  name = params_value (params, "name");

  xml = g_string_new ("<cvss_calculator>");

  /* Calculate base score */
  if (cvss_av && cvss_au && cvss_ac && cvss_c && cvss_i && cvss_a)
    {
      char *vector = g_strdup_printf
                      ("AV:%c/AC:%c/Au:%c/C:%c/I:%c/A:%c",
                       *cvss_av, *cvss_ac, *cvss_au, *cvss_c, *cvss_i, *cvss_a);

      g_string_append_printf (xml,
                              "<cvss_vector>%s</cvss_vector>"
                              "<cvss_score>%.1f</cvss_score>",
                              vector,
                              get_cvss_score_from_base_metrics (vector));

      g_string_append_printf
       (xml,
        "<cvss_av>%c</cvss_av><cvss_au>%c</cvss_au>"
        "<cvss_ac>%c</cvss_ac><cvss_c>%c</cvss_c>"
        "<cvss_i>%c</cvss_i><cvss_a>%c</cvss_a>",
        *cvss_av, *cvss_au, *cvss_ac, *cvss_c, *cvss_i, *cvss_a);

      g_free (vector);
    }
  else if (cvss_vector)
    {
      double cvss_score = get_cvss_score_from_base_metrics (cvss_vector);

      g_string_append_printf (xml,
                              "<cvss_vector>%s</cvss_vector>"
                              "<cvss_score>%.1f</cvss_score>",
                              cvss_vector,
                              cvss_score);

      if (cvss_score != -1.0)
        {
            cvss_av = strstr (cvss_vector, "AV:");
            cvss_ac = strstr (cvss_vector, "/AC:");
            cvss_au = strstr (cvss_vector, "/Au:");
            if (cvss_au == NULL)
              cvss_au = strstr (cvss_vector, "/AU:");
            cvss_c = strstr (cvss_vector, "/C:");
            cvss_i = strstr (cvss_vector, "/I:");
            cvss_a = strstr (cvss_vector, "/A:");

            if (cvss_av && cvss_ac && cvss_au && cvss_c
                && cvss_i && cvss_a)
              g_string_append_printf
               (xml,
                "<cvss_av>%c</cvss_av><cvss_ac>%c</cvss_ac>"
                "<cvss_au>%c</cvss_au><cvss_c>%c</cvss_c>"
                "<cvss_i>%c</cvss_i><cvss_a>%c</cvss_a>",
                *(cvss_av + 3), *(cvss_ac + 4), *(cvss_au + 4),
                *(cvss_c + 3), *(cvss_i + 3), *(cvss_a + 3));
        }
    }
  else if (name && !strcmp ("vector", name))
    {
      g_string_append_printf (xml,
                              "<cvss_score>%.1f</cvss_score>",
                              -1.0);
    }

  g_string_append (xml, "</cvss_calculator>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Show a dashboard.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return XSL transformed dashboard.
 */
char *
dashboard (openvas_connection_t *connection, credentials_t * credentials,
           params_t *params, cmd_response_data_t* response_data)
{
  GString *xml;
  const char *name;
  gchar* response;
  entity_t entity;
  int ret;
  int may_get_aggregates, may_get_info, may_get_tasks;

  may_get_aggregates = command_enabled (credentials, "GET_AGGREGATES");
  may_get_info = command_enabled (credentials, "GET_INFO");
  may_get_tasks = command_enabled (credentials, "GET_TASKS");
  name = params_value (params, "dashboard_name");
  if (name == NULL)
    {
      if (credentials->guest
          && may_get_aggregates && may_get_info)
        name = "secinfo";
      else if (may_get_aggregates && may_get_info && may_get_tasks)
        name = "main";
      else if (may_get_aggregates && may_get_tasks)
        name = "scans";
      else if (may_get_aggregates && may_get_info)
        name = "secinfo";
      else if (command_enabled (credentials, "GET_SYSTEM_REPORTS"))
        {
          gchar *redirect_url;
          redirect_url = g_strdup_printf ("/omp?cmd=get_system_reports&token=%s",
                                          credentials->token);
          response_data->redirect = redirect_url;
          return g_strdup_printf ("redirecting to %s", redirect_url);
        }
      else
        {
          gchar *redirect_url;
          redirect_url = g_strdup_printf ("/help/about.html?token=%s",
                                          credentials->token);
          response_data->redirect = redirect_url;
          return g_strdup_printf ("redirecting to %s", redirect_url);
        }
    }

  xml = g_string_new ("<dashboard>");
  g_string_append_printf (xml, "<name>%s</name>", name);

  response = NULL;
  entity = NULL;

  // Test if SCAP and CERT databases are available
  if (strcasecmp (name, "") == 0
      || strcasecmp (name, "Main") == 0
      || strcasecmp (name, "SecInfo") == 0)
    {
      ret = ompf (connection,
                  credentials,
                  &response,
                  &entity,
                  response_data,
                  "<get_info type=\"cve\" info_id=\"--\"/>");

      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            g_string_free (xml, TRUE);
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while "
                                "testing SecInfo database availability. "
                                "Diagnostics: Failure to send command to "
                                "manager daemon.",
                                "/omp?cmd=dashboard", response_data);
          case 2:
            g_string_free (xml, TRUE);
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while "
                                "testing SecInfo database availability. "
                                "Diagnostics: Failure to receive response from "
                                "manager daemon.",
                                "/omp?cmd=dashboard", response_data);
          default:
            g_string_free (xml, TRUE);
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while "
                                "testing SecInfo database availability. "
                                "Diagnostics: Internal Error.",
                                "/omp?cmd=dashboard", response_data);
        }
      g_string_append_printf (xml,
                              "<secinfo_test>%s</secinfo_test>",
                              response);
      g_free (response);
      free_entity (entity);
    }

  if (strcasecmp (name, "SecInfo") == 0)
    ret = ompf (connection,
                credentials,
                &response,
                &entity,
                response_data,
                "<get_filters filter=\"type=info or type= first=1 rows=-1\"/>");
  else
    ret = ompf (connection,
                credentials,
                &response,
                &entity,
                response_data,
                "<get_filters filter=\"first=1 rows=-1\"/>");

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        g_string_free (xml, TRUE);
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting the "
                            "filters list. "
                            "Diagnostics: Failure to send command to "
                            "manager daemon.",
                            "/omp?cmd=dashboard", response_data);
      case 2:
        g_string_free (xml, TRUE);
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting the "
                            "filters list. "
                            "Diagnostics: Failure to receive response from "
                            "manager daemon.",
                            "/omp?cmd=dashboard", response_data);
      default:
        g_string_free (xml, TRUE);
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while getting the "
                            "filters list. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=dashboard", response_data);
    }

  g_string_append (xml, response);
  g_free (response);
  free_entity (entity);

  g_string_append (xml, "</dashboard>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Generate AUTH_CONF_SETTING element for save_auth_omp.
 */
#define AUTH_CONF_SETTING(key, value) \
  "<auth_conf_setting>"               \
  "<key>" key "</key>"                \
  "<value>" value "</value>"          \
  "</auth_conf_setting>"

/**
 * @brief Save authentication settings.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return XSL transformated list of users and configuration.
 */
char*
save_auth_omp (openvas_connection_t *connection, credentials_t* credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  int ret;
  entity_t entity = NULL;
  char *html, *response = NULL, *truefalse;
  const char *no_redirect, *method;

  if (params_value (params, "enable")
      && (strcmp (params_value (params, "enable"), "1") == 0))
    truefalse = "true";
  else
    truefalse = "false";

  no_redirect = params_value (params, "no_redirect");
  method = params_value (params, "group");
  CHECK_PARAM_INVALID (method, "Save Authentication", "get_users");
  if (!strcmp (method, "method:ldap_connect"))
    {
      const char *ldaphost, *authdn, *certificate;
      ldaphost = params_value (params, "ldaphost");
      authdn = params_value (params, "authdn");
      certificate = params_value (params, "certificate");

      CHECK_PARAM_INVALID (ldaphost, "Save Authentication", "get_users");
      CHECK_PARAM_INVALID (authdn, "Save Authentication", "get_users");
      if (params_given (params, "certificate") && strcmp (certificate, ""))
        {
          CHECK_PARAM_INVALID (certificate, "Save Authentication", "get_users");
          /** @warning authdn shall contain a single %s, handle with care. */
          ret = ompf (connection, credentials, &response, &entity,
                      response_data,
                      "<modify_auth>"
                      "<group name=\"%s\">"
                      AUTH_CONF_SETTING ("enable", "%s")
                      AUTH_CONF_SETTING ("ldaphost", "%s")
                      AUTH_CONF_SETTING ("authdn", "%s")
                      AUTH_CONF_SETTING ("cacert", "%s")
                      "</group>"
                      "</modify_auth>", method, truefalse, ldaphost, authdn,
                      certificate);
        }
      else
        /** @warning authdn shall contain a single %s, handle with care. */
        ret = ompf (connection, credentials, &response, &entity, response_data,
                    "<modify_auth>"
                    "<group name=\"%s\">"
                    AUTH_CONF_SETTING ("enable", "%s")
                    AUTH_CONF_SETTING ("ldaphost", "%s")
                    AUTH_CONF_SETTING ("authdn", "%s")
                    "</group>"
                    "</modify_auth>", method, truefalse, ldaphost, authdn);
    }
  else if (!strcmp (method, "method:radius_connect"))
    {
      const char *radiushost, *radiuskey;
      radiushost = params_value (params, "radiushost");
      radiuskey = params_value (params, "radiuskey");

      CHECK_PARAM_INVALID (radiushost, "Save Authentication", "get_users");
      CHECK_PARAM_INVALID (radiuskey, "Save Authentication", "get_users");
      /** @warning authdn shall contain a single %s, handle with care. */
      ret = ompf (connection, credentials, &response, &entity, response_data,
                  "<modify_auth>"
                  "<group name=\"%s\">"
                  AUTH_CONF_SETTING ("enable", "%s")
                  AUTH_CONF_SETTING ("radiushost", "%s")
                  AUTH_CONF_SETTING ("radiuskey", "%s")
                  "</group>"
                  "</modify_auth>", method, truefalse, radiushost, radiuskey);
    }
  else
    return get_users (connection, credentials, params,
                      GSAD_MESSAGE_INVALID_PARAM
                       ("Save Authentication Configuration"),
                      response_data);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving the auth settings. "
                             "The settings were not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_users", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving the auth settings. "
                             "It is unclear whether the settings have been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_users", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving the auth settings. "
                             "It is unclear whether the settings have been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_users", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, NULL,
                               NULL, "modify_auth",
                               "Save Authentication Configuration",
                               response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Save chart preferences.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  pref_id        Preference ID.
 * @param[in]  pref_value     Preference value.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return SAVE_CHART_PREFERENCE OMP response.
 */
char*
save_chart_preference_omp (openvas_connection_t *connection,
                           credentials_t* credentials, params_t *params,
                           gchar **pref_id, gchar **pref_value,
                           cmd_response_data_t* response_data)
{
  *pref_id = g_strdup (params_value (params, "chart_preference_id"));
  *pref_value = g_strdup (params_value (params, "chart_preference_value"));

  gchar* value_64 = g_base64_encode ((guchar*)*pref_value,
                                     strlen (*pref_value));
  gchar* response;
  entity_t entity;
  int ret;

  if (*pref_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return ("<save_chart_preference_response"
              " status=\"400\" status_text=\"Invalid or missing name\"/>");
    }
  if (*pref_value == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return ("<save_chart_preference_response"
              " status=\"400\" status_text=\"Invalid or missing value\"/>");
    }

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials, &response, &entity, response_data,
              "<modify_setting setting_id=\"%s\">"
              "<value>%s</value>"
              "</modify_setting>",
              *pref_id, value_64);
  g_free (value_64);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving settings. "
                             "It is unclear whether all the settings were saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_my_settings", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving settings. "
                             "It is unclear whether all the settings were saved. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_my_settings", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving settings. "
                             "It is unclear whether all the settings were saved. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_my_settings", response_data);
    }

  if (omp_success (entity))
    {
      free_entity (entity);
      g_free (response);
      return ("<save_chart_preference_response"
              " status=\"200\" status_text=\"OK\"/>");
    }
  else
    {
      set_http_status_from_entity (entity, response_data);
      gchar* ret_response
        = g_strdup_printf("<save_chart_preference_response"
                          " status=\"%s\" status_text=\"%s\"/>",
                          entity_attribute (entity, "status"),
                          entity_attribute (entity, "status_text"));
      free_entity (entity);
      g_free (response);
      return ret_response;
    }
}


/* Wizards. */

/**
 * @brief Returns a wizard page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
wizard (openvas_connection_t *connection, credentials_t *credentials,
        params_t *params, const char *extra_xml,
        cmd_response_data_t* response_data)
{
  GString *xml;
  const char* name = params_value (params, "name");

  if (name == NULL)
    {
        response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting the wizard. "
                             "Given name was invalid",
                             "/omp?cmd=get_tasks", response_data);
    }

  xml = g_string_new ("");
  g_string_append_printf (xml,
                          "<wizard>%s<%s/>",
                          extra_xml ? extra_xml : "",
                          name);

  /* Try to run init mode of the wizard */
  if (openvas_connection_sendf_xml (connection,
                                    "<run_wizard read_only=\"1\">"
                                    "<name>%s</name>"
                                    "<mode>init</mode>"
                                    "</run_wizard>",
                                    name)
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the wizard. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the"
                           " wizard."
                           "Diagnostics: Failure to receive response from"
                           " manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Get the setting. */

  if (openvas_connection_sendf_xml (connection,
                                    "<get_settings"
                                    " setting_id=\"20f3034c-e709-11e1-87e7-406186ea4fc5\"/>")
      == -1)
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting the wizard. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (read_string_c (connection, &xml))
    {
      g_string_free (xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while the wizard. "
                           "Diagnostics: Failure to receive response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Cleanup, and return transformed XML. */

  g_string_append_printf (xml, "</wizard>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Returns a wizard page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
wizard_omp (openvas_connection_t *connection, credentials_t *credentials,
            params_t *params, cmd_response_data_t* response_data)
{
  return wizard (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Returns a wizard_get page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
wizard_get (openvas_connection_t *connection, credentials_t *credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  const char *name;
  int ret;
  GString *run;
  param_t *param;
  gchar *param_name, *response;
  params_iterator_t iter;
  params_t *wizard_params;
  entity_t entity;
  gchar *wizard_xml;

  /* The naming is a bit subtle here, because the HTTP request
   * parameters are called "param"s and so are the OMP wizard
   * parameters. */

  name = params_value (params, "get_name");
  if (name == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while trying to start a wizard. "
                           "Diagnostics: Required parameter 'get_name' was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  run = g_string_new ("<run_wizard read_only=\"1\">");

  g_string_append_printf (run,
                          "<name>%s</name>"
                          "<params>",
                          name);

  wizard_params = params_values (params, "event_data:");
  if (wizard_params)
    {
      params_iterator_init (&iter, wizard_params);
      while (params_iterator_next (&iter, &param_name, &param))
        xml_string_append (run,
                           "<param>"
                           "<name>%s</name>"
                           "<value>%s</value>"
                           "</param>",
                           param_name,
                           param->value);
    }

  g_string_append (run, "</params></run_wizard>");

  response = NULL;
  entity = NULL;
  ret = omp (connection, credentials, &response, &entity, response_data,
             run->str);
  g_string_free (run, TRUE);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while running a wizard. "
                             "The wizard did not start. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while running a wizard. "
                             "It is unclear whether the wizard started or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while running a wizard. "
                             "It is unclear whether the wizard started or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  wizard_xml = g_strdup_printf ("<wizard><%s/>%s%s</wizard>",
                                name,
                                extra_xml ? extra_xml : "",
                                response);

  return xsl_transform_omp (connection, credentials, params, wizard_xml,
                            response_data);
}

/**
 * @brief Returns a wizard_get page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
wizard_get_omp (openvas_connection_t *connection, credentials_t *credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return wizard_get (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Returns a process_bulk page.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Credentials of user issuing the action.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
process_bulk_omp (openvas_connection_t *connection, credentials_t *credentials,
                  params_t *params, enum content_type *content_type,
                  char **content_disposition, gsize *content_length,
                  cmd_response_data_t* response_data)
{
  GString *bulk_string;
  const char *type, *subtype, *action;
  char *param_name;
  params_t *selected_ids;
  param_t *param;
  params_iterator_t iter;

  type = params_value (params, "resource_type");
  if (type == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while performing a bulk action. "
                           "Diagnostics: Required parameter 'resource_type' was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }
  if (strcmp (type, "info") == 0)
    {
      subtype = params_value (params, "info_type");
      if (subtype == NULL)
        {
          response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
          return gsad_message (credentials,
                               "Internal error", __FUNCTION__, __LINE__,
                               "An internal error occurred while performing a bulk action. "
                               "Diagnostics: Required parameter 'info_type' was NULL.",
                               "/omp?cmd=get_tasks", response_data);
        }
    }
  else
    subtype = NULL;

  if (params_valid (params, "bulk_create.x"))
    action = "create";
  else if (params_valid (params, "bulk_delete.x"))
    action = "delete";
  else if (params_valid (params, "bulk_export.x"))
    action = "export";
  else if (params_value (params, "bulk_trash.x"))
    action = "trash";
  else
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while performing a bulk action. "
                           "Diagnostics: Could not determine the action.",
                           "/omp?cmd=get_tasks", response_data);
    }

  if (strcmp (action, "create") == 0)
    {
      if (params_value (params, "bulk_select")
          && strcmp (params_value (params, "bulk_select"), "1") == 0)
        {
          bulk_string = g_string_new ("first=1 rows=-1");

          selected_ids = params_values (params, "bulk_selected:");
          if (selected_ids)
            {
              params_iterator_init (&iter, selected_ids);
              while (params_iterator_next (&iter, &param_name, &param))
                xml_string_append (bulk_string,
                                   " uuid=%s",
                                   param_name);
            }
        }
      else if (params_value (params, "bulk_select")
               && strcmp (params_value (params, "bulk_select"), "2") == 0)
        {
          bulk_string = g_string_new ("first=1 rows=-1 ");
          g_string_append (bulk_string, params_value (params, "filter") ? : "");
        }
      else
        {
          bulk_string = g_string_new (params_value (params, "filter") ? : "");
        }
      param = params_add (params, "hosts_filter", bulk_string->str);
      param->valid = 1;
      param->valid_utf8 = g_utf8_validate (param->value, -1, NULL);
      g_string_free (bulk_string, TRUE);

      return new_target (connection, credentials, params, NULL, response_data);
    }

  if (strcmp (action, "export") == 0)
    {
      if (params_value (params, "bulk_select")
          && strcmp (params_value (params, "bulk_select"), "1") == 0)
        {
          bulk_string
            = g_string_new ("first=1 rows=-1 uuid=");

          selected_ids = params_values (params, "bulk_selected:");
          if (selected_ids)
            {
              params_iterator_init (&iter, selected_ids);
              while (params_iterator_next (&iter, &param_name, &param))
                xml_string_append (bulk_string,
                                  " uuid=%s",
                                  param_name);
            }
        }
      else if (params_value (params, "bulk_select")
               && strcmp (params_value (params, "bulk_select"), "2") == 0)
        {
          bulk_string
            = g_string_new ("first=1 rows=-1 ");
          g_string_append (bulk_string, params_value (params, "filter") ? : "");
        }
      else
        {
          bulk_string
            = g_string_new (params_value (params, "filter") ? : "");
        }
      params_add (params, "filter", g_string_free (bulk_string, FALSE));

      return export_many (connection, type, credentials, params, content_type,
                          content_disposition, content_length, response_data);
    }

  bulk_string = g_string_new ("<process_bulk>");

  g_string_append_printf (bulk_string,
                          "<type>%s</type>"
                          "<action>%s</action>",
                          type,
                          action);

  g_string_append (bulk_string, "<selections>");

  if (params_value (params, "bulk_select")
      && strcmp (params_value (params, "bulk_select"), "2") == 0)
    {
      int ret;
      entity_t entity;
      gchar *response;

      ret = ompf (connection, credentials, &response, &entity, response_data,
                  "<get_%ss filter=\"first=1 rows=-1 %s\"/>",
                  type,
                  params_value (params, "filter") ? : "");

      if (ret)
        {
          free_entity (entity);
          g_free (response);
          g_string_free (bulk_string, TRUE);
        }
      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a"
                                " resources list. "
                                "Diagnostics: Failure to send command to"
                                " manager daemon.",
                                "/omp?cmd=get_my_settings", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a"
                                " resources list. "
                                "Diagnostics: Failure to receive response from"
                                " manager daemon.",
                                "/omp?cmd=get_my_settings", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a"
                                " resources list. "
                                "Diagnostics: Internal Error.",
                                "/omp?cmd=get_my_settings", response_data);
        }

      entities_t entities = entity->entities;
      entity_t child_entity;

      while ((child_entity = first_entity (entities)))
        {
          if (strcmp (entity_name (child_entity), type) == 0)
            {
              const char *resource_id
                = entity_attribute (child_entity, "id");

              if (resource_id)
                xml_string_append (bulk_string,
                                   "<selection id=\"%s\" />",
                                   resource_id);
            }
          entities = next_entities (entities);
        }
    }
  else
    {
      selected_ids = params_values (params, "bulk_selected:");
      if (selected_ids)
        {
          params_iterator_init (&iter, selected_ids);
          while (params_iterator_next (&iter, &param_name, &param))
            xml_string_append (bulk_string,
                              "<selection id=\"%s\" />",
                              param_name);
        }
    }
  g_string_append (bulk_string, "</selections>");

  if (strcmp (action, "delete") == 0 && strcmp (type, "user") == 0)
    {
      int ret;
      entity_t entity;
      gchar *response;

      ret = ompf (connection, credentials, &response, &entity, response_data,
                  "<get_users filter=\"first=1 rows=-1\"/>",
                  type,
                  params_value (params, "filter") ? : "");

      if (ret)
        {
          free_entity (entity);
          g_free (response);
          g_string_free (bulk_string, TRUE);
        }
      switch (ret)
        {
          case 0:
          case -1:
            break;
          case 1:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a"
                                " resources list. "
                                "Diagnostics: Failure to send command to"
                                " manager daemon.",
                                "/omp?cmd=get_my_settings", response_data);
          case 2:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a"
                                " resources list. "
                                "Diagnostics: Failure to receive response from"
                                " manager daemon.",
                                "/omp?cmd=get_my_settings", response_data);
          default:
            response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
            return gsad_message (credentials,
                                "Internal error", __FUNCTION__, __LINE__,
                                "An internal error occurred while getting a"
                                " resources list. "
                                "Diagnostics: Internal Error.",
                                "/omp?cmd=get_my_settings", response_data);
        }

      g_string_append (bulk_string, response);
      free_entity (entity);
      g_free (response);
    }

  g_string_append (bulk_string, "</process_bulk>");

  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (bulk_string, FALSE), response_data);
}

/**
 * @brief Delete multiple resources, get next page, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
bulk_delete_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  const char *no_redirect, *type;
  GString *commands_xml;
  params_t *selected_ids;
  params_iterator_t iter;
  param_t *param;
  gchar *param_name;
  gchar *html, *response;
  entity_t entity;
  gchar *extra_attribs;

  no_redirect = params_value (params, "no_redirect");
  type = params_value (params, "resource_type");
  if (type == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while deleting resources. "
                           "The resources were not deleted. "
                           "Diagnostics: Required parameter 'resource_type' was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Extra attributes */
  extra_attribs = NULL;

  /* Inheritor of user's resource */
  if (strcmp (type, "user") == 0)
    {
      const char* inheritor_id;
      inheritor_id = params_value (params, "inheritor_id");
      if (inheritor_id)
        extra_attribs = g_strdup_printf ("inheritor_id=\"%s\"", inheritor_id);
    }

  commands_xml = g_string_new ("<commands>");

  selected_ids = params_values (params, "bulk_selected:");
  if (selected_ids)
    {
      params_iterator_init (&iter, selected_ids);
      while (params_iterator_next (&iter, &param_name, &param))
        {
          xml_string_append (commands_xml,
                            "<delete_%s %s_id=\"%s\" ultimate=\"0\"",
                            type,
                            type,
                            param_name);
          if (extra_attribs)
            g_string_append_printf (commands_xml, " %s/>", extra_attribs);
          else
            g_string_append (commands_xml, "/>");
        }
    }

  g_string_append (commands_xml, "</commands>");

  /* Delete the resources and get all resources. */

  if (openvas_connection_sendf_xml (connection,
                                    commands_xml->str)
      == -1)
    {
      g_string_free (commands_xml, TRUE);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while deleting resources. "
                           "The resources were not deleted. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }
  g_string_free (commands_xml, TRUE);

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, &response))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while deleting resources. "
                           "It is unclear whether the resources have been deleted or not. "
                           "Diagnostics: Failure to read response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Cleanup, and return transformed XML. */

  if (params_given (params, "next") == 0)
    {
      gchar *next;
      next = g_strdup_printf ("get_%ss", type);
      params_add (params, "next", next);
      g_free (next);
    }
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, NULL,
                               NULL, NULL,
                               "Bulk Delete", response_data);
  g_free (response);
  free_entity (entity);

  return html;
}


/* Assets. */

/**
 * @brief Returns page to create a new host.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials of user issuing the action.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
new_host (openvas_connection_t *connection, credentials_t *credentials,
          params_t *params, const char *extra_xml,
          cmd_response_data_t* response_data)
{
  GString *xml;
  xml = g_string_new ("<new_host>");
  if (extra_xml)
    g_string_append (xml, extra_xml);
  g_string_append (xml, "</new_host>");
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Return the new host page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
new_host_omp (openvas_connection_t *connection, credentials_t *credentials,
              params_t *params, cmd_response_data_t* response_data)
{
  return new_host (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create a host, serve next page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_host_omp (openvas_connection_t *connection, credentials_t * credentials,
                 params_t *params, cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect, *name, *comment;
  entity_t entity;
  GString *xml;

  no_redirect = params_value (params, "no_redirect");

  name = params_value (params, "name");
  CHECK_PARAM_INVALID (name, "Create Host", "new_host");

  comment = params_value (params, "comment");
  CHECK_PARAM_INVALID (comment, "Create Host", "new_host");

  /* Create the host. */

  xml = g_string_new ("");

  xml_string_append (xml,
                     "<create_asset>"
                     "<asset>"
                     "<type>host</type>"
                     "<name>%s</name>"
                     "<comment>%s</comment>"
                     "</asset>"
                     "</create_asset>",
                     name,
                     comment);

  ret = omp (connection, credentials,
             &response,
             &entity,
             response_data,
             xml->str);
  g_string_free (xml, TRUE);
  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new host. "
                            "No new host was created. "
                            "Diagnostics: Failure to send command to manager daemon.",
                            "/omp?cmd=get_assets", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new host. "
                            "It is unclear whether the host has been created or not. "
                            "Diagnostics: Failure to receive response from manager daemon.",
                            "/omp?cmd=get_assets", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                            "Internal error", __FUNCTION__, __LINE__,
                            "An internal error occurred while creating a new host. "
                            "It is unclear whether the host has been created or not. "
                            "Diagnostics: Internal Error.",
                            "/omp?cmd=get_assets", response_data);
    }

  if (entity_attribute (entity, "id"))
    params_add (params, "asset_id", entity_attribute (entity, "id"));
  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_assets",
                               NULL, "new_host",
                               "Create Host", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Request an asset.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials for the manager connection.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return XSL transformed asset response or error message.
 */
char *
get_asset (openvas_connection_t *connection, credentials_t *credentials,
           params_t *params, const char *extra_xml,
           cmd_response_data_t* response_data)
{
  char *ret;
  GString *extra_attribs, *extra_response;
  const char *asset_type;

  asset_type = params_value (params, "asset_type");
  if (asset_type == NULL)
    {
      param_t *param;
      param = params_add (params, "asset_type", "host");
      param->valid = 1;
      param->valid_utf8 = g_utf8_validate (param->value, -1, NULL);
      asset_type = params_value (params, "asset_type");
    }

  if (strcmp (asset_type, "host")
      && strcmp (asset_type, "os"))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting an asset. "
                           "Diagnostics: Invalid asset_type parameter value",
                           "/omp?cmd=get_asset", response_data);
    }

  if (params_value (params, "asset_name")
      && params_value (params, "asset_id"))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting an asset. "
                           "Diagnostics: Both ID and Name set.",
                           "/omp?cmd=get_asset", response_data);
    }

  extra_response = g_string_new (extra_xml ? extra_xml : "");

  extra_attribs = g_string_new ("");
  g_string_append_printf (extra_attribs, "type=\"%s\"",
                          params_value (params, "asset_type"));
  if (params_value (params, "asset_name"))
    g_string_append_printf (extra_attribs,
                            " name=\"%s\"",
                            params_value (params, "asset_name"));
  else if (params_value (params, "asset_id"))
    g_string_append_printf (extra_attribs,
                            " asset_id=\"%s\"",
                            params_value (params, "asset_id"));
  if (params_value (params, "details"))
    g_string_append_printf (extra_attribs,
                            " details=\"%s\"",
                            params_value (params, "details"));

  ret = get_one (connection, "asset", credentials, params, extra_response->str,
                 extra_attribs->str, response_data);

  g_string_free (extra_response, TRUE);
  g_string_free (extra_attribs, TRUE);

  return ret;
}

/**
 * @brief Get asset, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_asset_omp (openvas_connection_t *connection, credentials_t * credentials,
               params_t *params, cmd_response_data_t* response_data)
{
  return get_asset (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Request assets.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Credentials for the manager connection.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return XSL transformed assets response or error message.
 */
char *
get_assets (openvas_connection_t *connection, credentials_t *credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  char *ret;
  GString *extra_attribs, *extra_response;
  const char *asset_type;

  asset_type = params_value (params, "asset_type");
  if (asset_type == NULL)
    {
      param_t *param;
      param = params_add (params, "asset_type", "host");
      param->valid = 1;
      param->valid_utf8 = g_utf8_validate (param->value, -1, NULL);
      asset_type = params_value (params, "asset_type");
    }

  if (strcmp (asset_type, "host")
      && strcmp (asset_type, "os"))
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while getting Assets. "
                           "Diagnostics: Invalid asset_type parameter value",
                           "/omp?cmd=get_assets", response_data);
    }

  extra_response = g_string_new (extra_xml ? extra_xml : "");

  extra_attribs = g_string_new("");
  g_string_append_printf (extra_attribs, "type=\"%s\" ignore_pagination=\"%s\"",
                          params_value (params, "asset_type"),
                          params_value (params, "ignore_pagination")
                            ? params_value (params, "ignore_pagination")
                            : "0");
  if (params_value (params, "details"))
    g_string_append_printf (extra_attribs,
                            " details=\"%s\"",
                            params_value (params, "details"));
  ret = get_many (connection, "asset", credentials, params, extra_response->str,
                  extra_attribs->str, response_data);

  g_string_free (extra_response, TRUE);
  g_string_free (extra_attribs, TRUE);

  return ret;
}

/**
 * @brief Get assets, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_assets_omp (openvas_connection_t *connection, credentials_t * credentials,
                params_t *params, cmd_response_data_t* response_data)
{
  return get_assets (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Create an asset, get report, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
create_asset_omp (openvas_connection_t *connection, credentials_t *credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  char *ret;
  gchar *response;
  const char *no_redirect, *report_id, *filter;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  report_id = params_value (params, "report_id");
  filter = params_value (params, "filter");

  CHECK_PARAM_INVALID (report_id, "Create Asset", "get_report_section");
  CHECK_PARAM_INVALID (filter, "Create Asset", "get_report_section");

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<create_asset>"
                "<report id=\"%s\">"
                "<filter><term>%s</term></filter>"
                "</report>"
                "</create_asset>",
                report_id,
                filter))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating an asset. "
                             "No new asset was created. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating an asset. "
                             "It is unclear whether the asset has been created or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_tasks", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while creating an asset. "
                             "It is unclear whether the asset has been created or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_tasks", response_data);
    }

  ret = response_from_entity (connection, credentials, params, entity,
                              (no_redirect && strcmp (no_redirect, "0")),
                              NULL, "get_report_section",
                              NULL, "get_report_section",
                              "Create Asset", response_data);
  free_entity (entity);
  g_free (response);
  return ret;
}

/**
 * @brief Delete an asset, go to the next page.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
delete_asset_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, cmd_response_data_t* response_data)
{
  gchar *html, *response, *resource_id;
  const char *next_id, *no_redirect;
  entity_t entity;
  gchar *next_url;

  if (params_value (params, "asset_id"))
    resource_id = g_strdup (params_value (params, "asset_id"));
  else if (params_value (params, "report_id"))
    resource_id = g_strdup (params_value (params, "report_id"));
  else
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while deleting an asset. "
                           "The asset was not deleted. "
                           "Diagnostics: Required parameter was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* This is a hack, needed because asset_id is the param name used for
   * both the asset being deleted and the asset on the next page. */
  next_id = params_value (params, "next_id");
  if (next_id
      && params_value (params, "asset_id"))
    {
      param_t *param;
      param = params_get (params, "asset_id");
      g_free (param->value);
      param->value = g_strdup (next_id);
      param->value_size = strlen (param->value);
    }

  /* Delete the resource and get all resources. */

  if (openvas_connection_sendf (connection,
                                "<delete_asset %s_id=\"%s\"/>",
                                params_value (params, "asset_id")
                                 ? "asset" : "report",
                                resource_id)
      == -1)
    {
      g_free (resource_id);
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while deleting an asset. "
                           "The asset is not deleted. "
                           "Diagnostics: Failure to send command to manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  g_free (resource_id);

  entity = NULL;
  if (read_entity_and_text_c (connection, &entity, &response))
    {
      response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while deleting an asset. "
                           "It is unclear whether the asset has been deleted or not. "
                           "Diagnostics: Failure to read response from manager daemon.",
                           "/omp?cmd=get_tasks", response_data);
    }

  /* Cleanup, and return transformed XML. */

  if (params_given (params, "next") == 0)
    params_add (params, "next", "get_asset");

  no_redirect = params_value (params, "no_redirect");
  if (no_redirect && strcmp (no_redirect, "0"))
    {
      html = next_page (connection, credentials, params, response,
                        response_data);
      if (html == NULL)
        {
          response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
          html = gsad_message (credentials,
              "Internal error", __FUNCTION__, __LINE__,
              "An internal error occurred while deleting an "
              "asset. Diagnostics: Error in parameter next.",
              "/omp?cmd=get_tasks", response_data);
        }
    }
  else
    {
      next_url = next_page_url (credentials, params,
          NULL, "get_asset", "delete_asset",
          entity_attribute (entity, "status"),
          entity_attribute (entity, "status_text"));
      response_data->redirect = next_url;

      html = NULL;
    }

  g_free (response);
  free_entity (entity);
  return html;
}

/**
 * @brief Export an asset.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Asset XML on success.  HTML result of XSL transformation on error.
 */
char *
export_asset_omp (openvas_connection_t *connection, credentials_t * credentials,
                  params_t *params, enum content_type * content_type,
                  char **content_disposition, gsize *content_length,
                  cmd_response_data_t* response_data)
{
  return export_resource (connection, "asset", credentials, params,
                          content_type, content_disposition, content_length,
                          response_data);
}

/**
 * @brief Export a list of assets.
 *
 * @param[in]   connection           Connection to manager
 * @param[in]   credentials          Username and password for authentication.
 * @param[in]   params               Request parameters.
 * @param[out]  content_type         Content type return.
 * @param[out]  content_disposition  Content disposition return.
 * @param[out]  content_length       Content length return.
 * @param[out]  response_data        Extra data return for the HTTP response.
 *
 * @return Assets XML on success.  HTML result of XSL transformation
 *         on error.
 */
char *
export_assets_omp (openvas_connection_t *connection,
                   credentials_t * credentials, params_t *params,
                   enum content_type * content_type, char **content_disposition,
                   gsize *content_length, cmd_response_data_t* response_data)
{
  return export_many (connection, "asset", credentials, params, content_type,
                      content_disposition, content_length, response_data);
}

/**
 * @brief Setup edit XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[in]  extra_xml      Extra XML to insert inside page element.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_asset (openvas_connection_t *connection, credentials_t *credentials,
            params_t *params, const char *extra_xml,
            cmd_response_data_t* response_data)
{
  GString *xml;
  const char *asset_id;
  gchar *response;
  entity_t entity;

  asset_id = params_value (params, "asset_id");
  if (asset_id == NULL)
    {
      response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
      return gsad_message (credentials,
                           "Internal error", __FUNCTION__, __LINE__,
                           "An internal error occurred while editing a asset. "
                           "The asset remains as it was. "
                           "Diagnostics: Required ID parameter was NULL.",
                           "/omp?cmd=get_tasks", response_data);
    }

  xml = g_string_new ("");

  g_string_append_printf (xml, "<edit_asset>");

  if (extra_xml)
    g_string_append (xml, extra_xml);

  response = NULL;
  entity = NULL;
  switch (ompf (connection, credentials,
                &response,
                &entity,
                response_data,
                "<get_assets"
                " type=\"host\""
                " asset_id=\"%s\""
                " details=\"1\"/>",
                asset_id))
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        g_string_free (xml, TRUE);
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting the asset. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_assets", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        g_string_free (xml, TRUE);
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting the asset. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_assets", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        g_string_free (xml, TRUE);
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while getting the asset. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_assets", response_data);
    }

  g_string_append (xml, response);
  g_string_append_printf (xml, "</edit_asset>");
  free_entity (entity);
  g_free (response);
  return xsl_transform_omp (connection, credentials, params,
                            g_string_free (xml, FALSE), response_data);
}

/**
 * @brief Setup edit_asset XML, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
edit_asset_omp (openvas_connection_t *connection,
                credentials_t * credentials, params_t *params,
                cmd_response_data_t* response_data)
{
  return edit_asset (connection, credentials, params, NULL, response_data);
}

/**
 * @brief Modify an asset, get all assets, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
save_asset_omp (openvas_connection_t *connection,
                credentials_t * credentials, params_t *params,
                cmd_response_data_t* response_data)
{
  int ret;
  gchar *html, *response;
  const char *no_redirect, *asset_id, *comment;
  entity_t entity;

  no_redirect = params_value (params, "no_redirect");
  asset_id = params_value (params, "asset_id");
  comment = params_value (params, "comment");

  CHECK_PARAM_INVALID (asset_id, "Save Asset", "edit_asset");
  CHECK_PARAM_INVALID (comment, "Save Asset", "edit_asset");

  /* Modify the asset. */

  response = NULL;
  entity = NULL;
  ret = ompf (connection, credentials,
              &response,
              &entity,
              response_data,
              "<modify_asset asset_id=\"%s\">"
              "<comment>%s</comment>"
              "</modify_asset>",
              asset_id,
              comment);

  switch (ret)
    {
      case 0:
      case -1:
        break;
      case 1:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving an asset. "
                             "The asset was not saved. "
                             "Diagnostics: Failure to send command to manager daemon.",
                             "/omp?cmd=get_assets", response_data);
      case 2:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving an asset. "
                             "It is unclear whether the asset has been saved or not. "
                             "Diagnostics: Failure to receive response from manager daemon.",
                             "/omp?cmd=get_assets", response_data);
      default:
        response_data->http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
        return gsad_message (credentials,
                             "Internal error", __FUNCTION__, __LINE__,
                             "An internal error occurred while saving an asset. "
                             "It is unclear whether the asset has been saved or not. "
                             "Diagnostics: Internal Error.",
                             "/omp?cmd=get_assets", response_data);
    }

  html = response_from_entity (connection, credentials, params, entity,
                               (no_redirect && strcmp (no_redirect, "0")),
                               NULL, "get_assets",
                               NULL, "edit_asset",
                               "Save Asset", response_data);
  free_entity (entity);
  g_free (response);
  return html;
}

/**
 * @brief Get an assets chart, XSL transform the result.
 *
 * @param[in]  connection        Connection to manager
 * @param[in]  credentials       Username and password for authentication.
 * @param[in]  params            Request parameters.
 * @param[in]  extra_xml         Extra XML to insert inside page element.
 * @param[out] response_data     Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
static char *
get_assets_chart (openvas_connection_t *connection, credentials_t *credentials,
                  params_t *params, const char *extra_xml,
                  cmd_response_data_t* response_data)
{
  return xsl_transform_omp (connection, credentials, params,
                            g_strdup ("<get_assets_chart/>"), response_data);
}

/**
 * @brief Get an assets chart, XSL transform the result.
 *
 * @param[in]  connection     Connection to manager
 * @param[in]  credentials    Username and password for authentication.
 * @param[in]  params         Request parameters.
 * @param[out] response_data  Extra data return for the HTTP response.
 *
 * @return Result of XSL transformation.
 */
char *
get_assets_chart_omp (openvas_connection_t *connection,
                      credentials_t * credentials, params_t *params,
                      cmd_response_data_t* response_data)
{
  return get_assets_chart (connection, credentials, params, NULL,
                           response_data);
}


/* Manager communication. */

/**
 * @brief Connect to OpenVAS Manager daemon.
 *
 * @param[in]  path  Path to the Manager socket.
 *
 * @return Socket, or -1 on error.
 */
int
connect_unix (const gchar *path)
{
  struct sockaddr_un address;
  int sock;

  /* Make socket. */

  sock = socket (AF_UNIX, SOCK_STREAM, 0);
  if (sock == -1)
    {
      g_warning ("Failed to create server socket");
      return -1;
    }

  /* Connect to server. */

  address.sun_family = AF_UNIX;
  strncpy (address.sun_path, path, sizeof (address.sun_path) - 1);
  if (connect (sock, (struct sockaddr *) &address, sizeof (address)) == -1)
    {
      g_warning ("Failed to connect to server: %s", strerror (errno));
      close (sock);
      return -1;
    }

  return sock;
}

/**
 * @brief Connect to an address.
 *
 * @param[out]  connection  Connection.
 * @param[out]  address     Address.
 * @param[out]  port        Port.
 *
 * @return 0 success, -1 failed to connect.
 */
int
openvas_connection_open (openvas_connection_t *connection,
                         const gchar *address,
                         int port)
{
  if (address == NULL)
    return -1;

  connection->tls = manager_use_tls;

  if (manager_use_tls)
    {
      connection->socket = openvas_server_open (&connection->session,
                                                address,
                                                port);
      connection->credentials = NULL;
    }
  else
    connection->socket = connect_unix (address);

  if (connection->socket == -1)
    return -1;

  return 0;
}

/**
 * @brief Check authentication credentials.
 *
 * @param[in]  username      Username.
 * @param[in]  password      Password.
 * @param[out] role          Role.
 * @param[out] timezone      Timezone.
 * @param[out] severity      Severity class.
 * @param[out] capabilities  Capabilities of manager.
 * @param[out] language      User Interface Language, or NULL.
 * @param[out] pw_warning    Password warning message, NULL if password is OK.
 * @param[out] chart_prefs   Chart preferences.
 * @param[out] autorefresh   Autorefresh preference.
 *
 * @return 0 if valid, 1 failed, 2 manager down, -1 error.
 */
int
authenticate_omp (const gchar * username, const gchar * password,
                  gchar **role, gchar **timezone, gchar **severity,
                  gchar **capabilities, gchar **language, gchar **pw_warning,
                  GTree **chart_prefs, gchar **autorefresh)
{
  openvas_connection_t connection;
  int auth;
  omp_authenticate_info_opts_t auth_opts;

  if (openvas_connection_open (&connection,
                               manager_address,
                               manager_port))
    {
      g_debug ("%s failed to acquire socket!\n", __FUNCTION__);
      return 2;
    }

#ifdef DEBUG_AUTH
  /* Enable this if you need the CGI to sleep after launch. This can be useful
   * if you need to attach to manager process the CGI is talking to for
   * debugging purposes.
   *
   * It's probably easier to run gsad in the foreground under gdb and
   * set a break point here.
   */
  g_debug ("Sleeping!");
  sleep (20);
#endif

  auth_opts = omp_authenticate_info_opts_defaults;
  auth_opts.username = username;
  auth_opts.password = password;
  auth_opts.role = role;
  auth_opts.severity = severity;
  auth_opts.timezone = timezone;
  auth_opts.pw_warning = pw_warning;

  auth = omp_authenticate_info_ext_c (&connection, auth_opts);
  if (auth == 0)
    {
      entity_t entity;
      const char* status;
      char first;
      gchar *response;
      int ret;

      /* Get language setting. */

      ret = setting_get_value (&connection,
                               "6765549a-934e-11e3-b358-406186ea4fc5",
                               language,
                               NULL);

      switch (ret)
        {
          case 0:
            break;
          case 1:
          case 2:
            openvas_connection_close (&connection);
            return 2;
          default:
            openvas_connection_close (&connection);
            return -1;
        }

      /* Request help. */

      ret = openvas_connection_sendf (&connection,
                                      "<help format=\"XML\" type=\"brief\"/>");
      if (ret)
        {
          openvas_connection_close (&connection);
          return 2;
        }

      /* Read the response. */

      entity = NULL;
      if (read_entity_and_text_c (&connection, &entity, &response))
        {
          openvas_connection_close (&connection);
          return 2;
        }

      /* Check the response. */

      status = entity_attribute (entity, "status");
      if (status == NULL
          || strlen (status) == 0)
        {
          g_free (response);
          free_entity (entity);
          return -1;
        }
      first = status[0];
      free_entity (entity);
      if (first == '2')
        {
          *capabilities = response;
        }
      else
        {
          openvas_connection_close (&connection);
          g_free (response);
          return -1;
        }

      /* Get the chart preferences */

      ret = openvas_connection_sendf (&connection,
                                      "<get_settings"
                                      " filter='name~\"Dashboard\"'/>");
      if (ret)
        {
          openvas_connection_close (&connection);
          return 2;
        }

      /* Read the response */
      entity = NULL;
      if (read_entity_and_text_c (&connection, &entity, &response))
        {
          openvas_connection_close (&connection);
          return 2;
        }

      /* Check the response. */
      status = entity_attribute (entity, "status");
      if (status == NULL
          || strlen (status) == 0)
        {
          g_free (response);
          free_entity (entity);
          return -1;
        }
      first = status[0];
      if (first == '2')
        {
          entities_t entities = entity->entities;
          entity_t child_entity;
          *chart_prefs = g_tree_new_full ((GCompareDataFunc) g_strcmp0,
                                          NULL, g_free, g_free);

          while ((child_entity = first_entity (entities)))
            {
              if (strcmp (entity_name (child_entity), "setting") == 0)
                {
                  const char *setting_id
                    = entity_attribute (child_entity, "id");
                  const char *setting_value
                    = entity_text (entity_child (child_entity, "value"));

                  if (setting_id && setting_value)
                    g_tree_insert (*chart_prefs,
                                   g_strdup (setting_id),
                                   g_strdup (setting_value));
                }
              entities = next_entities (entities);
            }
          free_entity (entity);
          g_free (response);
        }
      else
        {
          free_entity (entity);
          g_free (response);
          openvas_connection_close (&connection);
          return -1;
        }

      /* Get autorefresh setting. */

      ret = setting_get_value (&connection,
                               "578a1c14-e2dc-45ef-a591-89d31391d007",
                               autorefresh,
                               NULL);

      switch (ret)
        {
          case 0:
            break;
          case 1:
          case 2:
            openvas_connection_close (&connection);
            return 2;
          default:
            openvas_connection_close (&connection);
            return -1;
        }

      openvas_connection_close (&connection);
      return 0;
    }
  else
    {
      openvas_connection_close (&connection);
      return 1;
    }
}

/**
 * @brief Connect to OpenVAS Manager daemon.
 *
 * If the Manager is down, logout and return the login HTML in \p html.
 *
 * @param[in]   credentials  Username and password for authentication.
 * @param[out]  connection   Connection to Manager on success.
 * @param[out]  response_data  Extra data return for the HTTP response.
 *
 * @return 0 success, -1 failed to connect, -2 authentication failed.
 */
int
manager_connect (credentials_t *credentials, openvas_connection_t *connection,
                 cmd_response_data_t *response_data)
{
  omp_authenticate_info_opts_t auth_opts;

  if (openvas_connection_open (connection,
                               manager_address,
                               manager_port))
    {
      response_data->http_status_code = MHD_HTTP_SERVICE_UNAVAILABLE;
      return -1;
    }

#if 0
  g_debug ("in manager_connect: Trying to authenticate with %s/%s\n",
           credentials->username,
           credentials->password);
#endif


  auth_opts = omp_authenticate_info_opts_defaults;
  auth_opts.username = credentials->username;
  auth_opts.password = credentials->password;
  if (omp_authenticate_info_ext_c (connection, auth_opts))
    {
      g_debug ("authenticate failed!\n");
      openvas_connection_close (connection);
      return -2;
    }

#ifdef DEBUG
  /* Enable this if you need the CGI to sleep after launch. This can be useful
   * if you need to attach to manager process the CGI is talking to for
   * debugging purposes.
   *
   * An easier method is to run gsad under gdb and set a breakpoint here.
   */
  g_debug ("Sleeping!");
  sleep (10);
#endif
  return 0;
}
