/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Authors: Christian Kellner <gicmo@gnome.org>
 *          Samuel Cormier-Iijima <sciyoshi@gmail.com>
 */

#include <config.h>
#include <glib.h>
#include <string.h>

#include "gunixsocketaddress.h"
#include "glibintl.h"
#include "gnetworking.h"


/**
 * SECTION:gunixsocketaddress
 * @short_description: UNIX GSocketAddress
 * @include: gio/gunixsocketaddress.h
 *
 * Support for UNIX-domain (also known as local) sockets.
 *
 * UNIX domain sockets are generally visible in the filesystem.
 * However, some systems support abstract socket names which are not
 * visible in the filesystem and not affected by the filesystem
 * permissions, visibility, etc. Currently this is only supported
 * under Linux. If you attempt to use abstract sockets on other
 * systems, function calls may return %G_IO_ERROR_NOT_SUPPORTED
 * errors. You can use g_unix_socket_address_abstract_names_supported()
 * to see if abstract names are supported.
 *
 * Note that <filename>&lt;gio/gunixsocketaddress.h&gt;</filename> belongs to
 * the UNIX-specific GIO interfaces, thus you have to use the
 * <filename>gio-unix-2.0.pc</filename> pkg-config file when using it.
 */

/**
 * GUnixSocketAddress:
 *
 * A UNIX-domain (local) socket address, corresponding to a
 * <type>struct sockaddr_un</type>.
 */
G_DEFINE_TYPE (GUnixSocketAddress, g_unix_socket_address, G_TYPE_SOCKET_ADDRESS);

enum
{
  PROP_0,
  PROP_PATH,
  PROP_PATH_AS_ARRAY,
  PROP_ABSTRACT,
  PROP_ADDRESS_TYPE
};

#define UNIX_PATH_MAX sizeof (((struct sockaddr_un *) 0)->sun_path)

struct _GUnixSocketAddressPrivate
{
  char path[UNIX_PATH_MAX]; /* Not including the initial zero in abstract case, so
			       we can guarantee zero termination of abstract
			       pathnames in the get_path() API */
  gsize path_len; /* Not including any terminating zeros */
  GUnixSocketAddressType address_type;
};

static void
g_unix_socket_address_set_property (GObject      *object,
				    guint         prop_id,
				    const GValue *value,
				    GParamSpec   *pspec)
{
  GUnixSocketAddress *address = G_UNIX_SOCKET_ADDRESS (object);
  const char *str;
  GByteArray *array;
  gsize len;

  switch (prop_id)
    {
    case PROP_PATH:
      str = g_value_get_string (value);
      if (str)
	{
	  g_strlcpy (address->priv->path, str,
		     sizeof (address->priv->path));
	  address->priv->path_len = strlen (address->priv->path);
	}
      break;

    case PROP_PATH_AS_ARRAY:
      array = g_value_get_boxed (value);

      if (array)
	{
	  /* Clip to fit in UNIX_PATH_MAX with zero termination or first byte */
	  len = MIN (array->len, UNIX_PATH_MAX-1);

	  memcpy (address->priv->path, array->data, len);
	  address->priv->path[len] = 0; /* Ensure null-terminated */
	  address->priv->path_len = len;
	}
      break;

    case PROP_ABSTRACT:
      /* If the caller already set PROP_ADDRESS_TYPE, don't let the
       * default value of PROP_ABSTRACT overwrite it.
       */
      if (address->priv->address_type != G_UNIX_SOCKET_ADDRESS_INVALID)
	return;

      if (g_value_get_boolean (value))
	address->priv->address_type = G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED;
      else
	address->priv->address_type = G_UNIX_SOCKET_ADDRESS_PATH;
      break;

    case PROP_ADDRESS_TYPE:
      /* If the caller already set PROP_ABSTRACT, don't let the
       * default value of PROP_ADDRESS_TYPE overwrite it.
       */
      if (address->priv->address_type != G_UNIX_SOCKET_ADDRESS_INVALID)
	return;

      address->priv->address_type = g_value_get_enum (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
g_unix_socket_address_get_property (GObject    *object,
				    guint       prop_id,
				    GValue     *value,
				    GParamSpec *pspec)
{
  GUnixSocketAddress *address = G_UNIX_SOCKET_ADDRESS (object);
  GByteArray *array;

  switch (prop_id)
    {
      case PROP_PATH:
	g_value_set_string (value, address->priv->path);
	break;

      case PROP_PATH_AS_ARRAY:
	array = g_byte_array_sized_new (address->priv->path_len);
	g_byte_array_append (array, (guint8 *)address->priv->path, address->priv->path_len);
	g_value_take_boxed (value, array);
	break;

      case PROP_ABSTRACT:
	g_value_set_boolean (value, (address->priv->address_type == G_UNIX_SOCKET_ADDRESS_ABSTRACT ||
				     address->priv->address_type == G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED));

	break;

      case PROP_ADDRESS_TYPE:
	g_value_set_enum (value, address->priv->address_type);
	break;

      default:
	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static GSocketFamily
g_unix_socket_address_get_family (GSocketAddress *address)
{
  g_assert (PF_UNIX == G_SOCKET_FAMILY_UNIX);

  return G_SOCKET_FAMILY_UNIX;
}

static gssize
g_unix_socket_address_get_native_size (GSocketAddress *address)
{
  GUnixSocketAddress *addr = G_UNIX_SOCKET_ADDRESS (address);

  switch (addr->priv->address_type)
    {
    case G_UNIX_SOCKET_ADDRESS_ANONYMOUS:
      return G_STRUCT_OFFSET(struct sockaddr_un, sun_path);
    case G_UNIX_SOCKET_ADDRESS_ABSTRACT:
      return G_STRUCT_OFFSET(struct sockaddr_un, sun_path) + addr->priv->path_len + 1;
    default:
      return sizeof (struct sockaddr_un);
    }
}

static gboolean
g_unix_socket_address_to_native (GSocketAddress *address,
				 gpointer        dest,
				 gsize           destlen,
				 GError        **error)
{
  GUnixSocketAddress *addr = G_UNIX_SOCKET_ADDRESS (address);
  struct sockaddr_un *sock;
  gssize socklen;

  socklen = g_unix_socket_address_get_native_size (address);
  if (destlen < socklen)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
			   _("Not enough space for socket address"));
      return FALSE;
    }

  sock = (struct sockaddr_un *) dest;
  memset (sock, 0, socklen);
  sock->sun_family = AF_UNIX;

  switch (addr->priv->address_type)
    {
    case G_UNIX_SOCKET_ADDRESS_INVALID:
    case G_UNIX_SOCKET_ADDRESS_ANONYMOUS:
      break;

    case G_UNIX_SOCKET_ADDRESS_PATH:
      strcpy (sock->sun_path, addr->priv->path);
      break;

    case G_UNIX_SOCKET_ADDRESS_ABSTRACT:
    case G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED:
      if (!g_unix_socket_address_abstract_names_supported ())
	{
	  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
			       _("Abstract UNIX domain socket addresses not supported on this system"));
	  return FALSE;
	}

      sock->sun_path[0] = 0;
      memcpy (sock->sun_path+1, addr->priv->path, addr->priv->path_len);
      break;
    }

  return TRUE;
}

static void
g_unix_socket_address_class_init (GUnixSocketAddressClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass);

  g_type_class_add_private (klass, sizeof (GUnixSocketAddressPrivate));

  gobject_class->set_property = g_unix_socket_address_set_property;
  gobject_class->get_property = g_unix_socket_address_get_property;

  gsocketaddress_class->get_family = g_unix_socket_address_get_family;
  gsocketaddress_class->to_native = g_unix_socket_address_to_native;
  gsocketaddress_class->get_native_size = g_unix_socket_address_get_native_size;

  g_object_class_install_property (gobject_class,
				   PROP_PATH,
				   g_param_spec_string ("path",
							P_("Path"),
							P_("UNIX socket path"),
							NULL,
							G_PARAM_READWRITE |
							G_PARAM_CONSTRUCT_ONLY |
							G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PATH_AS_ARRAY,
				   g_param_spec_boxed ("path-as-array",
						       P_("Path array"),
						       P_("UNIX socket path, as byte array"),
						       G_TYPE_BYTE_ARRAY,
						       G_PARAM_READWRITE |
						       G_PARAM_CONSTRUCT_ONLY |
						       G_PARAM_STATIC_STRINGS));
  /**
   * GUnixSocketAddress:abstract:
   *
   * Whether or not this is an abstract address
   *
   * Deprecated: Use #GUnixSocketAddress:address-type, which
   * distinguishes between zero-padded and non-zero-padded
   * abstract addresses.
   */
  g_object_class_install_property (gobject_class, PROP_ABSTRACT,
				   g_param_spec_boolean ("abstract",
							 P_("Abstract"),
							 P_("Whether or not this is an abstract address"),
							 FALSE,
							 G_PARAM_READWRITE |
							 G_PARAM_CONSTRUCT_ONLY |
							 G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_ADDRESS_TYPE,
				   g_param_spec_enum ("address-type",
						      P_("Address type"),
						      P_("The type of UNIX socket address"),
						      G_TYPE_UNIX_SOCKET_ADDRESS_TYPE,
						      G_UNIX_SOCKET_ADDRESS_PATH,
						      G_PARAM_READWRITE |
						      G_PARAM_CONSTRUCT_ONLY |
						      G_PARAM_STATIC_STRINGS));
}

static void
g_unix_socket_address_init (GUnixSocketAddress *address)
{
  address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
					       G_TYPE_UNIX_SOCKET_ADDRESS,
					       GUnixSocketAddressPrivate);

  memset (address->priv->path, 0, sizeof (address->priv->path));
  address->priv->path_len = -1;
  address->priv->address_type = G_UNIX_SOCKET_ADDRESS_INVALID;
}

/**
 * g_unix_socket_address_new:
 * @path: the socket path
 *
 * Creates a new #GUnixSocketAddress for @path.
 *
 * To create abstract socket addresses, on systems that support that,
 * use g_unix_socket_address_new_abstract().
 *
 * Returns: a new #GUnixSocketAddress
 *
 * Since: 2.22
 */
GSocketAddress *
g_unix_socket_address_new (const gchar *path)
{
  return g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
		       "path", path,
		       "abstract", FALSE,
		       NULL);
}

/**
 * g_unix_socket_address_new_abstract:
 * @path: (array length=path_len) (element-type gchar): the abstract name
 * @path_len: the length of @path, or -1
 *
 * Creates a new %G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED
 * #GUnixSocketAddress for @path.
 *
 * Returns: a new #GUnixSocketAddress
 *
 * Deprecated: Use g_unix_socket_address_new_with_type().
 */
GSocketAddress *
g_unix_socket_address_new_abstract (const gchar *path,
				    gint         path_len)
{
  return g_unix_socket_address_new_with_type (path, path_len,
					      G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED);
}

/**
 * g_unix_socket_address_new_with_type:
 * @path: (array length=path_len) (element-type gchar): the name
 * @path_len: the length of @path, or -1
 * @type: a #GUnixSocketAddressType
 *
 * Creates a new #GUnixSocketAddress of type @type with name @path.
 *
 * If @type is %G_UNIX_SOCKET_ADDRESS_PATH, this is equivalent to
 * calling g_unix_socket_address_new().
 *
 * If @path_type is %G_UNIX_SOCKET_ADDRESS_ABSTRACT, then @path_len
 * bytes of @path will be copied to the socket's path, and only those
 * bytes will be considered part of the name. (If @path_len is -1,
 * then @path is assumed to be NUL-terminated.) For example, if @path
 * was "test", then calling g_socket_address_get_native_size() on the
 * returned socket would return 7 (2 bytes of overhead, 1 byte for the
 * abstract-socket indicator byte, and 4 bytes for the name "test").
 *
 * If @path_type is %G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED, then
 * @path_len bytes of @path will be copied to the socket's path, the
 * rest of the path will be padded with 0 bytes, and the entire
 * zero-padded buffer will be considered the name. (As above, if
 * @path_len is -1, then @path is assumed to be NUL-terminated.) In
 * this case, g_socket_address_get_native_size() will always return
 * the full size of a <literal>struct sockaddr_un</literal>, although
 * g_unix_socket_address_get_path_len() will still return just the
 * length of @path.
 *
 * %G_UNIX_SOCKET_ADDRESS_ABSTRACT is preferred over
 * %G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED for new programs. Of course,
 * when connecting to a server created by another process, you must
 * use the appropriate type corresponding to how that process created
 * its listening socket.
 *
 * Returns: a new #GUnixSocketAddress
 *
 * Since: 2.26
 */
GSocketAddress *
g_unix_socket_address_new_with_type (const gchar            *path,
				     gint                    path_len,
				     GUnixSocketAddressType  type)
{
  GSocketAddress *address;
  GByteArray *array;

  if (type == G_UNIX_SOCKET_ADDRESS_ANONYMOUS)
    path_len = 0;
  else if (path_len == -1)
    path_len = strlen (path);

  array = g_byte_array_sized_new (path_len);

  g_byte_array_append (array, (guint8 *)path, path_len);

  address = g_object_new (G_TYPE_UNIX_SOCKET_ADDRESS,
			  "path-as-array", array,
			  "address-type", type,
			  NULL);

  g_byte_array_unref (array);

  return address;
}

/**
 * g_unix_socket_address_get_path:
 * @address: a #GInetSocketAddress
 *
 * Gets @address's path, or for abstract sockets the "name".
 *
 * Guaranteed to be zero-terminated, but an abstract socket
 * may contain embedded zeros, and thus you should use
 * g_unix_socket_address_get_path_len() to get the true length
 * of this string.
 *
 * Returns: the path for @address
 *
 * Since: 2.22
 */
const char *
g_unix_socket_address_get_path (GUnixSocketAddress *address)
{
  return address->priv->path;
}

/**
 * g_unix_socket_address_get_path_len:
 * @address: a #GInetSocketAddress
 *
 * Gets the length of @address's path.
 *
 * For details, see g_unix_socket_address_get_path().
 *
 * Returns: the length of the path
 *
 * Since: 2.22
 */
gsize
g_unix_socket_address_get_path_len (GUnixSocketAddress *address)
{
  return address->priv->path_len;
}

/**
 * g_unix_socket_address_get_address_type:
 * @address: a #GInetSocketAddress
 *
 * Gets @address's type.
 *
 * Returns: a #GUnixSocketAddressType
 *
 * Since: 2.26
 */
GUnixSocketAddressType
g_unix_socket_address_get_address_type (GUnixSocketAddress *address)
{
  return address->priv->address_type;
}

/**
 * g_unix_socket_address_get_is_abstract:
 * @address: a #GInetSocketAddress
 *
 * Tests if @address is abstract.
 *
 * Returns: %TRUE if the address is abstract, %FALSE otherwise
 *
 * Since: 2.22
 *
 * Deprecated: Use g_unix_socket_address_get_address_type()
 */
gboolean
g_unix_socket_address_get_is_abstract (GUnixSocketAddress *address)
{
  return (address->priv->address_type == G_UNIX_SOCKET_ADDRESS_ABSTRACT ||
	  address->priv->address_type == G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED);
}

/**
 * g_unix_socket_address_abstract_names_supported:
 *
 * Checks if abstract UNIX domain socket names are supported.
 *
 * Returns: %TRUE if supported, %FALSE otherwise
 *
 * Since: 2.22
 */
gboolean
g_unix_socket_address_abstract_names_supported (void)
{
#ifdef __linux__
  return TRUE;
#else
  return FALSE;
#endif
}
