[glib] Add network address and socket types
- From: Dan Winship <danw src gnome org>
- To: svn-commits-list gnome org
- Subject: [glib] Add network address and socket types
- Date: Wed, 22 Apr 2009 08:39:30 -0400 (EDT)
commit 68fc0556275edf6e63a3242841f2981a42ee11cb
Author: Dan Winship <danw gnome org>
Date: Fri Dec 12 13:13:55 2008 -0500
Add network address and socket types
Types and methods for dealing with IPv4 and IPv6 addresses (and UNIX
domain socket addresses under UNIX). This does not include code for
actual socket I/O.
Originally from "gnio". Much of the code was written by Christian
Kellner, Samuel Cormier-Iijima, and Ryan Lortie.
Part of #548466.
---
configure.in | 28 ++
docs/reference/gio/gio-docs.xml | 7 +
docs/reference/gio/gio-sections.txt | 91 +++++
docs/reference/gio/gio.types | 4 +
gio/Makefile.am | 11 +-
gio/ginetaddress.c | 747 +++++++++++++++++++++++++++++++++++
gio/ginetaddress.h | 101 +++++
gio/ginetsocketaddress.c | 306 ++++++++++++++
gio/ginetsocketaddress.h | 69 ++++
gio/gio.h | 3 +
gio/gio.symbols | 51 +++
gio/gioenums.h | 20 +
gio/giotypes.h | 5 +
gio/gnetworkingprivate.h | 53 +++
gio/gsocketaddress.c | 233 +++++++++++
gio/gsocketaddress.h | 77 ++++
gio/gunixsocketaddress.c | 206 ++++++++++
gio/gunixsocketaddress.h | 61 +++
glibconfig.h.win32.in | 3 +
19 files changed, 2075 insertions(+), 1 deletions(-)
diff --git a/configure.in b/configure.in
index 514fd75..5c33ab9 100644
--- a/configure.in
+++ b/configure.in
@@ -954,6 +954,26 @@ AC_CHECK_FUNCS(_NSGetEnviron)
AC_FUNC_VSNPRINTF_C99
AC_FUNC_PRINTF_UNIX98
+# Internet address families
+if test $glib_native_win32 = yes; then
+ glib_inet_includes=["
+#include <winsock2.h>
+ "]
+else
+ glib_inet_includes=["
+#include <sys/socket.h>
+ "]
+fi
+
+glib_failed=false
+GLIB_CHECK_VALUE(AF_INET, $glib_inet_includes, glib_failed=true)
+GLIB_CHECK_VALUE(AF_INET6, $glib_inet_includes, glib_failed=true)
+# winsock defines this even though it doesn't support it
+GLIB_CHECK_VALUE(AF_UNIX, $glib_inet_includes, glib_failed=true)
+if $glib_failed ; then
+ AC_MSG_ERROR([Could not determine values for AF_INET* constants])
+fi
+
dnl
dnl if statfs() takes 2 arguments (Posix) or 4 (Solaris)
dnl
@@ -2986,6 +3006,10 @@ _______EOF
*/
typedef $g_pid_type GPid;
+#define GLIB_SYSDEF_AF_UNIX $g_af_unix
+#define GLIB_SYSDEF_AF_INET $g_af_inet
+#define GLIB_SYSDEF_AF_INET6 $g_af_inet6
+
G_END_DECLS
#endif /* GLIBCONFIG_H */
@@ -3272,6 +3296,10 @@ g_pollhup=$glib_cv_value_POLLHUP
g_pollerr=$glib_cv_value_POLLERR
g_pollnval=$glib_cv_value_POLLNVAL
+g_af_unix=$glib_cv_value_AF_UNIX
+g_af_inet=$glib_cv_value_AF_INET
+g_af_inet6=$glib_cv_value_AF_INET6
+
g_stack_grows=$glib_cv_stack_grows
g_have_eilseq=$have_eilseq
diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml
index 46af7fe..8872ed7 100644
--- a/docs/reference/gio/gio-docs.xml
+++ b/docs/reference/gio/gio-docs.xml
@@ -90,6 +90,13 @@
<xi:include href="xml/gemblemedicon.xml"/>
<xi:include href="xml/gemblem.xml"/>
</chapter>
+ <chapter id="networking">
+ <title>Networking</title>
+ <xi:include href="xml/ginetaddress.xml"/>
+ <xi:include href="xml/gsocketaddress.xml"/>
+ <xi:include href="xml/ginetsocketaddress.xml"/>
+ <xi:include href="xml/gunixsocketaddress.xml"/>
+ </chapter>
<chapter id="utils">
<title>Utilities</title>
<xi:include href="xml/gfilenamecompleter.xml"/>
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 36e9aee..a2d19b7 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -1312,4 +1312,95 @@ g_io_extension_point_set_required_type
g_io_extension_ref_class
</SECTION>
+<SECTION>
+<FILE>ginetaddress</FILE>
+<TITLE>GInetAddress</TITLE>
+GInetAddress
+g_inet_address_new_from_string
+g_inet_address_new_from_bytes
+g_inet_address_new_any
+g_inet_address_new_loopback
+g_inet_address_to_bytes
+g_inet_address_to_string
+g_inet_address_get_family
+g_inet_address_get_is_any
+g_inet_address_get_is_link_local
+g_inet_address_get_is_loopback
+g_inet_address_get_is_mc_global
+g_inet_address_get_is_mc_link_local
+g_inet_address_get_is_mc_node_local
+g_inet_address_get_is_mc_org_local
+g_inet_address_get_is_mc_site_local
+g_inet_address_get_is_multicast
+g_inet_address_get_is_site_local
+<SUBSECTION Standard>
+GInetAddressClass
+GInetAddressPrivate
+G_INET_ADDRESS
+G_INET_ADDRESS_CLASS
+G_INET_ADDRESS_GET_CLASS
+G_IS_INET_ADDRESS
+G_IS_INET_ADDRESS_CLASS
+G_TYPE_INET_ADDRESS
+<SUBSECTION Private>
+g_inet_address_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gsocketaddress</FILE>
+<TITLE>GSocketAddress</TITLE>
+GSocketAddress
+GSocketFamily
+g_socket_address_new_from_native
+g_socket_address_get_family
+g_socket_address_to_native
+g_socket_address_get_native_size
+<SUBSECTION Standard>
+GSocketAddressClass
+G_IS_SOCKET_ADDRESS
+G_IS_SOCKET_ADDRESS_CLASS
+G_SOCKET_ADDRESS
+G_SOCKET_ADDRESS_CLASS
+G_SOCKET_ADDRESS_GET_CLASS
+G_TYPE_SOCKET_ADDRESS
+<SUBSECTION Private>
+g_socket_address_get_type
+</SECTION>
+<SECTION>
+<FILE>ginetsocketaddress</FILE>
+<TITLE>GInetSocketAddress</TITLE>
+GInetSocketAddress
+g_inet_socket_address_new
+g_inet_socket_address_get_address
+g_inet_socket_address_get_port
+<SUBSECTION Standard>
+GInetSocketAddressClass
+GInetSocketAddressPrivate
+G_INET_SOCKET_ADDRESS
+G_INET_SOCKET_ADDRESS_CLASS
+G_INET_SOCKET_ADDRESS_GET_CLASS
+G_IS_INET_SOCKET_ADDRESS
+G_IS_INET_SOCKET_ADDRESS_CLASS
+G_TYPE_INET_SOCKET_ADDRESS
+<SUBSECTION Private>
+g_inet_socket_address_get_type
+</SECTION>
+
+<SECTION>
+<FILE>gunixsocketaddress</FILE>
+<TITLE>GUnixSocketAddress</TITLE>
+GUnixSocketAddress
+g_unix_socket_address_new
+<SUBSECTION Standard>
+GUnixSocketAddressClass
+GUnixSocketAddressPrivate
+G_IS_UNIX_SOCKET_ADDRESS
+G_IS_UNIX_SOCKET_ADDRESS_CLASS
+G_TYPE_UNIX_SOCKET_ADDRESS
+G_UNIX_SOCKET_ADDRESS
+G_UNIX_SOCKET_ADDRESS_CLASS
+G_UNIX_SOCKET_ADDRESS_GET_CLASS
+<SUBSECTION Private>
+g_unix_socket_address_get_type
+</SECTION>
diff --git a/docs/reference/gio/gio.types b/docs/reference/gio/gio.types
index c73282a..cedae87 100644
--- a/docs/reference/gio/gio.types
+++ b/docs/reference/gio/gio.types
@@ -36,6 +36,8 @@ g_file_type_get_type
g_filter_input_stream_get_type
g_filter_output_stream_get_type
g_icon_get_type
+g_inet_address_get_type
+g_inet_socket_address_get_type
g_input_stream_get_type
g_io_error_enum_get_type
g_io_module_get_type
@@ -55,10 +57,12 @@ g_output_stream_splice_flags_get_type
g_password_save_get_type
g_seekable_get_type
g_simple_async_result_get_type
+g_socket_address_get_type
g_themed_icon_get_type
g_unix_input_stream_get_type
g_unix_mount_monitor_get_type
g_unix_output_stream_get_type
+g_unix_socket_address_get_type
g_vfs_get_type
g_volume_get_type
g_volume_monitor_get_type
diff --git a/gio/Makefile.am b/gio/Makefile.am
index be6568f..53b30c2 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -132,6 +132,7 @@ unix_sources = \
gunixmount.h \
gunixmounts.c \
gunixmounts.h \
+ gunixsocketaddress.c \
gunixvolume.c \
gunixvolume.h \
gunixvolumemonitor.c \
@@ -147,12 +148,13 @@ giounixinclude_HEADERS = \
gunixmounts.h \
gunixinputstream.h \
gunixoutputstream.h \
+ gunixsocketaddress.h \
$(NULL)
endif
if OS_WIN32
appinfo_sources += gwin32appinfo.c gwin32appinfo.h
-platform_libadd += -lshlwapi
+platform_libadd += -lshlwapi -lws2_32
win32_sources = \
gwin32mount.c \
gwin32mount.h \
@@ -196,6 +198,8 @@ libgio_2_0_la_SOURCES = \
gfilterinputstream.c \
gfilteroutputstream.c \
gicon.c \
+ ginetaddress.c \
+ ginetsocketaddress.c \
ginputstream.c \
gioenums.h \
gioerror.c \
@@ -209,11 +213,13 @@ libgio_2_0_la_SOURCES = \
gmountoperation.c \
gnativevolumemonitor.c \
gnativevolumemonitor.h \
+ gnetworkingprivate.h \
goutputstream.c \
gpollfilemonitor.c \
gpollfilemonitor.h \
gseekable.c \
gsimpleasyncresult.c \
+ gsocketaddress.c \
gthemedicon.c \
gunionvolumemonitor.c \
gunionvolumemonitor.h \
@@ -299,6 +305,8 @@ gio_headers = \
gfilterinputstream.h \
gfilteroutputstream.h \
gicon.h \
+ ginetaddress.h \
+ ginetsocketaddress.h \
ginputstream.h \
gio.h \
giotypes.h \
@@ -315,6 +323,7 @@ gio_headers = \
goutputstream.h \
gseekable.h \
gsimpleasyncresult.h \
+ gsocketaddress.h \
gthemedicon.h \
gvfs.h \
gvolume.h \
diff --git a/gio/ginetaddress.c b/gio/ginetaddress.c
new file mode 100644
index 0000000..cc5856b
--- /dev/null
+++ b/gio/ginetaddress.c
@@ -0,0 +1,747 @@
+/* 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 "ginetaddress.h"
+#include "gioenums.h"
+#include "gioenumtypes.h"
+#include "glibintl.h"
+#include "gnetworkingprivate.h"
+
+#include "gioalias.h"
+
+/**
+ * SECTION:ginetaddress
+ * @short_description: An IPv4/IPv6 address
+ *
+ * #GInetAddress represents an IPv4 or IPv6 internet address.
+ *
+ * To actually connect to a remote host, you will need a
+ * #GInetSocketAddress (which includes a #GInetAddress as well as a
+ * port number).
+ **/
+
+/**
+ * GInetAddress:
+ *
+ * An IPv4 or IPv6 internet address.
+ **/
+
+/* Networking initialization function, called from inside the g_once of
+ * g_inet_address_get_type()
+ */
+static void
+_g_networking_init (void)
+{
+#ifdef G_OS_WIN32
+ WSADATA wsadata;
+ if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0)
+ g_error ("Windows Sockets could not be initialized");
+#endif
+}
+
+G_DEFINE_TYPE_WITH_CODE (GInetAddress, g_inet_address, G_TYPE_OBJECT,
+ _g_networking_init ();)
+
+struct _GInetAddressPrivate
+{
+ GSocketFamily family;
+ union {
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+ } addr;
+};
+
+enum
+{
+ PROP_0,
+ PROP_FAMILY,
+ PROP_BYTES,
+ PROP_IS_ANY,
+ PROP_IS_LOOPBACK,
+ PROP_IS_LINK_LOCAL,
+ PROP_IS_SITE_LOCAL,
+ PROP_IS_MULTICAST,
+ PROP_IS_MC_GLOBAL,
+ PROP_IS_MC_LINK_LOCAL,
+ PROP_IS_MC_NODE_LOCAL,
+ PROP_IS_MC_ORG_LOCAL,
+ PROP_IS_MC_SITE_LOCAL,
+};
+
+static void
+g_inet_address_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GInetAddress *address = G_INET_ADDRESS (object);
+
+ switch (prop_id)
+ {
+ case PROP_FAMILY:
+ address->priv->family = g_value_get_enum (value);
+ break;
+
+ case PROP_BYTES:
+ memcpy (&address->priv->addr, g_value_get_pointer (value),
+ address->priv->family == AF_INET ?
+ sizeof (address->priv->addr.ipv4) :
+ sizeof (address->priv->addr.ipv6));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+
+}
+
+static void
+g_inet_address_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GInetAddress *address = G_INET_ADDRESS (object);
+
+ switch (prop_id)
+ {
+ case PROP_FAMILY:
+ g_value_set_enum (value, address->priv->family);
+ break;
+
+ case PROP_BYTES:
+ g_value_set_pointer (value, &address->priv->addr);
+ break;
+
+ case PROP_IS_ANY:
+ g_value_set_boolean (value, g_inet_address_get_is_any (address));
+ break;
+
+ case PROP_IS_LOOPBACK:
+ g_value_set_boolean (value, g_inet_address_get_is_loopback (address));
+ break;
+
+ case PROP_IS_LINK_LOCAL:
+ g_value_set_boolean (value, g_inet_address_get_is_link_local (address));
+ break;
+
+ case PROP_IS_SITE_LOCAL:
+ g_value_set_boolean (value, g_inet_address_get_is_site_local (address));
+ break;
+
+ case PROP_IS_MULTICAST:
+ g_value_set_boolean (value, g_inet_address_get_is_multicast (address));
+ break;
+
+ case PROP_IS_MC_GLOBAL:
+ g_value_set_boolean (value, g_inet_address_get_is_mc_global (address));
+ break;
+
+ case PROP_IS_MC_LINK_LOCAL:
+ g_value_set_boolean (value, g_inet_address_get_is_mc_link_local (address));
+ break;
+
+ case PROP_IS_MC_NODE_LOCAL:
+ g_value_set_boolean (value, g_inet_address_get_is_mc_node_local (address));
+ break;
+
+ case PROP_IS_MC_ORG_LOCAL:
+ g_value_set_boolean (value, g_inet_address_get_is_mc_org_local (address));
+ break;
+
+ case PROP_IS_MC_SITE_LOCAL:
+ g_value_set_boolean (value, g_inet_address_get_is_mc_site_local (address));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_inet_address_class_init (GInetAddressClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GInetAddressPrivate));
+
+ gobject_class->set_property = g_inet_address_set_property;
+ gobject_class->get_property = g_inet_address_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_FAMILY,
+ g_param_spec_enum ("family",
+ _("Address family"),
+ _("The address family (IPv4 or IPv6)"),
+ G_TYPE_SOCKET_FAMILY,
+ G_SOCKET_FAMILY_INVALID,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_BYTES,
+ g_param_spec_pointer ("bytes",
+ _("Bytes"),
+ _("The raw address data"),
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_ANY,
+ g_param_spec_boolean ("is-any",
+ _("Is any"),
+ _("See g_inet_address_get_is_any()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_LINK_LOCAL,
+ g_param_spec_boolean ("is-link-local",
+ _("Is link-local"),
+ _("See g_inet_address_get_is_link_local()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_LOOPBACK,
+ g_param_spec_boolean ("is-loopback",
+ _("Is loopback"),
+ _("See g_inet_address_get_is_loopback()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_SITE_LOCAL,
+ g_param_spec_boolean ("is-site-local",
+ _("Is site-local"),
+ _("See g_inet_address_get_is_site_local()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_MULTICAST,
+ g_param_spec_boolean ("is-multicast",
+ _("Is multicast"),
+ _("See g_inet_address_get_is_multicast()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_MC_GLOBAL,
+ g_param_spec_boolean ("is-mc-global",
+ _("Is multicast global"),
+ _("See g_inet_address_get_is_mc_global()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_MC_LINK_LOCAL,
+ g_param_spec_boolean ("is-mc-link-local",
+ _("Is multicast link-local"),
+ _("See g_inet_address_get_is_mc_link_local()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_MC_NODE_LOCAL,
+ g_param_spec_boolean ("is-mc-node-local",
+ _("Is multicast node-local"),
+ _("See g_inet_address_get_is_mc_node_local()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_MC_ORG_LOCAL,
+ g_param_spec_boolean ("is-mc-org-local",
+ _("Is multicast org-local"),
+ _("See g_inet_address_get_is_mc_org_local()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+
+ g_object_class_install_property (gobject_class, PROP_IS_MC_SITE_LOCAL,
+ g_param_spec_boolean ("is-mc-site-local",
+ _("Is multicast site-local"),
+ _("See g_inet_address_get_is_mc_site_local()"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+}
+
+static void
+g_inet_address_init (GInetAddress *address)
+{
+ address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
+ G_TYPE_INET_ADDRESS,
+ GInetAddressPrivate);
+}
+
+/**
+ * g_inet_address_new_from_string:
+ * @string: a string representation of an IP address
+ *
+ * Parses @string as an IP address and creates a new #GInetAddress.
+ *
+ * Returns: a new #GInetAddress corresponding to @string, or %NULL if
+ * @string could not be parsed.
+ *
+ * Since: 2.22
+ */
+GInetAddress *
+g_inet_address_new_from_string (const gchar *string)
+{
+#ifdef G_OS_WIN32
+ struct sockaddr_storage sa;
+ struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
+ gint len;
+#else /* !G_OS_WIN32 */
+ struct in_addr in_addr;
+ struct in6_addr in6_addr;
+#endif
+
+ /* Make sure _g_networking_init() has been called */
+ (void) g_inet_address_get_type ();
+
+#ifdef G_OS_WIN32
+ memset (&sa, 0, sizeof (sa));
+ len = sizeof (sa);
+ if (WSAStringToAddress ((LPTSTR) string, AF_INET, NULL, (LPSOCKADDR) &sa, &len) == 0)
+ return g_inet_address_new_from_bytes ((guint8 *)&sin->sin_addr, AF_INET);
+ else if (WSAStringToAddress ((LPTSTR) string, AF_INET6, NULL, (LPSOCKADDR) &sa, &len) == 0)
+ return g_inet_address_new_from_bytes ((guint8 *)&sin6->sin6_addr, AF_INET6);
+
+#else /* !G_OS_WIN32 */
+
+ if (inet_pton (AF_INET, string, &in_addr) > 0)
+ return g_inet_address_new_from_bytes ((guint8 *)&in_addr, AF_INET);
+ else if (inet_pton (AF_INET6, string, &in6_addr) > 0)
+ return g_inet_address_new_from_bytes ((guint8 *)&in6_addr, AF_INET6);
+#endif
+
+ return NULL;
+}
+
+#define G_INET_ADDRESS_FAMILY_IS_VALID(family) ((family) == AF_INET || (family) == AF_INET6)
+
+/**
+ * g_inet_address_new_from_bytes:
+ * @bytes: raw address data
+ * @family: the address family of @bytes
+ *
+ * Creates a new #GInetAddress from the given @family and @bytes.
+ * @bytes should be 4 bytes for %G_INET_ADDRESS_IPV4 and 16 bytes for
+ * %G_INET_ADDRESS_IPV6.
+ *
+ * Returns: a new #GInetAddress corresponding to @family and @bytes.
+ *
+ * Since: 2.22
+ */
+GInetAddress *
+g_inet_address_new_from_bytes (const guint8 *bytes,
+ GSocketFamily family)
+{
+ g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
+
+ return g_object_new (G_TYPE_INET_ADDRESS,
+ "family", family,
+ "bytes", bytes,
+ NULL);
+}
+
+/**
+ * g_inet_address_new_loopback:
+ * @family: the address family
+ *
+ * Creates a #GInetAddress for the loopback address for @family.
+ *
+ * Returns: a new #GInetAddress corresponding to the loopback address
+ * for @family.
+ *
+ * Since: 2.22
+ */
+GInetAddress *
+g_inet_address_new_loopback (GSocketFamily family)
+{
+ g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
+
+ if (family == AF_INET)
+ {
+ guint8 addr[4] = {127, 0, 0, 1};
+
+ return g_inet_address_new_from_bytes (addr, family);
+ }
+ else
+ return g_inet_address_new_from_bytes (in6addr_loopback.s6_addr, family);
+}
+
+/**
+ * g_inet_address_new_any:
+ * @family: the address family
+ *
+ * Creates a #GInetAddress for the "any" address (unassigned/"don't
+ * care") for @family.
+ *
+ * Returns: a new #GInetAddress corresponding to the "any" address
+ * for @family.
+ *
+ * Since: 2.22
+ */
+GInetAddress *
+g_inet_address_new_any (GSocketFamily family)
+{
+ g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
+
+ if (family == AF_INET)
+ {
+ guint8 addr[4] = {0, 0, 0, 0};
+
+ return g_inet_address_new_from_bytes (addr, family);
+ }
+ else
+ return g_inet_address_new_from_bytes (in6addr_any.s6_addr, family);
+}
+
+
+/**
+ * g_inet_address_to_string:
+ * @address: a #GInetAddress
+ *
+ * Converts @address to string form.
+ *
+ * Returns: a representation of @address as a string, which should be
+ * freed after use.
+ *
+ * Since: 2.22
+ */
+gchar *
+g_inet_address_to_string (GInetAddress *address)
+{
+ gchar buffer[INET6_ADDRSTRLEN];
+#ifdef G_OS_WIN32
+ DWORD buflen = sizeof (buffer), addrlen;
+ struct sockaddr_storage sa;
+ struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
+#endif
+
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
+
+#ifdef G_OS_WIN32
+ sa.ss_family = address->priv->family;
+ if (address->priv->family == AF_INET)
+ {
+ addrlen = sizeof (*sin);
+ memcpy (&sin->sin_addr, &address->priv->addr.ipv4,
+ sizeof (sin->sin_addr));
+ sin->sin_port = 0;
+ }
+ else
+ {
+ addrlen = sizeof (*sin6);
+ memcpy (&sin6->sin6_addr, &address->priv->addr.ipv6,
+ sizeof (sin6->sin6_addr));
+ sin6->sin6_port = 0;
+ }
+ if (WSAAddressToString ((LPSOCKADDR) &sa, addrlen, NULL, buffer, &buflen) != 0)
+ return NULL;
+
+#else /* !G_OS_WIN32 */
+
+ if (address->priv->family == AF_INET)
+ inet_ntop (AF_INET, &address->priv->addr.ipv4, buffer, sizeof (buffer));
+ else
+ inet_ntop (AF_INET6, &address->priv->addr.ipv6, buffer, sizeof (buffer));
+#endif
+
+ return g_strdup (buffer);
+}
+
+/**
+ * g_inet_address_to_bytes:
+ * @address: a #GInetAddress
+ *
+ * Gets the raw binary address data from @address.
+ *
+ * Returns: a pointer to an internal array of the bytes in @address,
+ * which should not be modified, stored, or freed.
+ *
+ * Since: 2.22
+ */
+const guint8 *
+g_inet_address_to_bytes (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
+
+ return (guint8 *)&address->priv->addr;
+}
+
+/**
+ * g_inet_address_get_family:
+ * @address: a #GInetAddress
+ *
+ * Gets @address's family
+ *
+ * Returns: @address's family
+ *
+ * Since: 2.22
+ */
+GSocketFamily
+g_inet_address_get_family (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ return address->priv->family;
+}
+
+/**
+ * g_inet_address_get_is_any:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is the "any" address for its family.
+ *
+ * Returns: %TRUE if @address is the "any" address for its family.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_any (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ {
+ guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
+
+ return addr4 == INADDR_ANY;
+ }
+ else
+ return IN6_IS_ADDR_UNSPECIFIED (&address->priv->addr.ipv6.s6_addr);
+}
+
+/**
+ * g_inet_address_get_is_loopback:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is the loopback address for its family.
+ *
+ * Returns: %TRUE if @address is the loopback address for its family.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_loopback (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ {
+ guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
+
+ /* 127.0.0.0/8 */
+ return ((addr4 & 0xff000000) == 0x7f000000);
+ }
+ else
+ return IN6_IS_ADDR_LOOPBACK (&address->priv->addr.ipv6.s6_addr);
+}
+
+/**
+ * g_inet_address_get_is_link_local:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is a link-local address (that is, if it
+ * identifies a host on a local network that is not connected to the
+ * Internet).
+ *
+ * Returns: %TRUE if @address is a link-local address.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_link_local (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ {
+ guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
+
+ /* 169.254.0.0/16 */
+ return ((addr4 & 0xffff0000) == 0xa9fe0000);
+ }
+ else
+ return IN6_IS_ADDR_LINKLOCAL (&address->priv->addr.ipv6.s6_addr);
+}
+
+/**
+ * g_inet_address_get_is_site_local:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is a site-local address such as 10.0.0.1
+ * (that is, the address identifies a host on a local network that can
+ * not be reached directly from the Internet, but which may have
+ * outgoing Internet connectivity via a NAT or firewall).
+ *
+ * Returns: %TRUE if @address is a site-local address.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_site_local (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ {
+ guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
+
+ /* 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 */
+ return ((addr4 & 0xff000000) == 0x0a000000 ||
+ (addr4 & 0xfff00000) == 0xac100000 ||
+ (addr4 & 0xffff0000) == 0xc0a80000);
+ }
+ else
+ return IN6_IS_ADDR_SITELOCAL (&address->priv->addr.ipv6.s6_addr);
+}
+
+/**
+ * g_inet_address_get_is_multicast:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is a multicast address.
+ *
+ * Returns: %TRUE if @address is a multicast address.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_multicast (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ {
+ guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
+
+ return IN_MULTICAST (addr4);
+ }
+ else
+ return IN6_IS_ADDR_MULTICAST (&address->priv->addr.ipv6.s6_addr);
+}
+
+/**
+ * g_inet_address_get_is_mc_global:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is a global multicast address.
+ *
+ * Returns: %TRUE if @address is a global multicast address.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_mc_global (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ return FALSE;
+ else
+ return IN6_IS_ADDR_MC_GLOBAL (&address->priv->addr.ipv6.s6_addr);
+}
+
+/**
+ * g_inet_address_get_is_mc_link_local:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is a link-local multicast address.
+ *
+ * Returns: %TRUE if @address is a link-local multicast address.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_mc_link_local (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ return FALSE;
+ else
+ return IN6_IS_ADDR_MC_LINKLOCAL (&address->priv->addr.ipv6.s6_addr);
+}
+
+/**
+ * g_inet_address_get_is_mc_node_local:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is a node-local multicast address.
+ *
+ * Returns: %TRUE if @address is a node-local multicast address.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_mc_node_local (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ return FALSE;
+ else
+ return IN6_IS_ADDR_MC_NODELOCAL (&address->priv->addr.ipv6.s6_addr);
+}
+
+/**
+ * g_inet_address_get_is_mc_org_local:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is an organization-local multicast address.
+ *
+ * Returns: %TRUE if @address is an organization-local multicast address.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_mc_org_local (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ return FALSE;
+ else
+ return IN6_IS_ADDR_MC_ORGLOCAL (&address->priv->addr.ipv6.s6_addr);
+}
+
+/**
+ * g_inet_address_get_is_mc_site_local:
+ * @address: a #GInetAddress
+ *
+ * Tests whether @address is a site-local multicast address.
+ *
+ * Returns: %TRUE if @address is a site-local multicast address.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_inet_address_get_is_mc_site_local (GInetAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
+
+ if (address->priv->family == AF_INET)
+ return FALSE;
+ else
+ return IN6_IS_ADDR_MC_SITELOCAL (&address->priv->addr.ipv6.s6_addr);
+}
+
+#define __G_INET_ADDRESS_C__
+#include "gioaliasdef.c"
diff --git a/gio/ginetaddress.h b/gio/ginetaddress.h
new file mode 100644
index 0000000..3f9e499
--- /dev/null
+++ b/gio/ginetaddress.h
@@ -0,0 +1,101 @@
+/* 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>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_INET_ADDRESS_H__
+#define __G_INET_ADDRESS_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_INET_ADDRESS (g_inet_address_get_type ())
+#define G_INET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_INET_ADDRESS, GInetAddress))
+#define G_INET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_INET_ADDRESS, GInetAddressClass))
+#define G_IS_INET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_INET_ADDRESS))
+#define G_IS_INET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_INET_ADDRESS))
+#define G_INET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_INET_ADDRESS, GInetAddressClass))
+
+typedef struct _GInetAddressClass GInetAddressClass;
+typedef struct _GInetAddressPrivate GInetAddressPrivate;
+
+struct _GInetAddress
+{
+ GObject parent_instance;
+
+ /*< private >*/
+ GInetAddressPrivate *priv;
+};
+
+struct _GInetAddressClass
+{
+ GObjectClass parent_class;
+
+ gchar * (*to_string) (GInetAddress *address);
+ const guint8 * (*to_bytes) (GInetAddress *address);
+};
+
+GType g_inet_address_get_type (void) G_GNUC_CONST;
+
+GInetAddress * g_inet_address_new_from_string (const gchar *string);
+
+GInetAddress * g_inet_address_new_from_bytes (const guint8 *bytes,
+ GSocketFamily family);
+
+GInetAddress * g_inet_address_new_loopback (GSocketFamily family);
+
+GInetAddress * g_inet_address_new_any (GSocketFamily family);
+
+gchar * g_inet_address_to_string (GInetAddress *address);
+
+const guint8 * g_inet_address_to_bytes (GInetAddress *address);
+
+GSocketFamily g_inet_address_get_family (GInetAddress *address);
+
+gboolean g_inet_address_get_is_any (GInetAddress *address);
+
+gboolean g_inet_address_get_is_loopback (GInetAddress *address);
+
+gboolean g_inet_address_get_is_link_local (GInetAddress *address);
+
+gboolean g_inet_address_get_is_site_local (GInetAddress *address);
+
+gboolean g_inet_address_get_is_multicast (GInetAddress *address);
+
+gboolean g_inet_address_get_is_mc_global (GInetAddress *address);
+
+gboolean g_inet_address_get_is_mc_link_local (GInetAddress *address);
+
+gboolean g_inet_address_get_is_mc_node_local (GInetAddress *address);
+
+gboolean g_inet_address_get_is_mc_org_local (GInetAddress *address);
+
+gboolean g_inet_address_get_is_mc_site_local (GInetAddress *address);
+
+G_END_DECLS
+
+#endif /* __G_INET_ADDRESS_H__ */
+
diff --git a/gio/ginetsocketaddress.c b/gio/ginetsocketaddress.c
new file mode 100644
index 0000000..b8275a8
--- /dev/null
+++ b/gio/ginetsocketaddress.c
@@ -0,0 +1,306 @@
+/* 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 "ginetsocketaddress.h"
+#include "ginetaddress.h"
+#include "gnetworkingprivate.h"
+
+#include "gioalias.h"
+
+/**
+ * SECTION:ginetsocketaddress
+ * @short_description: Internet socket addresses
+ *
+ * An IPv4 or IPv6 socket address; that is, the combination of a
+ * #GInetAddress and a port number.
+ **/
+
+/**
+ * GInetSocketAddress:
+ *
+ * An IPv4 or IPv6 socket address, corresponding to a <type>struct
+ * sockaddr_in</type> or <type>struct sockaddr_in6</type>.
+ **/
+G_DEFINE_TYPE (GInetSocketAddress, g_inet_socket_address, G_TYPE_SOCKET_ADDRESS);
+
+enum {
+ PROP_0,
+ PROP_ADDRESS,
+ PROP_PORT
+};
+
+struct _GInetSocketAddressPrivate
+{
+ GInetAddress *address;
+ guint16 port;
+};
+
+static void
+g_inet_socket_address_finalize (GObject *object)
+{
+ GInetSocketAddress *address G_GNUC_UNUSED = G_INET_SOCKET_ADDRESS (object);
+
+ if (G_OBJECT_CLASS (g_inet_socket_address_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_inet_socket_address_parent_class)->finalize) (object);
+}
+
+static void
+g_inet_socket_address_dispose (GObject *object)
+{
+ GInetSocketAddress *address G_GNUC_UNUSED = G_INET_SOCKET_ADDRESS (object);
+
+ g_object_unref (address->priv->address);
+
+ if (G_OBJECT_CLASS (g_inet_socket_address_parent_class)->dispose)
+ (*G_OBJECT_CLASS (g_inet_socket_address_parent_class)->dispose) (object);
+}
+
+static void
+g_inet_socket_address_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GInetSocketAddress *address = G_INET_SOCKET_ADDRESS (object);
+
+ switch (prop_id)
+ {
+ case PROP_ADDRESS:
+ g_value_set_object (value, address->priv->address);
+ break;
+
+ case PROP_PORT:
+ g_value_set_uint (value, address->priv->port);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_inet_socket_address_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GInetSocketAddress *address = G_INET_SOCKET_ADDRESS (object);
+
+ switch (prop_id)
+ {
+ case PROP_ADDRESS:
+ address->priv->address = g_object_ref (g_value_get_object (value));
+ break;
+
+ case PROP_PORT:
+ address->priv->port = (guint16) g_value_get_uint (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static GSocketFamily
+g_inet_socket_address_get_family (GSocketAddress *address)
+{
+ GInetSocketAddress *addr;
+
+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+
+ addr = G_INET_SOCKET_ADDRESS (address);
+
+ return g_inet_address_get_family (addr->priv->address);
+}
+
+static gssize
+g_inet_socket_address_get_native_size (GSocketAddress *address)
+{
+ GInetSocketAddress *addr;
+ GSocketFamily family;
+
+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+
+ addr = G_INET_SOCKET_ADDRESS (address);
+ family = g_inet_address_get_family (addr->priv->address);
+
+ if (family == AF_INET)
+ return sizeof (struct sockaddr_in);
+ else if (family == AF_INET6)
+ return sizeof (struct sockaddr_in6);
+ else
+ return -1;
+}
+
+static gboolean
+g_inet_socket_address_to_native (GSocketAddress *address,
+ gpointer dest,
+ gsize destlen)
+{
+ GInetSocketAddress *addr;
+ GSocketFamily family;
+
+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+
+ addr = G_INET_SOCKET_ADDRESS (address);
+ family = g_inet_address_get_family (addr->priv->address);
+
+ if (family == AF_INET)
+ {
+ struct sockaddr_in *sock = (struct sockaddr_in *) dest;
+
+ if (destlen < sizeof (*sock))
+ return FALSE;
+
+ sock->sin_family = AF_INET;
+ sock->sin_port = g_htons (addr->priv->port);
+ memcpy (&(sock->sin_addr.s_addr), g_inet_address_to_bytes (addr->priv->address), sizeof (sock->sin_addr));
+ memset (sock->sin_zero, 0, sizeof (sock->sin_zero));
+ return TRUE;
+ }
+ else if (family == AF_INET6)
+ {
+ struct sockaddr_in6 *sock = (struct sockaddr_in6 *) dest;
+
+ if (destlen < sizeof (*sock))
+ return FALSE;
+
+ memset (sock, 0, sizeof (sock));
+ sock->sin6_family = AF_INET6;
+ sock->sin6_port = g_htons (addr->priv->port);
+ memcpy (&(sock->sin6_addr.s6_addr), g_inet_address_to_bytes (addr->priv->address), sizeof (sock->sin6_addr));
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+g_inet_socket_address_class_init (GInetSocketAddressClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GInetSocketAddressPrivate));
+
+ gobject_class->finalize = g_inet_socket_address_finalize;
+ gobject_class->dispose = g_inet_socket_address_dispose;
+ gobject_class->set_property = g_inet_socket_address_set_property;
+ gobject_class->get_property = g_inet_socket_address_get_property;
+
+ gsocketaddress_class->get_family = g_inet_socket_address_get_family;
+ gsocketaddress_class->to_native = g_inet_socket_address_to_native;
+ gsocketaddress_class->get_native_size = g_inet_socket_address_get_native_size;
+
+ g_object_class_install_property (gobject_class, PROP_ADDRESS,
+ g_param_spec_object ("address",
+ "address",
+ "address",
+ G_TYPE_INET_ADDRESS,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
+
+ g_object_class_install_property (gobject_class, PROP_PORT,
+ g_param_spec_uint ("port",
+ "port",
+ "port",
+ 0,
+ 65535,
+ 0,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
+}
+
+static void
+g_inet_socket_address_init (GInetSocketAddress *address)
+{
+ address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
+ G_TYPE_INET_SOCKET_ADDRESS,
+ GInetSocketAddressPrivate);
+
+ address->priv->address = NULL;
+ address->priv->port = 0;
+}
+
+/**
+ * g_inet_socket_address_new:
+ * @address: a #GInetAddress
+ * @port: a port number
+ *
+ * Creates a new #GInetSocketAddress for @address and @port.
+ *
+ * Returns: a new #GInetSocketAddress
+ *
+ * Since: 2.22
+ */
+GSocketAddress *
+g_inet_socket_address_new (GInetAddress *address,
+ guint16 port)
+{
+ return g_object_new (G_TYPE_INET_SOCKET_ADDRESS,
+ "address", address,
+ "port", port,
+ NULL);
+}
+
+/**
+ * g_inet_socket_address_get_address:
+ * @address: a #GInetSocketAddress
+ *
+ * Gets @address's #GInetAddress.
+ *
+ * Returns: the #GInetAddress for @address, which must be
+ * g_object_ref()'d if it will be stored
+ *
+ * Since: 2.22
+ */
+GInetAddress *
+g_inet_socket_address_get_address (GInetSocketAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), NULL);
+
+ return address->priv->address;
+}
+
+/**
+ * g_inet_socket_address_get_port:
+ * @address: a #GInetSocketAddress
+ *
+ * Gets @address's port.
+ *
+ * Returns: the port for @address
+ *
+ * Since: 2.22
+ */
+guint16
+g_inet_socket_address_get_port (GInetSocketAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+
+ return address->priv->port;
+}
+
+#define __G_INET_SOCKET_ADDRESS_C__
+#include "gioaliasdef.c"
diff --git a/gio/ginetsocketaddress.h b/gio/ginetsocketaddress.h
new file mode 100644
index 0000000..b455ac5
--- /dev/null
+++ b/gio/ginetsocketaddress.h
@@ -0,0 +1,69 @@
+/* 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>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_INET_SOCKET_ADDRESS_H__
+#define __G_INET_SOCKET_ADDRESS_H__
+
+#include <gio/gsocketaddress.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_INET_SOCKET_ADDRESS (g_inet_socket_address_get_type ())
+#define G_INET_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_INET_SOCKET_ADDRESS, GInetSocketAddress))
+#define G_INET_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_INET_SOCKET_ADDRESS, GInetSocketAddressClass))
+#define G_IS_INET_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_INET_SOCKET_ADDRESS))
+#define G_IS_INET_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_INET_SOCKET_ADDRESS))
+#define G_INET_SOCKET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_INET_SOCKET_ADDRESS, GInetSocketAddressClass))
+
+typedef struct _GInetSocketAddressClass GInetSocketAddressClass;
+typedef struct _GInetSocketAddressPrivate GInetSocketAddressPrivate;
+
+struct _GInetSocketAddress
+{
+ GSocketAddress parent_instance;
+
+ /*< private >*/
+ GInetSocketAddressPrivate *priv;
+};
+
+struct _GInetSocketAddressClass
+{
+ GSocketAddressClass parent_class;
+};
+
+GType g_inet_socket_address_get_type (void) G_GNUC_CONST;
+
+GSocketAddress *g_inet_socket_address_new (GInetAddress *address,
+ guint16 port);
+
+GInetAddress * g_inet_socket_address_get_address (GInetSocketAddress *address);
+
+guint16 g_inet_socket_address_get_port (GInetSocketAddress *address);
+
+G_END_DECLS
+
+#endif /* __G_INET_SOCKET_ADDRESS_H__ */
diff --git a/gio/gio.h b/gio/gio.h
index e3a0b14..6e809ba 100644
--- a/gio/gio.h
+++ b/gio/gio.h
@@ -49,6 +49,8 @@
#include <gio/gfilterinputstream.h>
#include <gio/gfilteroutputstream.h>
#include <gio/gicon.h>
+#include <gio/ginetaddress.h>
+#include <gio/ginetsocketaddress.h>
#include <gio/ginputstream.h>
#include <gio/gioenums.h>
#include <gio/gioenumtypes.h>
@@ -64,6 +66,7 @@
#include <gio/goutputstream.h>
#include <gio/gseekable.h>
#include <gio/gsimpleasyncresult.h>
+#include <gio/gsocketaddress.h>
#include <gio/gthemedicon.h>
#include <gio/gvfs.h>
#include <gio/gvolume.h>
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 4dc5917..99ad117 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -833,6 +833,7 @@ g_output_stream_splice_flags_get_type G_GNUC_CONST
g_ask_password_flags_get_type G_GNUC_CONST
g_password_save_get_type G_GNUC_CONST
g_emblem_origin_get_type G_GNUC_CONST
+g_socket_family_get_type G_GNUC_CONST
#endif
#endif
@@ -857,3 +858,53 @@ g_emblem_get_origin
#endif
#endif
+#if IN_HEADER(__G_INET_ADDRESS_H__)
+#if IN_FILE(__G_INET_ADDRESS_C__)
+g_inet_address_new_from_string
+g_inet_address_new_from_bytes
+g_inet_address_new_any
+g_inet_address_new_loopback
+g_inet_address_get_family
+g_inet_address_get_type G_GNUC_CONST
+g_inet_address_get_is_any
+g_inet_address_get_is_link_local
+g_inet_address_get_is_loopback
+g_inet_address_get_is_mc_global
+g_inet_address_get_is_mc_link_local
+g_inet_address_get_is_mc_node_local
+g_inet_address_get_is_mc_org_local
+g_inet_address_get_is_mc_site_local
+g_inet_address_get_is_multicast
+g_inet_address_get_is_site_local
+g_inet_address_to_bytes
+g_inet_address_to_string
+#endif
+#endif
+
+#if IN_HEADER(__G_INET_SOCKET_ADDRESS_H__)
+#if IN_FILE(__G_INET_SOCKET_ADDRESS_C__)
+g_inet_socket_address_get_address
+g_inet_socket_address_get_port
+g_inet_socket_address_get_type G_GNUC_CONST
+g_inet_socket_address_new
+#endif
+#endif
+
+#if IN_HEADER(__G_UNIX_SOCKET_ADDRESS_H__)
+#if IN_FILE(__G_UNIX_SOCKET_ADDRESS_C__)
+#ifdef G_OS_UNIX
+g_unix_socket_address_get_type G_GNUC_CONST
+g_unix_socket_address_new
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_SOCKET_ADDRESS_H__)
+#if IN_FILE(__G_SOCKET_ADDRESS_C__)
+g_socket_address_new_from_native
+g_socket_address_get_type G_GNUC_CONST
+g_socket_address_get_family
+g_socket_address_get_native_size
+g_socket_address_to_native
+#endif
+#endif
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 3bb50ff..e6e6dfc 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -477,6 +477,26 @@ typedef enum {
} GEmblemOrigin;
+/**
+ * GSocketFamily:
+ * @G_SOCKET_FAMILY_INVALID: no address family
+ * @G_SOCKET_FAMILY_IPV4: the IPv4 family
+ * @G_SOCKET_FAMILY_IPV6: the IPv6 family
+ * @G_SOCKET_FAMILY_UNIX: the UNIX domain family
+ *
+ * The protocol family of a #GSocketAddress. (These values are
+ * identical to the system defines %AF_INET, %AF_INET6 and %AF_UNIX,
+ * if available.)
+ */
+typedef enum {
+ G_SOCKET_FAMILY_INVALID,
+#ifdef GLIB_SYSDEF_AF_UNIX
+ G_SOCKET_FAMILY_UNIX = GLIB_SYSDEF_AF_UNIX,
+#endif
+ G_SOCKET_FAMILY_IPV4 = GLIB_SYSDEF_AF_INET,
+ G_SOCKET_FAMILY_IPV6 = GLIB_SYSDEF_AF_INET6
+} GSocketFamily;
+
G_END_DECLS
#endif /* __GIO_ENUMS_H__ */
diff --git a/gio/giotypes.h b/gio/giotypes.h
index 981c195..6ea1c1b 100644
--- a/gio/giotypes.h
+++ b/gio/giotypes.h
@@ -75,6 +75,8 @@ typedef struct _GFilenameCompleter GFilenameCompleter;
typedef struct _GIcon GIcon; /* Dummy typedef */
+typedef struct _GInetAddress GInetAddress;
+typedef struct _GInetSocketAddress GInetSocketAddress;
typedef struct _GInputStream GInputStream;
typedef struct _GIOModule GIOModule;
typedef struct _GIOExtensionPoint GIOExtensionPoint;
@@ -97,9 +99,12 @@ typedef struct _GMemoryOutputStream GMemoryOutputStream;
**/
typedef struct _GMount GMount; /* Dummy typedef */
typedef struct _GMountOperation GMountOperation;
+typedef struct _GNetworkAddress GNetworkAddress;
+typedef struct _GNetworkService GNetworkService;
typedef struct _GOutputStream GOutputStream;
typedef struct _GSeekable GSeekable;
typedef struct _GSimpleAsyncResult GSimpleAsyncResult;
+typedef struct _GSocketAddress GSocketAddress;
typedef struct _GThemedIcon GThemedIcon;
typedef struct _GVfs GVfs; /* Dummy typedef */
diff --git a/gio/gnetworkingprivate.h b/gio/gnetworkingprivate.h
new file mode 100644
index 0000000..a90d264
--- /dev/null
+++ b/gio/gnetworkingprivate.h
@@ -0,0 +1,53 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __G_NETWORKINGPRIVATE_H__
+#define __G_NETWORKINGPRIVATE_H__
+
+#ifdef G_OS_WIN32
+
+#define WINVER 0x0501 // FIXME?
+#include <winsock2.h>
+#undef interface
+#include <ws2tcpip.h>
+#include <windns.h>
+
+#else /* !G_OS_WIN32 */
+
+#define BIND_4_COMPAT
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+/* We're supposed to define _GNU_SOURCE to get EAI_NODATA, but that
+ * won't actually work since <features.h> has already been included at
+ * this point. So we define __USE_GNU instead.
+ */
+#define __USE_GNU
+#include <netdb.h>
+#undef __USE_GNU
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <resolv.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#endif
+
+#endif /* __G_NETWORKINGPRIVATE_H__ */
diff --git a/gio/gsocketaddress.c b/gio/gsocketaddress.c
new file mode 100644
index 0000000..33e8ffd
--- /dev/null
+++ b/gio/gsocketaddress.c
@@ -0,0 +1,233 @@
+/* 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 "gsocketaddress.h"
+#include "ginetaddress.h"
+#include "ginetsocketaddress.h"
+#include "gnetworkingprivate.h"
+#include "glibintl.h"
+#include "gioenumtypes.h"
+
+#ifdef G_OS_UNIX
+#include "gunixsocketaddress.h"
+#endif
+
+#include "gioalias.h"
+
+/**
+ * SECTION:gsocketaddress
+ * @short_description: Abstract base class representing endpoints for
+ * socket communication
+ *
+ * #GSocketAddress is the equivalent of <type>struct sockaddr</type>
+ * in the BSD sockets API. This is an abstract class; use
+ * #GInetSocketAddress for internet sockets, or #GUnixSocketAddress
+ * for UNIX domain sockets.
+ **/
+
+/**
+ * GSocketAddress:
+ *
+ * A socket endpoint address, corresponding to <type>struct sockaddr</type>
+ * or one of its subtypes.
+ **/
+
+enum
+{
+ PROP_NONE,
+ PROP_FAMILY
+};
+
+G_DEFINE_ABSTRACT_TYPE (GSocketAddress, g_socket_address, G_TYPE_OBJECT);
+
+/**
+ * g_socket_address_get_family:
+ * @address: a #GSocketAddress
+ *
+ * Gets the socket family type of @address.
+ *
+ * Returns: the socket family type of @address.
+ *
+ * Since: 2.22
+ */
+GSocketFamily
+g_socket_address_get_family (GSocketAddress *address)
+{
+ g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), 0);
+
+ return G_SOCKET_ADDRESS_GET_CLASS (address)->get_family (address);
+}
+
+static void
+g_socket_address_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GSocketAddress *address = G_SOCKET_ADDRESS (object);
+
+ switch (prop_id)
+ {
+ case PROP_FAMILY:
+ g_value_set_enum (value, g_socket_address_get_family (address));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_socket_address_class_init (GSocketAddressClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->get_property = g_socket_address_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_FAMILY,
+ g_param_spec_enum ("family",
+ _("Address family"),
+ _("The family of the socket address"),
+ G_TYPE_SOCKET_FAMILY,
+ G_SOCKET_FAMILY_INVALID,
+ G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
+}
+
+static void
+g_socket_address_init (GSocketAddress *address)
+{
+
+}
+
+/**
+ * g_socket_address_get_native_size:
+ * @address: a #GSocketAddress
+ *
+ * Gets the size of @address's native <type>struct sockaddr</type>.
+ * You can use this to allocate memory to pass to
+ * g_socket_address_to_native().
+ *
+ * Returns: the size of the native <type>struct sockaddr</type> that
+ * @address represents
+ *
+ * Since: 2.22
+ */
+gssize
+g_socket_address_get_native_size (GSocketAddress *address)
+{
+ g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), -1);
+
+ return G_SOCKET_ADDRESS_GET_CLASS (address)->get_native_size (address);
+}
+
+/**
+ * g_socket_address_to_native:
+ * @address: a #GSocketAddress
+ * @dest: a pointer to a memory location that will contain the native
+ * <type>struct sockaddr</type>.
+ * @destlen: the size of @dest. Must be at least as large as
+ * g_socket_address_get_native_size().
+ *
+ * Converts a #GSocketAddress to a native <type>struct
+ * sockaddr</type>, which can be passed to low-level functions like
+ * connect() or bind().
+ *
+ * Returns: %TRUE if @dest was filled in, %FALSE if @address is invalid
+ * or @destlen is too small.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_socket_address_to_native (GSocketAddress *address,
+ gpointer dest,
+ gsize destlen)
+{
+ g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE);
+
+ return G_SOCKET_ADDRESS_GET_CLASS (address)->to_native (address, dest, destlen);
+}
+
+/**
+ * g_socket_address_new_from_native:
+ * @native: a pointer to a <type>struct sockaddr</type>
+ * @len: the size of the memory location pointed to by @native
+ *
+ * Creates a #GSocketAddress subclass corresponding to the native
+ * <type>struct sockaddr</type> @native.
+ *
+ * Returns: a new #GSocketAddress if @native could successfully be converted,
+ * otherwise %NULL.
+ *
+ * Since: 2.22
+ */
+GSocketAddress *
+g_socket_address_new_from_native (gpointer native,
+ gsize len)
+{
+ gshort family;
+
+ if (len < sizeof (gshort))
+ return NULL;
+
+ family = ((struct sockaddr *) native)->sa_family;
+
+ if (family == AF_UNSPEC)
+ return NULL;
+
+ if (family == AF_INET)
+ {
+ struct sockaddr_in *addr = (struct sockaddr_in *) native;
+ GInetAddress *iaddr = g_inet_address_new_from_bytes ((guint8 *) &(addr->sin_addr), AF_INET);
+ GSocketAddress *sockaddr;
+
+ sockaddr = g_inet_socket_address_new (iaddr, g_ntohs (addr->sin_port));
+ g_object_unref (iaddr);
+ return sockaddr;
+ }
+
+ if (family == AF_INET6)
+ {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) native;
+ GInetAddress *iaddr = g_inet_address_new_from_bytes ((guint8 *) &(addr->sin6_addr), AF_INET6);
+ GSocketAddress *sockaddr;
+
+ sockaddr = g_inet_socket_address_new (iaddr, g_ntohs (addr->sin6_port));
+ g_object_unref (iaddr);
+ return sockaddr;
+ }
+
+#ifdef G_OS_UNIX
+ if (family == AF_UNIX)
+ {
+ struct sockaddr_un *addr = (struct sockaddr_un *) native;
+
+ return g_unix_socket_address_new (addr->sun_path);
+ }
+#endif
+
+ return NULL;
+}
+
+#define __G_SOCKET_ADDRESS_C__
+#include "gioaliasdef.c"
diff --git a/gio/gsocketaddress.h b/gio/gsocketaddress.h
new file mode 100644
index 0000000..1649ba6
--- /dev/null
+++ b/gio/gsocketaddress.h
@@ -0,0 +1,77 @@
+/* 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>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_SOCKET_ADDRESS_H__
+#define __G_SOCKET_ADDRESS_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_SOCKET_ADDRESS (g_socket_address_get_type ())
+#define G_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SOCKET_ADDRESS, GSocketAddress))
+#define G_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SOCKET_ADDRESS, GSocketAddressClass))
+#define G_IS_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SOCKET_ADDRESS))
+#define G_IS_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SOCKET_ADDRESS))
+#define G_SOCKET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SOCKET_ADDRESS, GSocketAddressClass))
+
+typedef struct _GSocketAddressClass GSocketAddressClass;
+
+struct _GSocketAddress
+{
+ GObject parent_instance;
+};
+
+struct _GSocketAddressClass
+{
+ GObjectClass parent_class;
+
+ GSocketFamily (*get_family) (GSocketAddress *address);
+
+ gssize (*get_native_size) (GSocketAddress *address);
+
+ gboolean (*to_native) (GSocketAddress *address,
+ gpointer dest,
+ gsize destlen);
+};
+
+GType g_socket_address_get_type (void) G_GNUC_CONST;
+
+GSocketFamily g_socket_address_get_family (GSocketAddress *address);
+
+GSocketAddress * g_socket_address_new_from_native (gpointer native,
+ gsize len);
+
+gboolean g_socket_address_to_native (GSocketAddress *address,
+ gpointer dest,
+ gsize destlen);
+
+gssize g_socket_address_get_native_size (GSocketAddress *address);
+
+G_END_DECLS
+
+#endif /* __G_SOCKET_ADDRESS_H__ */
diff --git a/gio/gunixsocketaddress.c b/gio/gunixsocketaddress.c
new file mode 100644
index 0000000..0b1b7e3
--- /dev/null
+++ b/gio/gunixsocketaddress.c
@@ -0,0 +1,206 @@
+/* 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 "gnetworkingprivate.h"
+
+#include "gioalias.h"
+
+/**
+ * SECTION:gunixsocketaddress
+ * @short_description: Unix socket addresses
+ *
+ * Support for UNIX-domain (aka local) sockets.
+ **/
+
+/**
+ * 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,
+};
+
+struct _GUnixSocketAddressPrivate
+{
+ char *path;
+};
+
+static void
+g_unix_socket_address_finalize (GObject *object)
+{
+ GUnixSocketAddress *address G_GNUC_UNUSED = G_UNIX_SOCKET_ADDRESS (object);
+
+ g_free (address->priv->path);
+
+ if (G_OBJECT_CLASS (g_unix_socket_address_parent_class)->finalize)
+ (G_OBJECT_CLASS (g_unix_socket_address_parent_class)->finalize) (object);
+}
+
+static void
+g_unix_socket_address_dispose (GObject *object)
+{
+ GUnixSocketAddress *address G_GNUC_UNUSED = G_UNIX_SOCKET_ADDRESS (object);
+
+ if (G_OBJECT_CLASS (g_unix_socket_address_parent_class)->dispose)
+ (*G_OBJECT_CLASS (g_unix_socket_address_parent_class)->dispose) (object);
+}
+
+static void
+g_unix_socket_address_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GUnixSocketAddress *address = G_UNIX_SOCKET_ADDRESS (object);
+
+ switch (prop_id)
+ {
+ case PROP_PATH:
+ g_value_set_string (value, address->priv->path);
+ 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 void
+g_unix_socket_address_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GUnixSocketAddress *address = G_UNIX_SOCKET_ADDRESS (object);
+
+ switch (prop_id)
+ {
+ case PROP_PATH:
+ g_free (address->priv->path);
+ address->priv->path = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static gssize
+g_unix_socket_address_get_native_size (GSocketAddress *address)
+{
+ return sizeof (struct sockaddr_un);
+}
+
+static gboolean
+g_unix_socket_address_to_native (GSocketAddress *address,
+ gpointer dest,
+ gsize destlen)
+{
+ GUnixSocketAddress *addr = G_UNIX_SOCKET_ADDRESS (address);
+ struct sockaddr_un *sock;
+
+ if (destlen < sizeof (*sock))
+ return FALSE;
+
+ sock = (struct sockaddr_un *) dest;
+ sock->sun_family = AF_UNIX;
+ g_strlcpy (sock->sun_path, addr->priv->path, sizeof (sock->sun_path));
+
+ 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->finalize = g_unix_socket_address_finalize;
+ gobject_class->dispose = g_unix_socket_address_dispose;
+ 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",
+ _("Path"),
+ _("UNIX socket path"),
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+}
+
+static void
+g_unix_socket_address_init (GUnixSocketAddress *address)
+{
+ address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
+ G_TYPE_UNIX_SOCKET_ADDRESS,
+ GUnixSocketAddressPrivate);
+
+ address->priv->path = NULL;
+}
+
+/**
+ * g_unix_socket_address_new:
+ * @path: the socket path
+ *
+ * Creates a new #GUnixSocketAddress for @path.
+ *
+ * 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,
+ NULL);
+}
+
+#define __G_UNIX_SOCKET_ADDRESS_C__
+#include "gioaliasdef.c"
diff --git a/gio/gunixsocketaddress.h b/gio/gunixsocketaddress.h
new file mode 100644
index 0000000..527937f
--- /dev/null
+++ b/gio/gunixsocketaddress.h
@@ -0,0 +1,61 @@
+/* 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>
+ */
+
+#ifndef __G_UNIX_SOCKET_ADDRESS_H__
+#define __G_UNIX_SOCKET_ADDRESS_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_UNIX_SOCKET_ADDRESS (g_unix_socket_address_get_type ())
+#define G_UNIX_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_UNIX_SOCKET_ADDRESS, GUnixSocketAddress))
+#define G_UNIX_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_UNIX_SOCKET_ADDRESS, GUnixSocketAddressClass))
+#define G_IS_UNIX_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_UNIX_SOCKET_ADDRESS))
+#define G_IS_UNIX_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_UNIX_SOCKET_ADDRESS))
+#define G_UNIX_SOCKET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_UNIX_SOCKET_ADDRESS, GUnixSocketAddressClass))
+
+typedef struct _GUnixSocketAddress GUnixSocketAddress;
+typedef struct _GUnixSocketAddressClass GUnixSocketAddressClass;
+typedef struct _GUnixSocketAddressPrivate GUnixSocketAddressPrivate;
+
+struct _GUnixSocketAddress
+{
+ GSocketAddress parent_instance;
+
+ /*< private >*/
+ GUnixSocketAddressPrivate *priv;
+};
+
+struct _GUnixSocketAddressClass
+{
+ GSocketAddressClass parent_class;
+};
+
+GType g_unix_socket_address_get_type (void) G_GNUC_CONST;
+
+GSocketAddress *g_unix_socket_address_new (const gchar *path);
+
+G_END_DECLS
+
+#endif /* __G_UNIX_SOCKET_ADDRESS_H__ */
diff --git a/glibconfig.h.win32.in b/glibconfig.h.win32.in
index 92e8964..f10fa32 100644
--- a/glibconfig.h.win32.in
+++ b/glibconfig.h.win32.in
@@ -250,6 +250,9 @@ union _GSystemThread
*/
typedef void * GPid;
+#define GLIB_SYSDEF_AF_INET 2
+#define GLIB_SYSDEF_AF_INET6 23
+
G_END_DECLS
#endif /* GLIBCONFIG_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]