/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dbus-server-socket.c Server implementation for sockets
 *
 * Copyright (C) 2002, 2003, 2004, 2006  Red Hat Inc.
 *
 * Licensed under the Academic Free License version 2.1
 *
 * 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>
#include "dbus-internals.h"
#include "dbus-server-socket.h"
#include "dbus-transport-socket.h"
#include "dbus-connection-internal.h"
#include "dbus-memory.h"
#include "dbus-nonce.h"
#include "dbus-string.h"

/**
 * @defgroup DBusServerSocket DBusServer implementations for SOCKET
 * @ingroup  DBusInternals
 * @brief Implementation details of DBusServer on SOCKET
 *
 * @{
 */
/**
 *
 * Opaque object representing a Socket server implementation.
 */
typedef struct DBusServerSocket DBusServerSocket;

/**
 * Implementation details of DBusServerSocket. All members
 * are private.
 */
struct DBusServerSocket
{
  DBusServer base;   /**< Parent class members. */
  int n_fds;         /**< Number of active file handles */
  int *fds;          /**< File descriptor or -1 if disconnected. */
  DBusWatch **watch; /**< File descriptor watch. */
  char *socket_name; /**< Name of domain socket, to unlink if appropriate */
  DBusNonceFile *noncefile; /**< Nonce file used to authenticate clients */
};

static void
socket_finalize (DBusServer *server)
{
  DBusServerSocket *socket_server = (DBusServerSocket*) server;
  int i;

  _dbus_server_finalize_base (server);

  for (i = 0 ; i < socket_server->n_fds ; i++)
    if (socket_server->watch[i])
      {
        _dbus_watch_unref (socket_server->watch[i]);
        socket_server->watch[i] = NULL;
      }

  dbus_free (socket_server->fds);
  dbus_free (socket_server->watch);
  dbus_free (socket_server->socket_name);
  if (socket_server->noncefile)
	_dbus_noncefile_delete (socket_server->noncefile, NULL);
  dbus_free (socket_server->noncefile);
  dbus_free (server);
}

/* Return value is just for memory, not other failures. */
static dbus_bool_t
handle_new_client_fd_and_unlock (DBusServer *server,
                                 int         client_fd)
{
  DBusConnection *connection;
  DBusTransport *transport;
  DBusNewConnectionFunction new_connection_function;
  DBusServerSocket* socket_server;
  void *new_connection_data;

  socket_server = (DBusServerSocket*)server;
  _dbus_verbose ("Creating new client connection with fd %d\n", client_fd);

  HAVE_LOCK_CHECK (server);

  if (!_dbus_set_fd_nonblocking (client_fd, NULL))
    {
      SERVER_UNLOCK (server);
      return TRUE;
    }

  transport = _dbus_transport_new_for_socket (client_fd, &server->guid_hex, FALSE);
  if (transport == NULL)
    {
      _dbus_close_socket (client_fd, NULL);
      SERVER_UNLOCK (server);
      return FALSE;
    }

  if (!_dbus_transport_set_auth_mechanisms (transport,
                                            (const char **) server->auth_mechanisms))
    {
      _dbus_transport_unref (transport);
      SERVER_UNLOCK (server);
      return FALSE;
    }

  /* note that client_fd is now owned by the transport, and will be
   * closed on transport disconnection/finalization
   */

  connection = _dbus_connection_new_for_transport (transport);
  _dbus_transport_unref (transport);
  transport = NULL; /* now under the connection lock */

  if (connection == NULL)
    {
      SERVER_UNLOCK (server);
      return FALSE;
    }

  /* See if someone wants to handle this new connection, self-referencing
   * for paranoia.
   */
  new_connection_function = server->new_connection_function;
  new_connection_data = server->new_connection_data;

  _dbus_server_ref_unlocked (server);
  SERVER_UNLOCK (server);

  if (new_connection_function)
    {
      (* new_connection_function) (server, connection,
                                   new_connection_data);
    }
  dbus_server_unref (server);

  /* If no one grabbed a reference, the connection will die. */
  _dbus_connection_close_if_only_one_ref (connection);
  dbus_connection_unref (connection);

  return TRUE;
}

static dbus_bool_t
socket_handle_watch (DBusWatch    *watch,
                   unsigned int  flags,
                   void         *data)
{
  DBusServer *server = data;
  DBusServerSocket *socket_server = data;

#ifndef DBUS_DISABLE_ASSERT
  int i;
  dbus_bool_t found = FALSE;
#endif

  SERVER_LOCK (server);

#ifndef DBUS_DISABLE_ASSERT
  for (i = 0 ; i < socket_server->n_fds ; i++)
    {
      if (socket_server->watch[i] == watch)
        found = TRUE;
    }
  _dbus_assert (found);
#endif

  _dbus_verbose ("Handling client connection, flags 0x%x\n", flags);

  if (flags & DBUS_WATCH_READABLE)
    {
      int client_fd;
      int listen_fd;

      listen_fd = dbus_watch_get_socket (watch);

      if (socket_server->noncefile)
          client_fd = _dbus_accept_with_noncefile (listen_fd, socket_server->noncefile);
      else 
          client_fd = _dbus_accept (listen_fd);

      if (client_fd < 0)
        {
          /* EINTR handled for us */

          if (_dbus_get_is_errno_eagain_or_ewouldblock ())
            _dbus_verbose ("No client available to accept after all\n");
          else
            _dbus_verbose ("Failed to accept a client connection: %s\n",
                           _dbus_strerror_from_errno ());

          SERVER_UNLOCK (server);
        }
      else
        {
          if (!handle_new_client_fd_and_unlock (server, client_fd))
            _dbus_verbose ("Rejected client connection due to lack of memory\n");
        }
    }

  if (flags & DBUS_WATCH_ERROR)
    _dbus_verbose ("Error on server listening socket\n");

  if (flags & DBUS_WATCH_HANGUP)
    _dbus_verbose ("Hangup on server listening socket\n");

  return TRUE;
}

static void
socket_disconnect (DBusServer *server)
{
  DBusServerSocket *socket_server = (DBusServerSocket*) server;
  int i;

  HAVE_LOCK_CHECK (server);

  for (i = 0 ; i < socket_server->n_fds ; i++)
    {
      if (socket_server->watch[i])
        {
          _dbus_server_remove_watch (server,
                                     socket_server->watch[i]);
          _dbus_watch_unref (socket_server->watch[i]);
          socket_server->watch[i] = NULL;
        }

      _dbus_close_socket (socket_server->fds[i], NULL);
      socket_server->fds[i] = -1;
    }

  if (socket_server->socket_name != NULL)
    {
      DBusString tmp;
      _dbus_string_init_const (&tmp, socket_server->socket_name);
      _dbus_delete_file (&tmp, NULL);
    }

  HAVE_LOCK_CHECK (server);
}

static const DBusServerVTable socket_vtable = {
  socket_finalize,
  socket_disconnect
};

/**
 * Creates a new server listening on the given file descriptor.  The
 * file descriptor should be nonblocking (use
 * _dbus_set_fd_nonblocking() to make it so). The file descriptor
 * should be listening for connections, that is, listen() should have
 * been successfully invoked on it. The server will use accept() to
 * accept new client connections.
 *
 * @param fds list of file descriptors.
 * @param n_fds number of file descriptors
 * @param address the server's address
 * @param use_nonce whether to create and use a nonce for authentication
 * @returns the new server, or #NULL if no memory.
 *
 */
DBusServer*
_dbus_server_new_for_socket (int              *fds,
                             int               n_fds,
                             const DBusString *address,
                             DBusNonceFile    *noncefile)
{
  DBusServerSocket *socket_server;
  DBusServer *server;
  int i;

  socket_server = dbus_new0 (DBusServerSocket, 1);
  if (socket_server == NULL)
    return NULL;

  socket_server->noncefile = noncefile;

  socket_server->fds = dbus_new (int, n_fds);
  if (!socket_server->fds)
    goto failed_0;

  socket_server->watch = dbus_new0 (DBusWatch *, n_fds);
  if (!socket_server->watch)
    goto failed_1;

  for (i = 0 ; i < n_fds ; i++)
    {
      DBusWatch *watch;

      watch = _dbus_watch_new (fds[i],
                               DBUS_WATCH_READABLE,
                               TRUE,
                               socket_handle_watch, socket_server,
                               NULL);
      if (watch == NULL)
        goto failed_2;

      socket_server->n_fds++;
      socket_server->fds[i] = fds[i];
      socket_server->watch[i] = watch;
    }

  if (!_dbus_server_init_base (&socket_server->base,
                               &socket_vtable, address))
    goto failed_2;

  server = (DBusServer*)socket_server;

  SERVER_LOCK (server);

  for (i = 0 ; i < n_fds ; i++)
    {
      if (!_dbus_server_add_watch (&socket_server->base,
                                   socket_server->watch[i]))
        {
          int j;
          for (j = 0 ; j < i ; j++)
            _dbus_server_remove_watch (server,
                                       socket_server->watch[j]);

          SERVER_UNLOCK (server);
          _dbus_server_finalize_base (&socket_server->base);
          goto failed_2;
        }
    }

  SERVER_UNLOCK (server);

  return (DBusServer*) socket_server;

 failed_3:
  if (socket_server->noncefile)
    {
      _dbus_noncefile_delete (socket_server->noncefile, NULL);
      dbus_free (socket_server->noncefile );
    }
 failed_2:
  for (i = 0 ; i < n_fds ; i++)
    {
      if (socket_server->watch[i] != NULL)
        {
          _dbus_watch_unref (socket_server->watch[i]);
          socket_server->watch[i] = NULL;
        }
    }
  dbus_free (socket_server->watch);

 failed_1:
  dbus_free (socket_server->fds);

 failed_0:
  dbus_free (socket_server);
  return NULL;
}

/**
 * Creates a new server listening on TCP.
 * If host is NULL, it will default to localhost.
 * If bind is NULL, it will default to the value for the host
 * parameter, and if that is NULL, then localhost
 * If bind is a hostname, it will be resolved and will listen
 * on all returned addresses.
 * If family is NULL, hostname resolution will try all address
 * families, otherwise it can be ipv4 or ipv6 to restrict the
 * addresses considered.
 *
 * @param host the hostname to report for the listen address
 * @param bind the hostname to listen on
 * @param port the port to listen on or 0 to let the OS choose
 * @param family
 * @param error location to store reason for failure.
 * @param use_nonce whether to use a nonce for low-level authentication (nonce-tcp transport) or not (tcp transport)
 * @returns the new server, or #NULL on failure.
 */
DBusServer*
_dbus_server_new_for_tcp_socket (const char     *host,
                                 const char     *bind,
                                 const char     *port,
                                 const char     *family,
                                 DBusError      *error,
                                 dbus_bool_t    use_nonce)
{
  DBusServer *server;
  int *listen_fds = NULL;
  int nlisten_fds = 0, i;
  DBusString address;
  DBusString host_str;
  DBusString port_str;
  DBusNonceFile *noncefile;
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  noncefile = NULL;

  if (!_dbus_string_init (&address))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return NULL;
    }

  if (!_dbus_string_init (&port_str))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_0;
    }

  if (host == NULL)
    host = "localhost";

  if (port == NULL)
    port = "0";

  if (bind == NULL)
    bind = host;
  else if (strcmp (bind, "*") == 0)
    bind = NULL;

  nlisten_fds =_dbus_listen_tcp_socket (bind, port, family,
                                        &port_str,
                                        &listen_fds, error);
  if (nlisten_fds <= 0)
    {
      _DBUS_ASSERT_ERROR_IS_SET(error);
      goto failed_1;
    }

  _dbus_string_init_const (&host_str, host);
  if (!_dbus_string_append (&address, use_nonce ? "nonce-tcp:host=" : "tcp:host=") ||
      !_dbus_address_append_escaped (&address, &host_str) ||
      !_dbus_string_append (&address, ",port=") ||
      !_dbus_string_append (&address, _dbus_string_get_const_data(&port_str)))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_2;
    }
  if (family &&
      (!_dbus_string_append (&address, ",family=") ||
       !_dbus_string_append (&address, family)))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_2;
    }

  if (use_nonce)
    {
      noncefile = dbus_new0 (DBusNonceFile, 1);
      if (noncefile == NULL)
        {
          goto failed_2;
        }

      if (!_dbus_noncefile_create (noncefile, NULL))
          goto failed_2;

      if (!_dbus_string_append (&address, ",noncefile=") ||
          !_dbus_address_append_escaped (&address, _dbus_noncefile_get_path (noncefile)))
        {
          goto failed_2;
        }

    }

  server = _dbus_server_new_for_socket (listen_fds, nlisten_fds, &address, noncefile);
  if (server == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed_2;
    }

  _dbus_string_free (&port_str);
  _dbus_string_free (&address);
  dbus_free(listen_fds);

  return server;

 failed_2:
  for (i = 0 ; i < nlisten_fds ; i++)
    _dbus_close_socket (listen_fds[i], NULL);
  dbus_free(listen_fds);

 failed_1:
  _dbus_string_free (&port_str);

 failed_0:
  _dbus_string_free (&address);

  return NULL;
}

/**
 * Tries to interpret the address entry for various socket-related
 * addresses (well, currently only tcp and nonce-tcp).
 *
 * Sets error if the result is not OK.
 *
 * @param entry an address entry
 * @param server_p a new DBusServer, or #NULL on failure.
 * @param error location to store rationale for failure on bad address
 * @returns the outcome
 *
 */
DBusServerListenResult
_dbus_server_listen_socket (DBusAddressEntry *entry,
                            DBusServer      **server_p,
                            DBusError        *error)
{
  const char *method;

  *server_p = NULL;

  method = dbus_address_entry_get_method (entry);

  if (strcmp (method, "tcp") == 0 || strcmp (method, "nonce-tcp") == 0)
    {
      const char *host;
      const char *port;
      const char *bind;
      const char *family;

      host = dbus_address_entry_get_value (entry, "host");
      bind = dbus_address_entry_get_value (entry, "bind");
      port = dbus_address_entry_get_value (entry, "port");
      family = dbus_address_entry_get_value (entry, "family");

      *server_p = _dbus_server_new_for_tcp_socket (host, bind, port,
                                                   family, error, strcmp (method, "nonce-tcp") == 0 ? TRUE : FALSE);

      if (*server_p)
        {
          _DBUS_ASSERT_ERROR_IS_CLEAR(error);
          return DBUS_SERVER_LISTEN_OK;
        }
      else
        {
          _DBUS_ASSERT_ERROR_IS_SET(error);
          return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
        }
    }
  else
    {
      _DBUS_ASSERT_ERROR_IS_CLEAR(error);
      return DBUS_SERVER_LISTEN_NOT_HANDLED;
    }
}

/**
 * This is a bad hack since it's really unix domain socket
 * specific. Also, the function weirdly adopts ownership
 * of the passed-in string.
 *
 * @param server a socket server
 * @param filename socket filename to report/delete
 *
 */
void
_dbus_server_socket_own_filename (DBusServer *server,
                                  char       *filename)
{
  DBusServerSocket *socket_server = (DBusServerSocket*) server;

  socket_server->socket_name = filename;
}


/** @} */

