]> git.meshlink.io Git - catta/blob - avahi-daemon/main.c
* add support for static service definitions for the daemon using XML fragments
[catta] / avahi-daemon / main.c
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5  
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10  
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <avahi-core/core.h>
27
28 #define DBUS_API_SUBJECT_TO_CHANGE
29 #include <dbus/dbus.h>
30 #include <dbus/dbus-glib-lowlevel.h>
31
32 #include "main.h"
33 #include "simple-protocol.h"
34 #include "static-services.h"
35
36 #define DBUS_SERVICE_AVAHI "org.freedesktop.Avahi"
37
38 AvahiServer *avahi_server = NULL;
39
40 static DBusHandlerResult
41 do_register (DBusConnection *conn, DBusMessage *message)
42 {
43     DBusError error;
44     char *s;
45
46     dbus_error_init (&error);
47
48     dbus_message_get_args (message, &error,
49                            DBUS_TYPE_STRING, &s,
50                            DBUS_TYPE_INVALID);
51
52     if (dbus_error_is_set (&error))
53     {
54         g_warning ("Error parsing register attempt");
55         dbus_error_free (&error);
56
57         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
58     }
59
60     g_message ("Register received from: %s", s);
61
62     return DBUS_HANDLER_RESULT_HANDLED;
63 }
64
65 static DBusHandlerResult
66 signal_filter (DBusConnection *conn, DBusMessage *message, void *user_data)
67 {
68     GMainLoop *loop = user_data;
69     DBusError error;
70
71     dbus_error_init (&error);
72
73     g_message ("dbus: interface=%s, path=%s, member=%s",
74                dbus_message_get_interface (message),
75                dbus_message_get_path (message),
76                dbus_message_get_member (message));
77
78     if (dbus_message_is_signal (message,
79                                 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
80                                 "Disconnected"))
81     {
82         /* No, we shouldn't quit, but until we get somewhere
83          * usefull such that we can restore our state, we will */
84         g_warning ("Disconnnected from d-bus");
85
86         g_main_loop_quit (loop);
87         return DBUS_HANDLER_RESULT_HANDLED;
88     } else if (dbus_message_is_method_call (message, DBUS_SERVICE_AVAHI,
89                                             "Register"))
90     {
91         return do_register (conn, message);
92     } else if (dbus_message_is_signal (message,
93                                        DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
94                                        "ServiceAcquired"))
95     {
96         char *name;
97
98         dbus_message_get_args (message, &error,
99                                DBUS_TYPE_STRING, &name,
100                                DBUS_TYPE_INVALID);
101
102         if (dbus_error_is_set (&error))
103         {
104             g_warning ("Error parsing NameAcquired message");
105             dbus_error_free (&error);
106
107             return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
108         }
109
110         g_message ("dbus: ServiceAcquired (%s)", name);
111
112         return DBUS_HANDLER_RESULT_HANDLED;
113     }
114
115     g_message ("dbus: missed event");
116
117     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
118 }
119
120 static void server_callback(AvahiServer *s, AvahiServerState state, gpointer userdata) {
121     g_assert(s);
122
123     if (state == AVAHI_SERVER_RUNNING) {
124         g_message("Server startup complete.  Host name is <%s>", avahi_server_get_host_name_fqdn(s));
125         static_service_add_to_server();
126     } else if (state == AVAHI_SERVER_COLLISION) {
127         gchar *n;
128
129         static_service_remove_from_server();
130         
131         n = avahi_alternative_host_name(avahi_server_get_host_name(s));
132         g_message("Host name conflict, retrying with <%s>", n);
133         avahi_server_set_host_name(s, n);
134         g_free(n);
135     }
136 }
137
138 int main(int argc, char *argv[]) {
139     GMainLoop *loop = NULL;
140     DBusConnection *bus = NULL;
141     DBusError error;
142     gint r = 255;
143     AvahiServerConfig config;
144
145     avahi_server_config_init(&config);
146
147     loop = g_main_loop_new(NULL, FALSE);
148
149     dbus_error_init (&error);
150
151     bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
152
153     if (bus == NULL)
154     {
155         g_warning ("dbus_bus_get(): %s", error.message);
156         dbus_error_free (&error);
157
158         goto finish;
159     }
160
161     dbus_connection_setup_with_g_main (bus, NULL);
162     dbus_connection_set_exit_on_disconnect (bus, FALSE);
163
164     dbus_bus_acquire_service (bus, DBUS_SERVICE_AVAHI, 0, &error);
165
166     if (dbus_error_is_set (&error))
167     {
168         g_warning ("dbus_error_is_set (): %s", error.message);
169         dbus_error_free (&error);
170
171         goto finish;
172     }
173
174     dbus_connection_add_filter (bus, signal_filter, loop, NULL);
175     dbus_bus_add_match (bus,
176                         "type='method_call',interface='org.freedesktop.Avahi'",
177                         &error);
178
179     if (dbus_error_is_set (&error))
180     {
181         g_warning ("dbus_bus_add_match (): %s", error.message);
182         dbus_error_free (&error);
183
184         goto finish;
185     }
186
187     if (simple_protocol_setup(NULL) < 0)
188         goto finish;
189
190     if (!(avahi_server = avahi_server_new(NULL, &config, server_callback, NULL)))
191         goto finish;
192
193     static_service_load();
194
195     g_main_loop_run(loop);
196
197     r = 0;
198     
199 finish:
200
201     static_service_remove_from_server();
202     static_service_free_all();
203     
204     simple_protocol_shutdown();
205
206     if (bus) {
207         dbus_connection_disconnect(bus);
208         dbus_connection_unref(bus);
209     }
210
211     if (avahi_server)
212         avahi_server_free(avahi_server);
213     
214     if (loop)
215         g_main_loop_unref(loop);
216
217     avahi_server_config_free(&config);
218
219     return r;
220 }