/* dbus-server-launchd.c Server methods for interacting with launchd.
 * Copyright (C) 2007, Tanner Lovelace <lovelace@wayfarer.org>
 * Copyright (C) 2008, Colin Walters <walters@verbum.org>
 * Copyright (C) 2008-2009, Benjamin Reed <rangerrick@befunk.com>
 * Copyright (C) 2009, Jonas Bähr <jonas.baehr@web.de>
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <config.h>
#include "dbus-server-launchd.h"

/**
 * @defgroup DBusServerLaunchd DBusServer implementations for Launchd
 * @ingroup  DBusInternals
 * @brief Implementation details of DBusServer with Launchd support
 *
 * @{
 */

#ifdef DBUS_ENABLE_LAUNCHD
#include <launch.h>
#include <errno.h>

#include "dbus-server-socket.h"

/* put other private launchd functions here */

#endif /* DBUS_ENABLE_LAUNCHD */

/**
 * @brief Creates a new server from launchd.
 *
 * launchd has allocaed a socket for us. We now query launchd for the
 * file descriptor of this socket and create a server on it.
 * In addition we inherit launchd's environment which holds a variable
 * containing the path to the socket. This is used to init the server's
 * address which is passed to autolaunched services.
 *
 * @param launchd_env_var the environment variable which holds the unix path to the socket
 * @param error location to store reason for failure.
 * @returns the new server, or #NULL on failure.
 */

DBusServer *
_dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error)
  {
#ifdef DBUS_ENABLE_LAUNCHD
    DBusServer *server;
    DBusString address;
    int launchd_fd;
    launch_data_t sockets_dict, checkin_response;
    launch_data_t checkin_request;
    launch_data_t listening_fd_array, listening_fd;
    launch_data_t environment_dict, environment_param;
    const char *launchd_socket_path, *display;

    launchd_socket_path = _dbus_getenv (launchd_env_var);
    display = _dbus_getenv ("DISPLAY");

    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    if (launchd_socket_path == NULL || *launchd_socket_path == '\0')
      {
        dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                        "launchd's environment variable %s is empty, but should contain a socket path.\n", launchd_env_var);
        return NULL;
      }

    if (!_dbus_string_init (&address))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        return NULL;
      }
    if (!_dbus_string_append (&address, "unix:path="))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto l_failed_0;
      }
    if (!_dbus_string_append (&address, launchd_socket_path))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto l_failed_0;
      }

    if ((checkin_request = launch_data_new_string (LAUNCH_KEY_CHECKIN)) == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
                        "launch_data_new_string(\"%s\") Unable to create string.\n",
                        LAUNCH_KEY_CHECKIN);
        goto l_failed_0;
      }

    if ((checkin_response = launch_msg (checkin_request)) == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "launch_msg(\"%s\") IPC failure: %s\n",
                        LAUNCH_KEY_CHECKIN, strerror (errno));
        goto l_failed_0;
      }

    if (LAUNCH_DATA_ERRNO == launch_data_get_type (checkin_response))
      {
        dbus_set_error (error, DBUS_ERROR_FAILED, "Check-in failed: %s\n",
                        strerror (launch_data_get_errno (checkin_response)));
        goto l_failed_0;
      }

    sockets_dict =
      launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_SOCKETS);
    if (NULL == sockets_dict)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "No sockets found to answer requests on!\n");
        goto l_failed_0;
      }

    listening_fd_array =
      launch_data_dict_lookup (sockets_dict, "unix_domain_listener");
    if (NULL == listening_fd_array)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "No known sockets found to answer requests on!\n");
        goto l_failed_0;
      }

    if (launch_data_array_get_count (listening_fd_array) != 1)
      {
        dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
                        "Expected 1 socket from launchd, got %d.\n",
                        launch_data_array_get_count (listening_fd_array));
        goto l_failed_0;
      }

    listening_fd = launch_data_array_get_index (listening_fd_array, 0);
    launchd_fd = launch_data_get_fd (listening_fd);

    _dbus_fd_set_close_on_exec (launchd_fd);

    if (launchd_fd < 0)
      {
        _DBUS_ASSERT_ERROR_IS_SET (error);
        goto l_failed_0;
  if (display == NULL || *display == '\0')
    {
      environment_dict = launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES);
      if (NULL == environment_dict)
        {
          _dbus_warn ("Unable to retrieve user environment from launchd.");
        }
      else
        {
          environment_param = launch_data_dict_lookup (environment_dict, "DISPLAY");
          if (NULL == environment_param)
            {
              _dbus_warn ("Unable to retrieve DISPLAY from launchd.");
            }
          else
            {
              display = launch_data_get_string(environment_param);
              _dbus_setenv ("DISPLAY", display);
            }
        }
    }

      }

    server = _dbus_server_new_for_socket (&launchd_fd, 1, &address, 0);
    if (server == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_NO_SERVER,
                        "Unable to listen on launchd fd %d.", launchd_fd);
        goto l_failed_0;
      }

    _dbus_string_free (&address);

    return server;

  l_failed_0:
    _dbus_string_free (&address);

    return NULL;
#else /* DBUS_ENABLE_LAUNCHD */
    dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                    "address type 'launchd' requested, but launchd support not compiled in");
    return NULL;
#endif
  }

/** @} */
