~ubuntu-branches/ubuntu/vivid/liferea/vivid-proposed

« back to all changes in this revision

Viewing changes to src/sync/avahi_publisher.c

  • Committer: Package Import Robot
  • Author(s): bojo42
  • Date: 2012-03-29 14:17:21 UTC
  • mfrom: (1.3.9) (3.2.5 sid)
  • Revision ID: package-import@ubuntu.com-20120329141721-tbfopcrc5797wxt7
Tags: 1.8.3-0.1ubuntu1
* New upstream release (LP: #290666, #371754, #741543, #716688)
* Merge from Debian unstable (LP: #935147), remaining changes:
* debian/patches:
  - drop gtk-status-icon.patch & notification-append as in upstream
  - drop fix_systray_behavior as mostly upstreamed and rest seems unused
  - 01_ubuntu_feedlists: update & rename, move planets to "Open Source"  
  - add_X-Ubuntu-Gettext-Domain: rebase
  - libunity.patch: rebase, apply before indicator patch (liferea_shell.c)
  - libindicate_increase_version.patch: exclude from libindicate.patch
  - deactivate libindicate.patch, seems partly upstreamed and needs rework
* debian/control: libindicate-dev, libindicate-gtk-dev & libunity-dev
* debian/liferea.indicate & liferea.install: ship indicator desktop file
* debian/rules: enable libindicate

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * @file avahi_publisher.c  cache synchronization using AVAHI
3
 
 * 
4
 
 * Copyright (C) 2007 Lars Lindner <lars.lindner@gmail.com>
5
 
 *
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. 
10
 
 *
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.
15
 
 *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 */
20
 
 
21
 
#include "sync/avahi_publisher.h"
22
 
#include "conf.h"
23
 
 
24
 
#include <glib.h>
25
 
#include <glib/gi18n.h>
26
 
#include <glib-object.h>
27
 
 
28
 
#include <avahi-client/lookup.h>
29
 
#include <avahi-client/publish.h>
30
 
#include <avahi-client/client.h>
31
 
#include <avahi-common/error.h>
32
 
#include <avahi-glib/glib-malloc.h>
33
 
#include <avahi-glib/glib-watch.h>
34
 
 
35
 
static void liferea_avahi_publisher_class_init  (LifereaAvahiPublisherClass *klass);
36
 
static void liferea_avahi_publisher_init        (LifereaAvahiPublisher  *publisher);
37
 
static void liferea_avahi_publisher_finalize    (GObject *object);
38
 
 
39
 
#define LIFEREA_AVAHI_PUBLISHER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIFEREA_AVAHI_PUBLISHER_TYPE, LifereaAvahiPublisherPrivate))
40
 
 
41
 
struct LifereaAvahiPublisherPrivate {
42
 
        AvahiClient     *client;
43
 
        AvahiGLibPoll   *poll;
44
 
        AvahiEntryGroup *entry_group;
45
 
        
46
 
        gchar           *name;
47
 
        guint           port;
48
 
};
49
 
 
50
 
enum {
51
 
        PUBLISHED,
52
 
        NAME_COLLISION,
53
 
        LAST_SIGNAL
54
 
};
55
 
 
56
 
enum {
57
 
        PROP_0
58
 
};
59
 
 
60
 
static guint         signals [LAST_SIGNAL] = { 0, };
61
 
static GObjectClass *parent_class = NULL;
62
 
 
63
 
static gpointer liferea_avahi_publisher = NULL;
64
 
 
65
 
GQuark
66
 
liferea_avahi_publisher_error_quark (void)
67
 
{
68
 
        static GQuark quark = 0;
69
 
        if (!quark)
70
 
                quark = g_quark_from_static_string ("liferea_avahi_publisher_error");
71
 
 
72
 
        return quark;
73
 
}
74
 
 
75
 
static void
76
 
client_cb (AvahiClient         *client,
77
 
           AvahiClientState     state,
78
 
           LifereaAvahiPublisher *publisher)
79
 
{
80
 
        /* FIXME
81
 
         * check to make sure we're in the _RUNNING state before we publish
82
 
         * check for COLLISION state and remove published information
83
 
         */
84
 
 
85
 
        /* Called whenever the client or server state changes */
86
 
 
87
 
        switch (state) {
88
 
        case AVAHI_CLIENT_S_RUNNING:
89
 
 
90
 
                /* The server has startup successfully and registered its host
91
 
                 * name on the network, so it's time to create our services */
92
 
 
93
 
                break;
94
 
 
95
 
        case AVAHI_CLIENT_S_COLLISION:
96
 
 
97
 
                 /* Let's drop our registered services. When the server is back
98
 
                  * in AVAHI_SERVER_RUNNING state we will register them
99
 
                  * again with the new host name. */
100
 
                 if (publisher->priv->entry_group) {
101
 
                         avahi_entry_group_reset (publisher->priv->entry_group);
102
 
                 }
103
 
                 break;
104
 
 
105
 
        case AVAHI_CLIENT_FAILURE:
106
 
 
107
 
                 g_warning ("Client failure: %s\n", avahi_strerror (avahi_client_errno (client)));
108
 
                 break;
109
 
        case AVAHI_CLIENT_CONNECTING:
110
 
        case AVAHI_CLIENT_S_REGISTERING:
111
 
        default:
112
 
                break;
113
 
        }
114
 
}
115
 
 
116
 
static void
117
 
avahi_client_init (LifereaAvahiPublisher *publisher)
118
 
{
119
 
        gint error = 0;
120
 
 
121
 
        avahi_set_allocator (avahi_glib_allocator ());
122
 
 
123
 
        publisher->priv->poll = avahi_glib_poll_new (NULL, G_PRIORITY_DEFAULT);
124
 
 
125
 
        if (! publisher->priv->poll) {
126
 
                g_warning ("Unable to create AvahiGlibPoll object for mDNS");
127
 
        }
128
 
 
129
 
        AvahiClientFlags flags;
130
 
        flags = 0;
131
 
 
132
 
        publisher->priv->client = avahi_client_new (avahi_glib_poll_get (publisher->priv->poll),
133
 
                                                    flags,
134
 
                                                    (AvahiClientCallback)client_cb,
135
 
                                                    publisher,
136
 
                                                    &error);
137
 
}
138
 
 
139
 
static void
140
 
entry_group_cb (AvahiEntryGroup     *group,
141
 
                AvahiEntryGroupState state,
142
 
                LifereaAvahiPublisher *publisher)
143
 
{
144
 
        if (state == AVAHI_ENTRY_GROUP_ESTABLISHED) {
145
 
 
146
 
                g_signal_emit (publisher, signals [PUBLISHED], 0, publisher->priv->name);
147
 
 
148
 
        } else if (state == AVAHI_ENTRY_GROUP_COLLISION) {
149
 
                g_warning ("MDNS name collision");
150
 
 
151
 
                g_signal_emit (publisher, signals [NAME_COLLISION], 0, publisher->priv->name);
152
 
        }
153
 
}
154
 
 
155
 
static gboolean
156
 
create_service (LifereaAvahiPublisher *publisher)
157
 
{
158
 
        int         ret;
159
 
 
160
 
        if (publisher->priv->entry_group == NULL) {
161
 
                publisher->priv->entry_group = avahi_entry_group_new (publisher->priv->client,
162
 
                                                                      (AvahiEntryGroupCallback)entry_group_cb,
163
 
                                                                      publisher);
164
 
        } else {
165
 
                avahi_entry_group_reset (publisher->priv->entry_group);
166
 
        }
167
 
 
168
 
        if (publisher->priv->entry_group == NULL) {
169
 
                g_warning ("Could not create AvahiEntryGroup for publishing");
170
 
                return FALSE;
171
 
        }
172
 
 
173
 
        ret = avahi_entry_group_add_service (publisher->priv->entry_group,
174
 
                                             AVAHI_IF_UNSPEC,
175
 
                                             AVAHI_PROTO_UNSPEC,
176
 
                                             0,
177
 
                                             publisher->priv->name,
178
 
                                             "_liferea._tcp",
179
 
                                             NULL,
180
 
                                             NULL,
181
 
                                             publisher->priv->port,
182
 
                                             "Password=false" /* txt_record */,
183
 
                                             NULL);
184
 
 
185
 
        if (ret < 0) {
186
 
                g_warning ("Could not add service: %s", avahi_strerror (ret));
187
 
                return FALSE;
188
 
        }
189
 
 
190
 
        ret = avahi_entry_group_commit (publisher->priv->entry_group);
191
 
 
192
 
        if (ret < 0) {
193
 
                g_warning ("Could not commit service: %s", avahi_strerror (ret));
194
 
                return FALSE;
195
 
        }
196
 
 
197
 
        return TRUE;
198
 
}
199
 
 
200
 
gboolean
201
 
liferea_avahi_publisher_publish (LifereaAvahiPublisher *publisher,
202
 
                                 gchar                 *name,
203
 
                                 guint                 port)
204
 
{
205
 
        if (publisher->priv->client == NULL) {
206
 
                g_warning ("The avahi MDNS service is not running") ;
207
 
                return FALSE;
208
 
        }
209
 
 
210
 
        publisher->priv->port = port;
211
 
        publisher->priv->name = name;
212
 
        
213
 
        return create_service (publisher);
214
 
}
215
 
 
216
 
GType
217
 
liferea_avahi_publisher_get_type (void) 
218
 
{
219
 
        static GType type = 0;
220
 
 
221
 
        if (G_UNLIKELY (type == 0)) 
222
 
        {
223
 
                static const GTypeInfo our_info = 
224
 
                {
225
 
                        sizeof (LifereaAvahiPublisherClass),
226
 
                        NULL, /* base_init */
227
 
                        NULL, /* base_finalize */
228
 
                        (GClassInitFunc) liferea_avahi_publisher_class_init,
229
 
                        NULL,
230
 
                        NULL, /* class_data */
231
 
                        sizeof (LifereaAvahiPublisher),
232
 
                        0, /* n_preallocs */
233
 
                        (GInstanceInitFunc) liferea_avahi_publisher_init
234
 
                };
235
 
 
236
 
                type = g_type_register_static (G_TYPE_OBJECT,
237
 
                                               "LifereaAvahiPublisher",
238
 
                                               &our_info, 0);
239
 
        }
240
 
 
241
 
        return type;
242
 
}
243
 
 
244
 
static void
245
 
liferea_avahi_publisher_class_init (LifereaAvahiPublisherClass *klass)
246
 
{
247
 
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
248
 
 
249
 
        parent_class = g_type_class_peek_parent (klass);
250
 
 
251
 
        object_class->finalize = liferea_avahi_publisher_finalize;
252
 
 
253
 
        g_type_class_add_private (object_class, sizeof(LifereaAvahiPublisherPrivate));
254
 
}
255
 
 
256
 
static void
257
 
liferea_avahi_publisher_init (LifereaAvahiPublisher *publisher)
258
 
{
259
 
        publisher->priv = LIFEREA_AVAHI_PUBLISHER_GET_PRIVATE (publisher);
260
 
        
261
 
        avahi_client_init (publisher);
262
 
}
263
 
 
264
 
static void
265
 
liferea_avahi_publisher_finalize (GObject *object)
266
 
{
267
 
        LifereaAvahiPublisher *publisher;
268
 
        
269
 
        publisher = LIFEREA_AVAHI_PUBLISHER (object);
270
 
        
271
 
        g_return_if_fail (publisher->priv != NULL);
272
 
        
273
 
        if (publisher->priv->entry_group)
274
 
                avahi_entry_group_free (publisher->priv->entry_group);
275
 
                
276
 
        if (publisher->priv->client)
277
 
                avahi_client_free (publisher->priv->client);
278
 
                
279
 
        if (publisher->priv->poll)
280
 
                avahi_glib_poll_free (publisher->priv->poll);
281
 
                
282
 
        g_free (publisher->priv->name);
283
 
        
284
 
        G_OBJECT_CLASS (parent_class)->finalize (object);
285
 
}
286
 
 
287
 
LifereaAvahiPublisher *
288
 
liferea_avahi_publisher_new (void)
289
 
{
290
 
        gchar   *serviceName;
291
 
        
292
 
        /* check service name preference and set default if necessary */
293
 
        serviceName = conf_get_str_value (SYNC_AVAHI_SERVICE_NAME);
294
 
        if (g_str_equal (serviceName, "")) {
295
 
                g_free (serviceName);
296
 
                serviceName = g_strdup_printf (_("Liferea Sync %s@%s"), g_get_user_name(), g_get_host_name ());
297
 
                conf_set_str_value (SYNC_AVAHI_SERVICE_NAME, serviceName);
298
 
        }
299
 
        g_free (serviceName);
300
 
 
301
 
        if (liferea_avahi_publisher) {
302
 
                g_object_ref (liferea_avahi_publisher);
303
 
        } else {
304
 
                liferea_avahi_publisher = g_object_new (LIFEREA_AVAHI_PUBLISHER_TYPE, NULL);
305
 
                g_object_add_weak_pointer (liferea_avahi_publisher, (gpointer *) &liferea_avahi_publisher);
306
 
        }
307
 
        
308
 
        return liferea_avahi_publisher;
309
 
}