Mercurial > pidgin.yaz
annotate src/protocols/bonjour/bonjour.c @ 11837:fa742ad8068c
[gaim-migrate @ 14128]
Don't pass our active GaimStatus to the login PRPL callback...
It's not used by most PRPLS, and that ones that DO use it
probably shouldn't. Ideally the PRPLs won't store any info
about their own status, message, etc. All that should be in
the core status API, and when it needs some info it should
query the core to get it.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Wed, 26 Oct 2005 05:40:02 +0000 |
parents | 36c2e09c2cf9 |
children | 216a05e0a6f1 |
rev | line source |
---|---|
11477 | 1 /* |
2 * gaim - Bonjour Protocol Plugin | |
3 * | |
4 * Gaim is the legal property of its developers, whose names are too numerous | |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 */ | |
22 #include <glib.h> | |
23 | |
24 #include "internal.h" | |
25 #include "account.h" | |
26 #include "accountopt.h" | |
27 #include "version.h" | |
28 #include "debug.h" | |
29 | |
30 #include "bonjour.h" | |
31 #include "dns_sd.h" | |
32 #include "jabber.h" | |
33 #include "buddy.h" | |
34 | |
11691 | 35 static void |
36 bonjour_removeallfromlocal(GaimConnection *gc) | |
37 { | |
38 GaimAccount *account = gaim_connection_get_account(gc); | |
39 GaimBuddyList *blist; | |
40 GaimBlistNode *gnode, *cnode, *bnode; | |
41 GaimBuddy *buddy; | |
42 | |
43 blist = gaim_get_blist(); | |
44 if (blist == NULL) | |
45 return; | |
46 | |
47 /* Go through and remove all buddies that belong to this account */ | |
48 for (gnode = blist->root; gnode; gnode = gnode->next) | |
49 { | |
50 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
51 continue; | |
52 for (cnode = gnode->child; cnode; cnode = cnode->next) | |
53 { | |
54 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) | |
55 continue; | |
56 for (bnode = cnode->child; bnode; bnode = bnode->next) | |
57 { | |
58 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
59 continue; | |
60 buddy = (GaimBuddy *)bnode; | |
61 if (buddy->account != account) | |
62 continue; | |
63 gaim_prpl_got_user_status(account, buddy->name, "offline", NULL); | |
64 gaim_blist_remove_buddy(buddy); | |
65 } | |
66 } | |
67 } | |
68 } | |
69 | |
11539 | 70 void |
11837 | 71 bonjour_login(GaimAccount *account) |
11477 | 72 { |
73 GaimConnection *gc = gaim_account_get_connection(account); | |
11539 | 74 GaimGroup *bonjour_group = NULL; |
75 BonjourData *bd = NULL; | |
11837 | 76 GaimStatus *status; |
11834 | 77 GaimPresence *presence; |
11539 | 78 |
11477 | 79 gc->flags |= GAIM_CONNECTION_HTML; |
80 gc->proto_data = g_new(BonjourData, 1); | |
81 bd = gc->proto_data; | |
11539 | 82 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
83 /* Start waiting for jabber connections (iChat style) */ |
11477 | 84 bd->jabber_data = g_new(BonjourJabber, 1); |
85 bd->jabber_data->name = gc->account->username; | |
86 bd->jabber_data->port = gaim_account_get_int(account, "port", BONJOUR_DEFAULT_PORT_INT); | |
87 bd->jabber_data->account = account; | |
11539 | 88 |
11477 | 89 if (bonjour_jabber_start(bd->jabber_data) == -1) { |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
90 /* Send a message about the connection error */ |
11834 | 91 gaim_debug_error("bonjour", "Unable to listen to iChat connections"); |
11539 | 92 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
93 /* Free the data */ |
11477 | 94 g_free(bd->jabber_data); |
95 g_free(bd); | |
96 return; | |
97 } | |
11539 | 98 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
99 /* Connect to the mDNS daemon looking for buddies in the LAN */ |
11477 | 100 bd->dns_sd_data = bonjour_dns_sd_new(); |
101 bd->dns_sd_data->name = (sw_string)gaim_account_get_username(account); | |
102 bd->dns_sd_data->txtvers = g_strdup("1"); | |
103 bd->dns_sd_data->version = g_strdup("1"); | |
11496 | 104 bd->dns_sd_data->first = g_strdup(gaim_account_get_string(account, "first", "TODO")); |
105 bd->dns_sd_data->last = g_strdup(gaim_account_get_string(account, "last", "")); | |
11477 | 106 bd->dns_sd_data->port_p2pj = gaim_account_get_int(account, "port", BONJOUR_DEFAULT_PORT_INT); |
107 bd->dns_sd_data->phsh = g_strdup(""); | |
11496 | 108 bd->dns_sd_data->email = g_strdup(gaim_account_get_string(account, "email", "")); |
11477 | 109 bd->dns_sd_data->vc = g_strdup(""); |
110 bd->dns_sd_data->jid = g_strdup(""); | |
111 bd->dns_sd_data->AIM = g_strdup(""); | |
11834 | 112 |
113 status = gaim_account_get_active_status(account); | |
114 presence = gaim_account_get_presence(account); | |
115 if (gaim_presence_is_available(presence)) | |
116 bd->dns_sd_data->status = g_strdup("avail"); | |
117 else if (gaim_presence_is_idle(presence)) | |
118 bd->dns_sd_data->status = g_strdup("away"); | |
119 else | |
120 bd->dns_sd_data->status = g_strdup("dnd"); | |
121 bd->dns_sd_data->msg = g_strdup(gaim_status_get_attr_string(status, "message")); | |
11539 | 122 |
11477 | 123 bd->dns_sd_data->account = account; |
124 bonjour_dns_sd_start(bd->dns_sd_data); | |
11539 | 125 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
126 /* Create a group for bonjour buddies */ |
11477 | 127 bonjour_group = gaim_group_new(BONJOUR_GROUP_NAME); |
128 gaim_blist_add_group(bonjour_group, NULL); | |
11539 | 129 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
130 /* Show the buddy list by telling Gaim we have already connected */ |
11477 | 131 gaim_connection_set_state(gc, GAIM_CONNECTED); |
132 } | |
133 | |
11539 | 134 void |
135 bonjour_close(GaimConnection *connection) | |
11477 | 136 { |
11539 | 137 GaimGroup *bonjour_group = gaim_find_group(BONJOUR_GROUP_NAME); |
138 BonjourData *bd = (BonjourData*)connection->proto_data; | |
139 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
140 /* Stop looking for buddies in the LAN */ |
11477 | 141 if (connection != NULL) { |
142 bonjour_dns_sd_stop(bd->dns_sd_data); | |
143 if (bd != NULL) { | |
144 bonjour_dns_sd_free(bd->dns_sd_data); | |
145 } | |
146 } | |
11539 | 147 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
148 /* Stop waiting for conversations */ |
11477 | 149 bonjour_jabber_stop(bd->jabber_data); |
150 g_free(bd->jabber_data); | |
11539 | 151 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
152 /* Remove all the bonjour buddies */ |
11691 | 153 bonjour_removeallfromlocal(connection); |
11539 | 154 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
155 /* Delete the bonjour group */ |
11477 | 156 gaim_blist_remove_group(bonjour_group); |
11539 | 157 |
11477 | 158 } |
159 | |
11539 | 160 const char * |
161 bonjour_list_icon(GaimAccount *account, GaimBuddy *buddy) | |
11477 | 162 { |
163 return BONJOUR_ICON_NAME; | |
164 } | |
165 | |
11539 | 166 int |
167 bonjour_send_im(GaimConnection *connection, const char *to, const char *msg, GaimConvImFlags flags) | |
11477 | 168 { |
169 if(!to || !msg) | |
170 return 0; | |
11539 | 171 |
11693 | 172 return bonjour_jabber_send_message(((BonjourData*)(connection->proto_data))->jabber_data, to, msg); |
11477 | 173 } |
174 | |
11539 | 175 void |
176 bonjour_set_status(GaimAccount *account, GaimStatus *status) | |
11477 | 177 { |
11496 | 178 GaimConnection *gc; |
179 BonjourData *bd; | |
180 gboolean disconnected; | |
181 GaimStatusType *type; | |
182 int primitive; | |
183 GaimPresence *presence; | |
184 const char *message, *bonjour_status; | |
11477 | 185 |
11496 | 186 disconnected = gaim_account_is_disconnected(account); |
187 type = gaim_status_get_type(status); | |
188 primitive = gaim_status_type_get_primitive(type); | |
189 presence = gaim_account_get_presence(account); | |
190 | |
191 if (!gaim_account_is_connected(account)) | |
192 /* TODO: Does this mean we're connecting? */ | |
193 return; | |
194 | |
195 message = gaim_status_get_attr_string(status, "message"); | |
196 if (message == NULL) | |
197 message = ""; | |
198 | |
199 /* | |
200 * The three possible status for Bonjour are | |
201 * -available ("avail") | |
202 * -idle ("away") | |
203 * -away ("dnd") | |
204 * Each of them can have an optional message. | |
205 */ | |
11835 | 206 if (gaim_presence_is_available(presence)) |
207 bd->dns_sd_data->status = g_strdup("avail"); | |
208 else if (gaim_presence_is_idle(presence)) | |
209 bd->dns_sd_data->status = g_strdup("away"); | |
210 else | |
211 bd->dns_sd_data->status = g_strdup("dnd"); | |
11477 | 212 |
11496 | 213 gc = gaim_account_get_connection(account); |
214 bd = gc->proto_data; | |
215 bonjour_dns_sd_send_status(bd->dns_sd_data, bonjour_status, message); | |
11477 | 216 } |
217 | |
11496 | 218 static GList * |
219 bonjour_status_types(GaimAccount *account) | |
11477 | 220 { |
11496 | 221 GList *status_types = NULL; |
222 GaimStatusType *type; | |
223 | |
224 g_return_val_if_fail(account != NULL, NULL); | |
225 | |
226 type = gaim_status_type_new_full(GAIM_STATUS_OFFLINE, | |
227 BONJOUR_STATUS_ID_OFFLINE, | |
228 _("Offline"), TRUE, TRUE, FALSE); | |
229 status_types = g_list_append(status_types, type); | |
11477 | 230 |
11496 | 231 type = gaim_status_type_new_with_attrs(GAIM_STATUS_AVAILABLE, |
232 BONJOUR_STATUS_ID_AVAILABLE, | |
233 _("Available"), TRUE, TRUE, FALSE, | |
234 "message", _("Message"), | |
235 gaim_value_new(GAIM_TYPE_STRING), NULL); | |
236 status_types = g_list_append(status_types, type); | |
11477 | 237 |
11496 | 238 type = gaim_status_type_new_with_attrs(GAIM_STATUS_AWAY, |
239 BONJOUR_STATUS_ID_AWAY, | |
240 _("Away"), TRUE, TRUE, FALSE, | |
241 "message", _("Message"), | |
242 gaim_value_new(GAIM_TYPE_STRING), NULL); | |
243 status_types = g_list_append(status_types, type); | |
244 | |
245 return status_types; | |
11477 | 246 } |
247 | |
11539 | 248 static void |
249 bonjour_convo_closed(GaimConnection *connection, const char *who) | |
11477 | 250 { |
11539 | 251 GaimBuddy *buddy = gaim_find_buddy(connection->account, who); |
252 | |
11477 | 253 bonjour_jabber_close_conversation(((BonjourData*)(connection->proto_data))->jabber_data, buddy); |
254 } | |
255 | |
11539 | 256 static void |
257 bonjour_list_emblems(GaimBuddy *buddy, | |
11496 | 258 const char **se, const char **sw, |
259 const char **nw,const char **ne) | |
11477 | 260 { |
11496 | 261 GaimPresence *presence; |
262 | |
263 presence = gaim_buddy_get_presence(buddy); | |
264 | |
265 if (!gaim_presence_is_available(presence)) | |
266 *se = "away"; | |
267 } | |
268 | |
11539 | 269 static char * |
270 bonjour_status_text(GaimBuddy *buddy) | |
11496 | 271 { |
272 GaimPresence *presence; | |
273 | |
274 presence = gaim_buddy_get_presence(buddy); | |
275 | |
276 if (gaim_presence_is_available(presence)) | |
277 return g_strdup(""); | |
278 else | |
279 return g_strdup("Away"); | |
11477 | 280 } |
281 | |
11539 | 282 static char * |
283 bonjour_tooltip_text(GaimBuddy *buddy) | |
11477 | 284 { |
11496 | 285 GString *ret; |
286 GaimPresence *presence; | |
287 GaimStatus *status; | |
288 const char *status_description; | |
289 const char *message; | |
290 | |
291 presence = gaim_buddy_get_presence(buddy); | |
292 status = gaim_presence_get_active_status(presence); | |
293 message = gaim_status_get_attr_string(status, "message"); | |
294 | |
295 if (gaim_presence_is_available(presence)) | |
296 status_description = gaim_status_get_name(status); | |
297 else if (gaim_presence_is_idle(presence)) | |
298 status_description = _("Idle"); | |
299 else | |
300 status_description = gaim_status_get_name(status); | |
301 | |
302 ret = g_string_new(""); | |
11519 | 303 g_string_append_printf(ret, _("\n<b>Status:</b> %s"), status_description); |
304 if (message != NULL) | |
305 g_string_append_printf(ret, _("\n<b>Message:</b> %s"), message); | |
11496 | 306 |
307 return g_string_free(ret, FALSE); | |
11477 | 308 } |
309 | |
310 static GaimPlugin *my_protocol = NULL; | |
311 | |
312 static GaimPluginProtocolInfo prpl_info = | |
313 { | |
314 OPT_PROTO_NO_PASSWORD, | |
315 NULL, /* user_splits */ | |
316 NULL, /* protocol_options */ | |
317 {"png", 0, 0, 96, 96, GAIM_ICON_SCALE_DISPLAY}, /* icon_spec */ | |
318 bonjour_list_icon, /* list_icon */ | |
319 bonjour_list_emblems, /* list_emblems */ | |
320 bonjour_status_text, /* status_text */ | |
321 bonjour_tooltip_text, /* tooltip_text */ | |
322 bonjour_status_types, /* status_types */ | |
323 NULL, /* blist_node_menu */ | |
324 NULL, /* chat_info */ | |
325 NULL, /* chat_info_defaults */ | |
326 bonjour_login, /* login */ | |
327 bonjour_close, /* close */ | |
328 bonjour_send_im, /* send_im */ | |
329 NULL, /* set_info */ | |
330 NULL, /* send_typing */ | |
331 NULL, /* get_info */ | |
332 bonjour_set_status, /* set_status */ | |
333 NULL, /* set_idle */ | |
334 NULL, /* change_passwd */ | |
335 NULL, /* add_buddy */ | |
336 NULL, /* add_buddies */ | |
337 NULL, /* remove_buddy */ | |
338 NULL, /* remove_buddies */ | |
339 NULL, /* add_permit */ | |
340 NULL, /* add_deny */ | |
341 NULL, /* rem_permit */ | |
342 NULL, /* rem_deny */ | |
343 NULL, /* set_permit_deny */ | |
344 NULL, /* join_chat */ | |
345 NULL, /* reject_chat */ | |
346 NULL, /* get_chat_name */ | |
347 NULL, /* chat_invite */ | |
348 NULL, /* chat_leave */ | |
349 NULL, /* chat_whisper */ | |
350 NULL, /* chat_send */ | |
351 NULL, /* keepalive */ | |
352 NULL, /* register_user */ | |
353 NULL, /* get_cb_info */ | |
354 NULL, /* get_cb_away */ | |
355 NULL, /* alias_buddy */ | |
356 NULL, /* group_buddy */ | |
357 NULL, /* rename_group */ | |
358 NULL, /* buddy_free */ | |
359 bonjour_convo_closed, /* convo_closed */ | |
360 NULL, /* normalize */ | |
361 NULL, /* set_buddy_icon */ | |
362 NULL, /* remove_group */ | |
363 NULL, /* get_cb_real_name */ | |
364 NULL, /* set_chat_topic */ | |
365 NULL, /* find_blist_chat */ | |
366 NULL, /* roomlist_get_list */ | |
367 NULL, /* roomlist_cancel */ | |
368 NULL, /* roomlist_expand_category */ | |
369 NULL, /* can_receive_file */ | |
370 NULL /* send_file */ | |
371 }; | |
372 | |
373 static GaimPluginInfo info = | |
374 { | |
375 GAIM_PLUGIN_MAGIC, | |
376 GAIM_MAJOR_VERSION, | |
377 GAIM_MINOR_VERSION, | |
378 GAIM_PLUGIN_PROTOCOL, /**< type */ | |
379 NULL, /**< ui_requirement */ | |
380 0, /**< flags */ | |
381 NULL, /**< dependencies */ | |
382 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
383 | |
384 "prpl-bonjour", /**< id */ | |
385 "Bonjour", /**< name */ | |
386 VERSION, /**< version */ | |
387 /** summary */ | |
388 N_("Bonjour Protocol Plugin"), | |
389 /** description */ | |
390 N_("Bonjour Protocol Plugin"), | |
391 NULL, /**< author */ | |
392 GAIM_WEBSITE, /**< homepage */ | |
393 | |
394 NULL, /**< load */ | |
395 NULL, /**< unload */ | |
396 NULL, /**< destroy */ | |
397 | |
398 NULL, /**< ui_info */ | |
399 &prpl_info, /**< extra_info */ | |
400 NULL, /**< prefs_info */ | |
401 NULL | |
402 }; | |
403 | |
404 static void | |
405 init_plugin(GaimPlugin *plugin) | |
406 { | |
407 GaimAccountUserSplit *split; | |
408 GaimAccountOption *option; | |
409 char hostname[255]; | |
410 | |
411 if (gethostname(hostname, 255) != 0) { | |
412 gaim_debug_warning("rendezvous", "Error %d when getting host name. Using \"localhost.\"\n", errno); | |
413 strcpy(hostname, "localhost"); | |
414 } | |
415 | |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
416 /* Creating the user splits */ |
11477 | 417 split = gaim_account_user_split_new(_("Host name"), hostname, '@'); |
418 prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); | |
11539 | 419 |
11829
4669e7461968
[gaim-migrate @ 14120]
Richard Laager <rlaager@wiktel.com>
parents:
11718
diff
changeset
|
420 /* Creating the options for the protocol */ |
11477 | 421 option = gaim_account_option_int_new(_("Port"), "port", 5298); |
422 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
423 | |
424 option = gaim_account_option_string_new(_("First name"), "first", "Gaim"); | |
425 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
426 | |
427 option = gaim_account_option_string_new(_("Last name"), "last", "User"); | |
428 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
429 | |
430 option = gaim_account_option_string_new(_("Email"), "email", ""); | |
431 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
11539 | 432 |
11477 | 433 my_protocol = plugin; |
434 } | |
435 | |
436 GAIM_INIT_PLUGIN(bonjour, init_plugin, info); |