/* OpenVAS Manager - OMP Command Line Interface
 * $Id$
 * Description: Provides a command line client for the OpenVAS Manager
 *
 * Authors:
 * Michael Wiegand <michael.wiegand@intevation.de>
 * based on work by
 * Matthew Mundell <matt@mundell.ukfsn.org>
 *
 * Copyright:
 * Copyright (C) 2009 Greenbone Networks GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2,
 * or, at your option, any later version as published by the Free
 * Software Foundation
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */


/**
 * @file  omp-cli.c
 * @brief The OMP Command Line Interface
 *
 * TODO: Add documentation
 */

#include <glib.h>
#include <stdio.h>
#include <stdlib.h>

#include <openvas_server.h>
#include "common.h"
#include "corevers.h"

/**
 * @brief The name of this program.
 */
#define OMPCLI_PROGNAME "omp-cli"

/**
 * @brief The version number of this program.
 */
#ifndef OMPCLI_VERSION
#define OMPCLI_VERSION "0.0.1"
#endif

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

/**
 * @brief Default Server port.
 */
#define OPENVASMD_PORT 9391

int
main (int argc, char** argv)
{
  unsigned int manager_port;
  int socket;
  gnutls_session_t session;

  static gboolean print_version = FALSE;
  static gboolean be_verbose = FALSE;
  static gchar *manager_host_string = NULL;
  static gchar *manager_port_string = NULL;
  static gchar *command = NULL;
  static gchar *omp_command = NULL;
  static gchar *omp_username = "dummy";
  static gchar *omp_password = "dummy";

  GError *error = NULL;

  GOptionContext *option_context;
  static GOptionEntry option_entries[]
    = {
        { "host", 'h', 0, G_OPTION_ARG_STRING, &manager_host_string,
          "Connect to manager on host <host>", "<host>" },
        { "port", 'p', 0, G_OPTION_ARG_STRING, &manager_port_string,
          "Use port number <number>", "<number>" },
        { "version", 'V', 0, G_OPTION_ARG_NONE, &print_version,
          "Print version.", NULL },
        { "verbose", 'v', 0, G_OPTION_ARG_NONE, &be_verbose,
          "Verbose messages.", NULL },
        { "command", 'c', 0, G_OPTION_ARG_STRING, &command,
          "OMP command (e.g. \"<omp_version/>\", \"<get_nvt_feed_all/>\", \"<get_nvt_feed_checksum/>\")",
          "<command>" },
        { "username", 'u', 0, G_OPTION_ARG_STRING, &omp_username,
          "OMP username", "<username>" },
        { "password", 'w', 0, G_OPTION_ARG_STRING, &omp_password,
          "OMP password", "<password>" },
        { NULL }
      };

  option_context = g_option_context_new ("- OpenVAS OMP Command Line \
                                         Interface");
  g_option_context_add_main_entries (option_context, option_entries, NULL);
  if (!g_option_context_parse (option_context, &argc, &argv, &error))
    {
      printf ("%s\n\n", error->message);
      exit (EXIT_FAILURE);
    }

  if (print_version)
    {
      printf ("OMP Command Line Interface (%s) %s for %s\n",
              OMPCLI_PROGNAME, OMPCLI_VERSION, NESS_OS_NAME);
      printf ("Copyright (C) 2009 Greenbone Networks GmbH\n\n");
      exit (EXIT_SUCCESS);
    }

  if (manager_host_string == NULL)
    manager_host_string = OPENVASMD_ADDRESS;

  if (manager_port_string)
    {
      manager_port = atoi (manager_port_string);
      if (manager_port <= 0 || manager_port >= 65536)
        {
          fprintf (stderr, "Manager port must be a number between 0 and 65536.\n");
          exit (EXIT_FAILURE);
        }
    }
  else
    {
      manager_port = OPENVASMD_PORT;
    }

  if (command != NULL)
    {
      omp_command = g_strconcat (command, "\n", NULL);
    }
  else
    {
      printf ("No OMP command supplied, exiting.\n");
      exit (EXIT_FAILURE);
    }

  if (be_verbose)
    {
      printf ("Will try to connect to host %s, port %d...\n", manager_host_string,
              manager_port);
    }

  socket = openvas_server_open (&session, manager_host_string, manager_port);
  if (socket == -1)
    {
      fprintf (stderr, "Failed to acquire socket.\n");
      exit (EXIT_FAILURE);
    }

  if (authenticate (&session, omp_username, omp_password))
    {
      openvas_server_close (socket, session);
      fprintf (stderr, "Failed to authenticate.\n");
      exit (EXIT_FAILURE);
    }

  fprintf (stderr, "Sending to manager: %s", omp_command);

  if (openvas_server_send (&session, omp_command) == -1)
    {
      openvas_server_close (socket, session);
      fprintf (stderr, "Failed to send_to_manager.\n");
      exit (EXIT_FAILURE);
    }

  /* Read the response. */

  entity_t entity = NULL;
  if (read_entity (&session, &entity))
    {
      fprintf (stderr, "Failed to read response.\n");
      openvas_server_close (socket, session);
      exit (EXIT_FAILURE);
    }

  fprintf (stderr, "Got response:\n");
  print_entity (stderr, entity);
  fprintf (stderr, "\n");

  /* Cleanup. */

  openvas_server_close (socket, session);
  free_entity (entity);

  exit (EXIT_SUCCESS);
}
