comparison libpurple/protocols/bonjour/mdns_common.c @ 17495:d7b50cac1c7a

This is a patch from Chris Davies to make Bonjour work on Windows using the Apple Bonjour framework. It turns out that the actual DNS-SD library is (3 clause) BSD licensed, so we can use it. There are a few changes by me, mainly to fix the howl implementation. Fixes #1117 . There appear to be a few bugs, but I believe that they were also present previously. I'm hoping to do some more tweaking before the next release. The howl implementation will eventually be supersceded by a native avahi implementation, so I opted for a somewhat dirty hack to enable it instead of doing something with config.h.
author Daniel Atallah <daniel.atallah@gmail.com>
date Tue, 05 Jun 2007 03:38:22 +0000
parents
children c96b085ddf5c
comparison
equal deleted inserted replaced
17488:7e856734b712 17495:d7b50cac1c7a
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Library General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16
17 #include <string.h>
18
19 #include "config.h"
20 #include "mdns_common.h"
21 #include "bonjour.h"
22 #include "buddy.h"
23 #include "debug.h"
24
25
26 /**
27 * Allocate space for the dns-sd data.
28 */
29 BonjourDnsSd *
30 bonjour_dns_sd_new()
31 {
32 BonjourDnsSd *data = g_new0(BonjourDnsSd, 1);
33
34 return data;
35 }
36
37 /**
38 * Deallocate the space of the dns-sd data.
39 */
40 void
41 bonjour_dns_sd_free(BonjourDnsSd *data)
42 {
43 g_free(data->first);
44 g_free(data->last);
45 g_free(data->email);
46 g_free(data);
47 }
48
49 /**
50 * Send a new dns-sd packet updating our status.
51 */
52 void
53 bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message)
54 {
55 g_free(data->status);
56 g_free(data->msg);
57
58 data->status = g_strdup(status);
59 data->msg = g_strdup(status_message);
60
61 /* Update our text record with the new status */
62 _mdns_publish(data, PUBLISH_UPDATE); /* <--We must control the errors */
63 }
64
65 /**
66 * Advertise our presence within the dns-sd daemon and start browsing
67 * for other bonjour peers.
68 */
69 gboolean
70 bonjour_dns_sd_start(BonjourDnsSd *data)
71 {
72 PurpleAccount *account;
73 PurpleConnection *gc;
74 gint dns_sd_socket;
75 gpointer opaque_data;
76
77 #ifdef USE_BONJOUR_HOWL
78 sw_discovery_oid session_id;
79 #endif
80
81 account = data->account;
82 gc = purple_account_get_connection(account);
83
84 /* Initialize the dns-sd data and session */
85
86 #ifndef USE_BONJOUR_APPLE
87 if (sw_discovery_init(&data->session) != SW_OKAY)
88 {
89 purple_debug_error("bonjour", "Unable to initialize an mDNS session.\n");
90
91 /* In Avahi, sw_discovery_init frees data->session but doesn't clear it */
92 data->session = NULL;
93
94 return FALSE;
95 }
96 #endif
97
98 /* Publish our bonjour IM client at the mDNS daemon */
99
100 if (0 != _mdns_publish(data, PUBLISH_START))
101 {
102 return FALSE;
103 }
104
105 /* Advise the daemon that we are waiting for connections */
106
107 #ifdef USE_BONJOUR_APPLE
108 printf("account pointer here is %x\n,", account);
109 if (DNSServiceBrowse(&data->browser, 0, 0, ICHAT_SERVICE, NULL, _mdns_service_browse_callback, account)
110 != kDNSServiceErr_NoError)
111 #else /* USE_BONJOUR_HOWL */
112 if (sw_discovery_browse(data->session, 0, ICHAT_SERVICE, NULL, _browser_reply,
113 account, &session_id) != SW_OKAY)
114 #endif
115 {
116 purple_debug_error("bonjour", "Unable to get service.");
117 return FALSE;
118 }
119
120 /* Get the socket that communicates with the mDNS daemon and bind it to a */
121 /* callback that will handle the dns_sd packets */
122
123 #ifdef USE_BONJOUR_APPLE
124 dns_sd_socket = DNSServiceRefSockFD(data->browser);
125 opaque_data = data->browser;
126 #else /* USE_BONJOUR_HOWL */
127 dns_sd_socket = sw_discovery_socket(data->session);
128 opaque_data = data->session;
129 #endif
130
131 gc->inpa = purple_input_add(dns_sd_socket, PURPLE_INPUT_READ,
132 _mdns_handle_event, opaque_data);
133
134 return TRUE;
135 }
136
137 /**
138 * Unregister the "_presence._tcp" service at the mDNS daemon.
139 */
140
141 void
142 bonjour_dns_sd_stop(BonjourDnsSd *data)
143 {
144 PurpleAccount *account;
145 PurpleConnection *gc;
146
147 #ifdef USE_BONJOUR_APPLE
148 if (NULL == data->advertisement || NULL == data->browser)
149 #else /* USE_BONJOUR_HOWL */
150 if (data->session == NULL)
151 #endif
152 return;
153
154 #ifdef USE_BONJOUR_HOWL
155 sw_discovery_cancel(data->session, data->session_id);
156 #endif
157
158 account = data->account;
159 gc = purple_account_get_connection(account);
160 purple_input_remove(gc->inpa);
161
162 #ifdef USE_BONJOUR_APPLE
163 /* hack: for win32, we need to stop listening to the advertisement pipe too */
164 purple_input_remove(data->advertisement_fd);
165
166 DNSServiceRefDeallocate(data->advertisement);
167 DNSServiceRefDeallocate(data->browser);
168 data->advertisement = NULL;
169 data->browser = NULL;
170 #else /* USE_BONJOUR_HOWL */
171 g_free(data->session);
172 data->session = NULL;
173 #endif
174 }