11d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering/* 21d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * ga-entry-group.c - Source for GaEntryGroup 342a376fd09fe2f9d73fd97c69cbc4150ea79d3bbSjoerd Simons * Copyright (C) 2006-2007 Collabora Ltd. 41d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * 51d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * This library is free software; you can redistribute it and/or 61d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * modify it under the terms of the GNU Lesser General Public 71d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * License as published by the Free Software Foundation; either 81d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * version 2.1 of the License, or (at your option) any later version. 91d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * 101d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * This library is distributed in the hope that it will be useful, 111d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of 121d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 131d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * Lesser General Public License for more details. 141d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * 151d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * You should have received a copy of the GNU Lesser General Public 161d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * License along with this library; if not, write to the Free Software 171d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 181d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering */ 191d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 201d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#ifdef HAVE_CONFIG_H 211d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#include <config.h> 221d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#endif 231d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 241d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#include <stdarg.h> 251d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#include <stdio.h> 261d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#include <stdlib.h> 271d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#include <string.h> 288e46e738cae449bf44232c66e973c8e9e15fbcb5Robert Ginda#include "avahi-common/avahi-malloc.h" 291d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3058ee9d8c85293eefa1e901c660fb30bf2b9122c8Sjoerd Simons#include "ga-error.h" 311d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#include "ga-entry-group.h" 321d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#include "ga-entry-group-enumtypes.h" 331d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 341d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart PoetteringG_DEFINE_TYPE(GaEntryGroup, ga_entry_group, G_TYPE_OBJECT) 351d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 361d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void _free_service(gpointer data); 371d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 381d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering/* signal enum */ 391d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringenum { 401d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering STATE_CHANGED, 411d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering LAST_SIGNAL 421d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering}; 431d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 441d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic guint signals[LAST_SIGNAL] = { 0 }; 451d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 461d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering/* properties */ 471d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringenum { 481d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering PROP_STATE = 1 491d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering}; 501d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 511d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering/* private structures */ 521d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringtypedef struct _GaEntryGroupPrivate GaEntryGroupPrivate; 531d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 541d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstruct _GaEntryGroupPrivate { 551d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupState state; 561d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaClient *client; 571d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiEntryGroup *group; 581d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GHashTable *services; 591d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering gboolean dispose_has_run; 601d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering}; 611d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 621d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringtypedef struct _GaEntryGroupServicePrivate GaEntryGroupServicePrivate; 631d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 641d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstruct _GaEntryGroupServicePrivate { 651d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupService public; 661d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroup *group; 671d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering gboolean frozen; 681d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GHashTable *entries; 691d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering}; 701d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 711d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringtypedef struct _GaEntryGroupServiceEntry GaEntryGroupServiceEntry; 721d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 731d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstruct _GaEntryGroupServiceEntry { 741d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint8 *value; 751d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering gsize size; 761d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering}; 771d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 781d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 791d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering#define GA_ENTRY_GROUP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GA_TYPE_ENTRY_GROUP, GaEntryGroupPrivate)) 801d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 811d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void ga_entry_group_init(GaEntryGroup * obj) { 821d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(obj); 831d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering /* allocate any data required by the object here */ 841d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->state = GA_ENTRY_GROUP_STATE_UNCOMMITED; 851d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->client = NULL; 861d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->group = NULL; 871d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->services = g_hash_table_new_full(g_direct_hash, 881d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_direct_equal, 891d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering NULL, _free_service); 901d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 911d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 921d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void ga_entry_group_dispose(GObject * object); 931d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void ga_entry_group_finalize(GObject * object); 941d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 951d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void ga_entry_group_get_property(GObject * object, 961d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint property_id, 971d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GValue * value, GParamSpec * pspec) { 981d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroup *group = GA_ENTRY_GROUP(object); 991d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(group); 1001d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1011d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering switch (property_id) { 1021d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering case PROP_STATE: 1031d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_value_set_enum(value, priv->state); 1041d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering break; 1051d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering default: 1061d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); 1071d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering break; 1081d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 1091d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 1101d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1111d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void ga_entry_group_class_init(GaEntryGroupClass * ga_entry_group_class) { 1121d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GObjectClass *object_class = G_OBJECT_CLASS(ga_entry_group_class); 1131d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GParamSpec *param_spec; 1141d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1151d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_type_class_add_private(ga_entry_group_class, 1161d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering sizeof (GaEntryGroupPrivate)); 1171d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1181d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering object_class->dispose = ga_entry_group_dispose; 1191d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering object_class->finalize = ga_entry_group_finalize; 1201d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering object_class->get_property = ga_entry_group_get_property; 1211d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1221d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering param_spec = g_param_spec_enum("state", "Entry Group state", 1231d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering "The state of the avahi entry group", 1241d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GA_TYPE_ENTRY_GROUP_STATE, 1251d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GA_ENTRY_GROUP_STATE_UNCOMMITED, 1261d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering G_PARAM_READABLE | 1271d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering G_PARAM_STATIC_NAME | 1281d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering G_PARAM_STATIC_BLURB); 1291d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_object_class_install_property(object_class, PROP_STATE, param_spec); 1301d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1311d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering signals[STATE_CHANGED] = 1321d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_signal_new("state-changed", 1331d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering G_OBJECT_CLASS_TYPE(ga_entry_group_class), 1341d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 1351d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 0, 1361d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering NULL, NULL, 1371d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_cclosure_marshal_VOID__ENUM, 1381d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering G_TYPE_NONE, 1, GA_TYPE_ENTRY_GROUP_STATE); 1391d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 1401d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1411d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringvoid ga_entry_group_dispose(GObject * object) { 1421d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroup *self = GA_ENTRY_GROUP(object); 1431d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(self); 1441d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1451d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (priv->dispose_has_run) 1461d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return; 1471d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->dispose_has_run = TRUE; 1481d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1491d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering /* release any references held by the object here */ 1501d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (priv->group) { 1511d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_entry_group_free(priv->group); 1521d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->group = NULL; 1531d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 1541d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1551d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (priv->client) { 1561d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_object_unref(priv->client); 1571d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->client = NULL; 1581d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 1591d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1601d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (G_OBJECT_CLASS(ga_entry_group_parent_class)->dispose) 1611d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering G_OBJECT_CLASS(ga_entry_group_parent_class)->dispose(object); 1621d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 1631d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1641d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringvoid ga_entry_group_finalize(GObject * object) { 1651d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroup *self = GA_ENTRY_GROUP(object); 1661d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(self); 1671d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1681d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering /* free any data held directly by the object here */ 1691d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_hash_table_destroy(priv->services); 1701d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->services = NULL; 1711d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1721d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering G_OBJECT_CLASS(ga_entry_group_parent_class)->finalize(object); 1731d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 1741d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1751d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void _free_service(gpointer data) { 1761d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupService *s = (GaEntryGroupService *) data; 1771d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServicePrivate *p = (GaEntryGroupServicePrivate *) s; 1781d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_free(s->name); 1791d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_free(s->type); 1801d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_free(s->domain); 1811d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_free(s->host); 1821d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_hash_table_destroy(p->entries); 1831d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_free(s); 1841d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 1851d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 1861d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic GQuark detail_for_state(AvahiEntryGroupState state) { 1871d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering static struct { 1882462c966a241720518f612a62a56f55bb8e4b1d6Lennart Poettering AvahiEntryGroupState state; 1891d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar *name; 1901d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GQuark quark; 1911d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } states[] = { 1921d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering { AVAHI_ENTRY_GROUP_UNCOMMITED, "uncommited", 0}, 1931d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering { AVAHI_ENTRY_GROUP_REGISTERING, "registering", 0}, 1941d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering { AVAHI_ENTRY_GROUP_ESTABLISHED, "established", 0}, 1951d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering { AVAHI_ENTRY_GROUP_COLLISION, "collistion", 0}, 1961d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering { AVAHI_ENTRY_GROUP_FAILURE, "failure", 0}, 1971d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering { 0, NULL, 0} 1981d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering }; 1991d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering int i; 2001d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2011d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering for (i = 0; states[i].name != NULL; i++) { 2021d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (state != states[i].state) 2031d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering continue; 2041d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2051d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (!states[i].quark) 2061d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering states[i].quark = g_quark_from_static_string(states[i].name); 2071d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return states[i].quark; 2081d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 2091d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_assert_not_reached(); 2101d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 2111d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2121d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void _avahi_entry_group_cb(AvahiEntryGroup * g, 2131d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiEntryGroupState state, void *data) { 2141d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroup *self = GA_ENTRY_GROUP(data); 2151d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(self); 2161d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2171d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering /* Avahi can call the callback before return from _client_new */ 2181d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (priv->group == NULL) 2191d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->group = g; 2201d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2211d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_assert(g == priv->group); 2221d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->state = state; 2231d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_signal_emit(self, signals[STATE_CHANGED], 2241d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering detail_for_state(state), state); 2251d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 2261d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2271d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart PoetteringGaEntryGroup *ga_entry_group_new(void) { 2281d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return g_object_new(GA_TYPE_ENTRY_GROUP, NULL); 2291d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 2301d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2311d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic guint _entry_hash(gconstpointer v) { 2321d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const GaEntryGroupServiceEntry *entry = 2331d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering (const GaEntryGroupServiceEntry *) v; 2341d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint32 h = 0; 2351d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint i; 2361d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2371d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering for (i = 0; i < entry->size; i++) { 2381d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering h = (h << 5) - h + entry->value[i]; 2391d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 2401d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2411d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return h; 2421d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 2431d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2441d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic gboolean _entry_equal(gconstpointer a, gconstpointer b) { 2451d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const GaEntryGroupServiceEntry *aentry = 2461d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering (const GaEntryGroupServiceEntry *) a; 2471d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const GaEntryGroupServiceEntry *bentry = 2481d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering (const GaEntryGroupServiceEntry *) b; 2491d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2501d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (aentry->size != bentry->size) { 2511d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return FALSE; 2521d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 2531d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2541d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return memcmp(aentry->value, bentry->value, aentry->size) == 0; 2551d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 2561d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2571d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic GaEntryGroupServiceEntry *_new_entry(const guint8 * value, gsize size) { 2581d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServiceEntry *entry; 2591d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2601d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (value == NULL) { 2611d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return NULL; 2621d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 2631d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2641d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering entry = g_slice_new(GaEntryGroupServiceEntry); 2651d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering entry->value = g_malloc(size + 1); 2661d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering memcpy(entry->value, value, size); 2671d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering /* for string keys, make sure it's NUL-terminated too */ 2681d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering entry->value[size] = 0; 2691d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering entry->size = size; 2701d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2711d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return entry; 2721d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 2731d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2741d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void _set_entry(GHashTable * table, const guint8 * key, gsize ksize, 2751d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const guint8 * value, gsize vsize) { 2761d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2771d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_hash_table_insert(table, _new_entry(key, ksize), 2781d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering _new_entry(value, vsize)); 2791d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 2801d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2811d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void _free_entry(gpointer data) { 2821d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServiceEntry *entry = (GaEntryGroupServiceEntry *) data; 2831d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2841d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (entry == NULL) { 2851d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return; 2861d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 2871d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2881d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_free(entry->value); 2891d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_slice_free(GaEntryGroupServiceEntry, entry); 2901d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 2911d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2921d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic GHashTable *_string_list_to_hash(AvahiStringList * list) { 2931d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GHashTable *ret; 2941d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiStringList *t; 2951d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2961d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ret = g_hash_table_new_full(_entry_hash, 2971d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering _entry_equal, _free_entry, _free_entry); 2981d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 2991d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering for (t = list; t != NULL; t = avahi_string_list_get_next(t)) { 3001d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering gchar *key; 3011d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering gchar *value; 3021d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering gsize size; 3031d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering int r; 3041d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3051d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering /* list_get_pair only fails if if memory allocation fails. Normal glib 3061d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering * behaviour is to assert/abort when that happens */ 3071d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering r = avahi_string_list_get_pair(t, &key, &value, &size); 3081d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_assert(r == 0); 3091d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3101d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (value == NULL) { 3111d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering _set_entry(ret, t->text, t->size, NULL, 0); 3121d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } else { 3131d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering _set_entry(ret, (const guint8 *) key, strlen(key), 3141d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering (const guint8 *) value, size); 3151d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 3161d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_free(key); 3171d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_free(value); 3181d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 3191d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return ret; 3201d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 3211d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3221d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic void _hash_to_string_list_foreach(gpointer key, gpointer value, gpointer data) { 3231d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiStringList **list = (AvahiStringList **) data; 3241d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServiceEntry *kentry = (GaEntryGroupServiceEntry *) key; 3251d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServiceEntry *ventry = (GaEntryGroupServiceEntry *) value; 3261d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3271d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (value != NULL) { 3281d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering *list = avahi_string_list_add_pair_arbitrary(*list, 3291d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering (gchar *) kentry->value, 3301d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ventry->value, 3311d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ventry->size); 3321d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } else { 3331d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering *list = avahi_string_list_add_arbitrary(*list, 3341d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering kentry->value, kentry->size); 3351d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 3361d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 3371d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3381d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringstatic AvahiStringList *_hash_to_string_list(GHashTable * table) { 3391d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiStringList *list = NULL; 3401d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_hash_table_foreach(table, _hash_to_string_list_foreach, 3411d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering (gpointer) & list); 3421d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return list; 3431d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 3441d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3451d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart PoetteringGaEntryGroupService *ga_entry_group_add_service_strlist(GaEntryGroup * group, 3461d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * name, 3471d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * type, 3481d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint16 port, 3491d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GError ** error, 3501d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiStringList * 3511d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering txt) { 3521d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return ga_entry_group_add_service_full_strlist(group, AVAHI_IF_UNSPEC, 3531d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AVAHI_PROTO_UNSPEC, 0, 3541d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering name, type, NULL, NULL, 3551d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering port, error, txt); 3561d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 3571d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3581d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart PoetteringGaEntryGroupService *ga_entry_group_add_service_full_strlist(GaEntryGroup * 3591d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering group, 3601d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiIfIndex 3611d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering interface, 3621d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiProtocol 3631d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering protocol, 3641d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiPublishFlags 3651d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering flags, 3661d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * 3671d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering name, 3681d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * 3691d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering type, 3701d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * 3711d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering domain, 3721d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * 3731d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering host, 3741d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint16 port, 3751d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GError ** error, 3761d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiStringList * 3771d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering txt) { 3781d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(group); 3791d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServicePrivate *service = NULL; 3801d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering int ret; 3811d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3821d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ret = avahi_entry_group_add_service_strlst(priv->group, 3831d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering interface, protocol, 3841d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering flags, 3851d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering name, type, 3861d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering domain, host, port, txt); 3871d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (ret) { 3881d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (error != NULL) { 38958ee9d8c85293eefa1e901c660fb30bf2b9122c8Sjoerd Simons *error = g_error_new(GA_ERROR, ret, 3901d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering "Adding service to group failed: %s", 3911d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_strerror(ret)); 3921d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 3931d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering goto out; 3941d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 3951d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 3961d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service = g_new0(GaEntryGroupServicePrivate, 1); 3971d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->public.interface = interface; 3981d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->public.protocol = protocol; 3991d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->public.flags = flags; 4001d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->public.name = g_strdup(name); 4011d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->public.type = g_strdup(type); 4021d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->public.domain = g_strdup(domain); 4031d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->public.host = g_strdup(host); 4041d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->public.port = port; 4051d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->group = group; 4061d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->frozen = FALSE; 4071d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->entries = _string_list_to_hash(txt); 4081d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_hash_table_insert(priv->services, group, service); 4091d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering out: 4101d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return (GaEntryGroupService *) service; 4111d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 4121d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 4131d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart PoetteringGaEntryGroupService *ga_entry_group_add_service(GaEntryGroup * group, 4141d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * name, 4151d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * type, 4161d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint16 port, 4171d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GError ** error, ...) { 4181d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupService *ret; 4191d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiStringList *txt = NULL; 4201d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering va_list va; 4211d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering va_start(va, error); 4221d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering txt = avahi_string_list_new_va(va); 4231d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 4241d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ret = ga_entry_group_add_service_full_strlist(group, 4251d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AVAHI_IF_UNSPEC, 4261d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AVAHI_PROTO_UNSPEC, 4271d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 0, 4281d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering name, type, 4291d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering NULL, NULL, 4301d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering port, error, txt); 4311d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_string_list_free(txt); 4321d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering va_end(va); 4331d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return ret; 4341d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 4351d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 4361d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart PoetteringGaEntryGroupService *ga_entry_group_add_service_full(GaEntryGroup * group, 4371d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiIfIndex interface, 4381d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiProtocol protocol, 4391d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiPublishFlags flags, 4401d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * name, 4411d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * type, 4421d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * domain, 4431d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * host, 4441d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint16 port, 4451d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GError ** error, ...) { 4461d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupService *ret; 4471d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiStringList *txt = NULL; 4481d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering va_list va; 4491d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 4501d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering va_start(va, error); 4511d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering txt = avahi_string_list_new_va(va); 4521d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 4531d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ret = ga_entry_group_add_service_full_strlist(group, 4541d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering interface, protocol, 4551d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering flags, 4561d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering name, type, 4571d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering domain, host, 4581d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering port, error, txt); 4591d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_string_list_free(txt); 4601d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering va_end(va); 4611d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return ret; 4621d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 4631d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 4641d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringgboolean ga_entry_group_add_record(GaEntryGroup * group, 4651d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiPublishFlags flags, 4661d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * name, 4671d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint16 type, 4681d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint32 ttl, 4691d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const void *rdata, gsize size, GError ** error) { 4701d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return ga_entry_group_add_record_full(group, 4711d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 4721d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering flags, name, AVAHI_DNS_CLASS_IN, 4731d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering type, ttl, rdata, size, error); 4741d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 4751d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 4761d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringgboolean ga_entry_group_add_record_full(GaEntryGroup * group, 4771d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiIfIndex interface, 4781d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiProtocol protocol, 4791d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiPublishFlags flags, 4801d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * name, 4811d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint16 clazz, 4821d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint16 type, 4831d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering guint32 ttl, 4841d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const void *rdata, 4851d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering gsize size, GError ** error) { 4861d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering int ret; 4871d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(group); 4881d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_assert(group != NULL && priv->group != NULL); 4891d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 4901d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ret = avahi_entry_group_add_record(priv->group, interface, protocol, 4911d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering flags, name, clazz, type, ttl, rdata, 4921d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering size); 4931d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (ret) { 4941d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (error != NULL) { 49558ee9d8c85293eefa1e901c660fb30bf2b9122c8Sjoerd Simons *error = g_error_new(GA_ERROR, ret, 4961d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering "Setting raw record failed: %s", 4971d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_strerror(ret)); 4981d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 4991d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return FALSE; 5001d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 5011d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return TRUE; 5021d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 5031d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5041d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5051d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringvoid ga_entry_group_service_freeze(GaEntryGroupService * service) { 5061d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServicePrivate *p = (GaEntryGroupServicePrivate *) service; 5071d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering p->frozen = TRUE; 5081d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 5091d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5101d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringgboolean ga_entry_group_service_thaw(GaEntryGroupService * service, GError ** error) { 5111d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServicePrivate *priv = (GaEntryGroupServicePrivate *) service; 5121d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering int ret; 5131d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering gboolean result = TRUE; 5141d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5151d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering AvahiStringList *txt = _hash_to_string_list(priv->entries); 5161d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ret = avahi_entry_group_update_service_txt_strlst 5171d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering (GA_ENTRY_GROUP_GET_PRIVATE(priv->group)->group, 5181d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->interface, service->protocol, service->flags, 5191d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering service->name, service->type, service->domain, txt); 5201d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (ret) { 5211d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (error != NULL) { 52258ee9d8c85293eefa1e901c660fb30bf2b9122c8Sjoerd Simons *error = g_error_new(GA_ERROR, ret, 5231d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering "Updating txt record failed: %s", 5241d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_strerror(ret)); 5251d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 5261d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering result = FALSE; 5271d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 5281d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5291d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_string_list_free(txt); 5301d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->frozen = FALSE; 5311d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return result; 5321d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 5331d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5341d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringgboolean ga_entry_group_service_set(GaEntryGroupService * service, 5351d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * key, const gchar * value, 5361d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GError ** error) { 5371d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return ga_entry_group_service_set_arbitrary(service, key, 5381d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering (const guint8 *) value, 5391d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering strlen(value), error); 5401d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5411d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 5421d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5431d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringgboolean ga_entry_group_service_set_arbitrary(GaEntryGroupService * service, 5441d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * key, const guint8 * value, 5451d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering gsize size, GError ** error) { 5461d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServicePrivate *priv = (GaEntryGroupServicePrivate *) service; 5471d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5481d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering _set_entry(priv->entries, (const guint8 *) key, strlen(key), value, size); 5491d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5501d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (!priv->frozen) 5511d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return ga_entry_group_service_thaw(service, error); 5521d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering else 5531d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return TRUE; 5541d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 5551d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5561d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringgboolean ga_entry_group_service_remove_key(GaEntryGroupService * service, 5571d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering const gchar * key, GError ** error) { 5581d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupServicePrivate *priv = (GaEntryGroupServicePrivate *) service; 559505fd1b5c1dadff46f4b50df76f9ee978351b3dcSjoerd Simons GaEntryGroupServiceEntry entry; 5601d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 561012a5048366fb661ce37287dcf6de60497f102dcLennart Poettering entry.value = (void*) key; 562505fd1b5c1dadff46f4b50df76f9ee978351b3dcSjoerd Simons entry.size = strlen(key); 563505fd1b5c1dadff46f4b50df76f9ee978351b3dcSjoerd Simons 564505fd1b5c1dadff46f4b50df76f9ee978351b3dcSjoerd Simons g_hash_table_remove(priv->entries, &entry); 5651d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5661d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (!priv->frozen) 5671d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return ga_entry_group_service_thaw(service, error); 5681d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering else 5691d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return TRUE; 5701d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 5711d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5721d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5731d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringgboolean ga_entry_group_attach(GaEntryGroup * group, 5741d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaClient * client, GError ** error) { 5751d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(group); 5761d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 577ac84e2a88f37aa778a9ac7be6bbb7b44b431cd57Sjoerd Simons g_return_val_if_fail(client->avahi_client, FALSE); 5781d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_assert(priv->client == NULL || priv->client == client); 5791d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_assert(priv->group == NULL); 5801d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5811d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->client = client; 5821d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering g_object_ref(client); 5831d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5841d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering priv->group = avahi_entry_group_new(client->avahi_client, 5851d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering _avahi_entry_group_cb, group); 5861d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (priv->group == NULL) { 5871d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (error != NULL) { 5881d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering int aerrno = avahi_client_errno(client->avahi_client); 58958ee9d8c85293eefa1e901c660fb30bf2b9122c8Sjoerd Simons *error = g_error_new(GA_ERROR, aerrno, 5901d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering "Attaching group failed: %s", 5911d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_strerror(aerrno)); 5921d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 5931d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return FALSE; 5941d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 5951d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return TRUE; 5961d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 5971d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 5981d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringgboolean ga_entry_group_commit(GaEntryGroup * group, GError ** error) { 5991d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(group); 6001d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering int ret; 6011d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ret = avahi_entry_group_commit(priv->group); 6021d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (ret) { 6031d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (error != NULL) { 60458ee9d8c85293eefa1e901c660fb30bf2b9122c8Sjoerd Simons *error = g_error_new(GA_ERROR, ret, 6051d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering "Committing group failed: %s", 6061d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_strerror(ret)); 6071d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 6081d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return FALSE; 6091d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 6101d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return TRUE; 6111d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 6121d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering 6131d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poetteringgboolean ga_entry_group_reset(GaEntryGroup * group, GError ** error) { 6141d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering GaEntryGroupPrivate *priv = GA_ENTRY_GROUP_GET_PRIVATE(group); 6151d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering int ret; 6161d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering ret = avahi_entry_group_reset(priv->group); 6171d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (ret) { 6181d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering if (error != NULL) { 61958ee9d8c85293eefa1e901c660fb30bf2b9122c8Sjoerd Simons *error = g_error_new(GA_ERROR, ret, 6201d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering "Resetting group failed: %s", 6211d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering avahi_strerror(ret)); 6221d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 6231d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return FALSE; 6241d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering } 6251d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering return TRUE; 6261d987ef7422a107305d21f8b0c4903e7b7b6d93fLennart Poettering} 627