udapted vi.po
[rhythmbox.git] / daapsharing / rb-daap-mdns-publisher-avahi.c
blob7799b8f981fd7215fead933b7bc7d084e279707a
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 * Copyright (C) 2005 Charles Schmidt <cschmidt2@emich.edu>
4 * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "config.h"
24 #include <stdlib.h>
25 #include <stdio.h>
27 #include <glib.h>
28 #include <glib/gi18n.h>
29 #include <glib-object.h>
31 #ifdef HAVE_AVAHI_0_6
32 #include <avahi-client/lookup.h>
33 #include <avahi-client/publish.h>
34 #endif
35 #include <avahi-client/client.h>
36 #include <avahi-common/error.h>
37 #include <avahi-glib/glib-malloc.h>
38 #include <avahi-glib/glib-watch.h>
40 #include "rb-daap-mdns-publisher.h"
41 #include "rb-debug.h"
43 static void rb_daap_mdns_publisher_class_init (RBDaapMdnsPublisherClass *klass);
44 static void rb_daap_mdns_publisher_init (RBDaapMdnsPublisher *publisher);
45 static void rb_daap_mdns_publisher_finalize (GObject *object);
47 #define RB_DAAP_MDNS_PUBLISHER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DAAP_MDNS_PUBLISHER, RBDaapMdnsPublisherPrivate))
49 struct RBDaapMdnsPublisherPrivate
51 AvahiClient *client;
52 AvahiGLibPoll *poll;
53 AvahiEntryGroup *entry_group;
55 char *name;
56 guint port;
57 gboolean password_required;
60 enum {
61 PUBLISHED,
62 NAME_COLLISION,
63 LAST_SIGNAL
66 enum {
67 PROP_0
70 static guint signals [LAST_SIGNAL] = { 0, };
72 G_DEFINE_TYPE (RBDaapMdnsPublisher, rb_daap_mdns_publisher, G_TYPE_OBJECT)
74 static gpointer publisher_object = NULL;
76 GQuark
77 rb_daap_mdns_publisher_error_quark (void)
79 static GQuark quark = 0;
80 if (!quark)
81 quark = g_quark_from_static_string ("rb_daap_mdns_publisher_error");
83 return quark;
86 static void
87 client_cb (AvahiClient *client,
88 AvahiClientState state,
89 RBDaapMdnsPublisher *publisher)
91 /* FIXME
92 * check to make sure we're in the _RUNNING state before we publish
93 * check for COLLISION state and remove published information
96 /* Called whenever the client or server state changes */
98 switch (state) {
99 case AVAHI_CLIENT_S_RUNNING:
101 /* The server has startup successfully and registered its host
102 * name on the network, so it's time to create our services */
104 break;
106 case AVAHI_CLIENT_S_COLLISION:
108 /* Let's drop our registered services. When the server is back
109 * in AVAHI_SERVER_RUNNING state we will register them
110 * again with the new host name. */
111 if (publisher->priv->entry_group) {
112 avahi_entry_group_reset (publisher->priv->entry_group);
114 break;
116 #ifdef HAVE_AVAHI_0_6
117 case AVAHI_CLIENT_FAILURE:
119 g_warning ("Client failure: %s\n", avahi_strerror (avahi_client_errno (client)));
120 break;
121 case AVAHI_CLIENT_CONNECTING:
122 case AVAHI_CLIENT_S_REGISTERING:
123 #endif
124 default:
125 break;
129 static void
130 avahi_client_init (RBDaapMdnsPublisher *publisher)
132 gint error = 0;
134 avahi_set_allocator (avahi_glib_allocator ());
136 publisher->priv->poll = avahi_glib_poll_new (NULL, G_PRIORITY_DEFAULT);
138 if (! publisher->priv->poll) {
139 rb_debug ("Unable to create AvahiGlibPoll object for mDNS");
142 #ifdef HAVE_AVAHI_0_5
143 publisher->priv->client = avahi_client_new (avahi_glib_poll_get (publisher->priv->poll),
144 (AvahiClientCallback) client_cb,
145 publisher,
146 &error);
147 #endif
148 #ifdef HAVE_AVAHI_0_6
150 AvahiClientFlags flags;
151 flags = 0;
153 publisher->priv->client = avahi_client_new (avahi_glib_poll_get (publisher->priv->poll),
154 flags,
155 (AvahiClientCallback)client_cb,
156 publisher,
157 &error);
159 #endif
162 static void
163 entry_group_cb (AvahiEntryGroup *group,
164 AvahiEntryGroupState state,
165 RBDaapMdnsPublisher *publisher)
167 if (state == AVAHI_ENTRY_GROUP_ESTABLISHED) {
169 g_signal_emit (publisher, signals [PUBLISHED], 0, publisher->priv->name);
171 } else if (state == AVAHI_ENTRY_GROUP_COLLISION) {
172 g_warning ("MDNS name collision");
174 g_signal_emit (publisher, signals [NAME_COLLISION], 0, publisher->priv->name);
178 static gboolean
179 create_service (RBDaapMdnsPublisher *publisher,
180 GError **error)
182 int ret;
183 const char *txt_record;
185 if (publisher->priv->entry_group == NULL) {
186 publisher->priv->entry_group = avahi_entry_group_new (publisher->priv->client,
187 (AvahiEntryGroupCallback)entry_group_cb,
188 publisher);
189 } else {
190 avahi_entry_group_reset (publisher->priv->entry_group);
193 if (publisher->priv->entry_group == NULL) {
194 rb_debug ("Could not create AvahiEntryGroup for publishing");
195 g_set_error (error,
196 RB_DAAP_MDNS_PUBLISHER_ERROR,
197 RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
198 "%s",
199 _("Could not create AvahiEntryGroup for publishing"));
200 return FALSE;
203 #if 0
204 g_message ("Service name:%s port:%u password:%d",
205 publisher->priv->name,
206 publisher->priv->port,
207 publisher->priv->password_required);
208 #endif
210 if (publisher->priv->password_required) {
211 txt_record = "Password=true";
212 } else {
213 txt_record = "Password=false";
216 ret = avahi_entry_group_add_service (publisher->priv->entry_group,
217 AVAHI_IF_UNSPEC,
218 AVAHI_PROTO_UNSPEC,
219 #ifdef HAVE_AVAHI_0_6
221 #endif
222 publisher->priv->name,
223 "_daap._tcp",
224 NULL,
225 NULL,
226 publisher->priv->port,
227 txt_record,
228 NULL);
230 if (ret < 0) {
231 g_set_error (error,
232 RB_DAAP_MDNS_PUBLISHER_ERROR,
233 RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
234 "%s: %s",
235 _("Could not add service"),
236 avahi_strerror (ret));
237 return FALSE;
240 ret = avahi_entry_group_commit (publisher->priv->entry_group);
242 if (ret < 0) {
243 g_set_error (error,
244 RB_DAAP_MDNS_PUBLISHER_ERROR,
245 RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
246 "%s: %s",
247 _("Could not commit service"),
248 avahi_strerror (ret));
249 return FALSE;
252 return TRUE;
255 static gboolean
256 refresh_service (RBDaapMdnsPublisher *publisher,
257 GError **error)
259 return create_service (publisher, error);
262 static gboolean
263 publisher_set_name_internal (RBDaapMdnsPublisher *publisher,
264 const char *name,
265 GError **error)
267 g_free (publisher->priv->name);
268 publisher->priv->name = g_strdup (name);
270 return TRUE;
273 gboolean
274 rb_daap_mdns_publisher_set_name (RBDaapMdnsPublisher *publisher,
275 const char *name,
276 GError **error)
278 g_return_val_if_fail (publisher != NULL, FALSE);
280 publisher_set_name_internal (publisher, name, error);
282 if (publisher->priv->entry_group) {
283 refresh_service (publisher, error);
286 return TRUE;
289 static gboolean
290 publisher_set_port_internal (RBDaapMdnsPublisher *publisher,
291 guint port,
292 GError **error)
294 publisher->priv->port = port;
296 return TRUE;
299 gboolean
300 rb_daap_mdns_publisher_set_port (RBDaapMdnsPublisher *publisher,
301 guint port,
302 GError **error)
304 g_return_val_if_fail (publisher != NULL, FALSE);
306 publisher_set_port_internal (publisher, port, error);
308 if (publisher->priv->entry_group) {
309 refresh_service (publisher, error);
312 return TRUE;
315 static gboolean
316 publisher_set_password_required_internal (RBDaapMdnsPublisher *publisher,
317 gboolean required,
318 GError **error)
320 publisher->priv->password_required = required;
321 return TRUE;
324 gboolean
325 rb_daap_mdns_publisher_set_password_required (RBDaapMdnsPublisher *publisher,
326 gboolean required,
327 GError **error)
329 g_return_val_if_fail (publisher != NULL, FALSE);
331 publisher_set_password_required_internal (publisher, required, error);
333 if (publisher->priv->entry_group) {
334 refresh_service (publisher, error);
337 return TRUE;
340 gboolean
341 rb_daap_mdns_publisher_publish (RBDaapMdnsPublisher *publisher,
342 const char *name,
343 guint port,
344 gboolean password_required,
345 GError **error)
347 if (publisher->priv->client == NULL) {
348 g_set_error (error,
349 RB_DAAP_MDNS_PUBLISHER_ERROR,
350 RB_DAAP_MDNS_PUBLISHER_ERROR_NOT_RUNNING,
351 "%s",
352 _("The avahi MDNS service is not running"));
353 return FALSE;
356 publisher_set_name_internal (publisher, name, NULL);
357 publisher_set_port_internal (publisher, port, NULL);
358 publisher_set_password_required_internal (publisher, password_required, NULL);
360 return create_service (publisher, error);
363 gboolean
364 rb_daap_mdns_publisher_withdraw (RBDaapMdnsPublisher *publisher,
365 GError **error)
367 if (publisher->priv->client == NULL) {
368 g_set_error (error,
369 RB_DAAP_MDNS_PUBLISHER_ERROR,
370 RB_DAAP_MDNS_PUBLISHER_ERROR_NOT_RUNNING,
371 "%s",
372 _("The avahi MDNS service is not running"));
373 return FALSE;
376 if (publisher->priv->entry_group == NULL) {
377 g_set_error (error,
378 RB_DAAP_MDNS_PUBLISHER_ERROR,
379 RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
380 "%s",
381 _("The MDNS service is not published"));
382 return FALSE;
385 avahi_entry_group_reset (publisher->priv->entry_group);
386 avahi_entry_group_free (publisher->priv->entry_group);
387 publisher->priv->entry_group = NULL;
389 return TRUE;
392 static void
393 rb_daap_mdns_publisher_set_property (GObject *object,
394 guint prop_id,
395 const GValue *value,
396 GParamSpec *pspec)
398 switch (prop_id) {
399 default:
400 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
401 break;
405 static void
406 rb_daap_mdns_publisher_get_property (GObject *object,
407 guint prop_id,
408 GValue *value,
409 GParamSpec *pspec)
411 switch (prop_id) {
412 default:
413 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
414 break;
418 static void
419 rb_daap_mdns_publisher_class_init (RBDaapMdnsPublisherClass *klass)
421 GObjectClass *object_class = G_OBJECT_CLASS (klass);
423 object_class->finalize = rb_daap_mdns_publisher_finalize;
424 object_class->get_property = rb_daap_mdns_publisher_get_property;
425 object_class->set_property = rb_daap_mdns_publisher_set_property;
427 signals [PUBLISHED] =
428 g_signal_new ("published",
429 G_TYPE_FROM_CLASS (object_class),
430 G_SIGNAL_RUN_LAST,
431 G_STRUCT_OFFSET (RBDaapMdnsPublisherClass, published),
432 NULL,
433 NULL,
434 g_cclosure_marshal_VOID__STRING,
435 G_TYPE_NONE,
436 1, G_TYPE_STRING);
437 signals [NAME_COLLISION] =
438 g_signal_new ("name-collision",
439 G_TYPE_FROM_CLASS (object_class),
440 G_SIGNAL_RUN_LAST,
441 G_STRUCT_OFFSET (RBDaapMdnsPublisherClass, name_collision),
442 NULL,
443 NULL,
444 g_cclosure_marshal_VOID__STRING,
445 G_TYPE_NONE,
446 1, G_TYPE_STRING);
448 g_type_class_add_private (klass, sizeof (RBDaapMdnsPublisherPrivate));
451 static void
452 rb_daap_mdns_publisher_init (RBDaapMdnsPublisher *publisher)
454 publisher->priv = RB_DAAP_MDNS_PUBLISHER_GET_PRIVATE (publisher);
456 avahi_client_init (publisher);
459 static void
460 rb_daap_mdns_publisher_finalize (GObject *object)
462 RBDaapMdnsPublisher *publisher;
464 g_return_if_fail (object != NULL);
465 g_return_if_fail (RB_IS_DAAP_MDNS_PUBLISHER (object));
467 publisher = RB_DAAP_MDNS_PUBLISHER (object);
469 g_return_if_fail (publisher->priv != NULL);
471 if (publisher->priv->entry_group) {
472 avahi_entry_group_free (publisher->priv->entry_group);
475 if (publisher->priv->client) {
476 avahi_client_free (publisher->priv->client);
479 if (publisher->priv->poll) {
480 avahi_glib_poll_free (publisher->priv->poll);
483 g_free (publisher->priv->name);
485 G_OBJECT_CLASS (rb_daap_mdns_publisher_parent_class)->finalize (object);
488 RBDaapMdnsPublisher *
489 rb_daap_mdns_publisher_new (void)
491 if (publisher_object) {
492 g_object_ref (publisher_object);
493 } else {
494 publisher_object = g_object_new (RB_TYPE_DAAP_MDNS_PUBLISHER, NULL);
495 g_object_add_weak_pointer (publisher_object,
496 (gpointer *) &publisher_object);
499 return RB_DAAP_MDNS_PUBLISHER (publisher_object);