/* -*- 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;
  void *new_connection_data;

  _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_invalidate (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);
    }

  if (server->published_address)
      _dbus_daemon_unpublish_session_bus_address();

  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 noncefile to be used for authentication (NULL if not needed)
 * @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);

  _dbus_server_trace_ref (&socket_server->base, 0, 1, "new_for_socket");
  return (DBusServer*) socket_server;

 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)
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          goto failed_2;
        }

      if (!_dbus_noncefile_create (noncefile, error))
          goto failed_3;

      if (!_dbus_string_append (&address, ",noncefile=") ||
          !_dbus_address_append_escaped (&address, _dbus_noncefile_get_path (noncefile)))
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          goto failed_4;
        }

    }

  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_4;
    }

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

  return server;

 failed_4:
  _dbus_noncefile_delete (noncefile, NULL);

 failed_3:
  dbus_free (noncefile);

 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;
}


/** @} */

