Fix crashes when filenames end up being NULL in some prpls.
[pidgin-git.git] / libpurple / protocols / bonjour / bonjour.c
blob8456ffb7e34e5433e4e3e86a282ce491e6498d56
1 /*
2 * purple - Bonjour Protocol Plugin
4 * Purple 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.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #include <glib.h>
23 #ifndef _WIN32
24 #include <pwd.h>
25 #else
26 #define UNICODE
27 #include <winsock2.h>
28 #include <windows.h>
29 #include <lm.h>
30 #include "dns_sd_proxy.h"
31 #endif
33 #include "internal.h"
35 #include "account.h"
36 #include "accountopt.h"
37 #include "debug.h"
38 #include "util.h"
39 #include "version.h"
41 #include "bonjour.h"
42 #include "mdns_common.h"
43 #include "jabber.h"
44 #include "buddy.h"
45 #include "bonjour_ft.h"
47 static char *default_firstname;
48 static char *default_lastname;
49 static char *default_hostname;
51 static void
52 bonjour_removeallfromlocal(PurpleConnection *conn, PurpleGroup *bonjour_group)
54 PurpleAccount *account = purple_connection_get_account(conn);
55 PurpleBlistNode *cnode, *cnodenext, *bnode, *bnodenext;
56 PurpleBuddy *buddy;
58 if (bonjour_group == NULL)
59 return;
61 /* Go through and remove all buddies that belong to this account */
62 for (cnode = purple_blist_node_get_first_child((PurpleBlistNode *) bonjour_group); cnode; cnode = cnodenext) {
63 cnodenext = purple_blist_node_get_sibling_next(cnode);
64 if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode))
65 continue;
66 for (bnode = purple_blist_node_get_first_child(cnode); bnode; bnode = bnodenext) {
67 bnodenext = purple_blist_node_get_sibling_next(bnode);
68 if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
69 continue;
70 buddy = (PurpleBuddy *) bnode;
71 if (purple_buddy_get_account(buddy) != account)
72 continue;
73 purple_prpl_got_user_status(account, purple_buddy_get_name(buddy), "offline", NULL);
74 purple_account_remove_buddy(account, buddy, NULL);
75 purple_blist_remove_buddy(buddy);
81 static void
82 bonjour_login(PurpleAccount *account)
84 PurpleConnection *gc = purple_account_get_connection(account);
85 BonjourData *bd;
86 PurpleStatus *status;
87 PurplePresence *presence;
89 #ifdef _WIN32
90 if (!dns_sd_available()) {
91 purple_connection_error_reason(gc,
92 PURPLE_CONNECTION_ERROR_OTHER_ERROR,
93 _("The Apple Bonjour For Windows toolkit wasn't found, see the FAQ at: "
94 "http://d.pidgin.im/BonjourWindows"
95 " for more information."));
96 return;
98 #endif
100 gc->flags |= PURPLE_CONNECTION_HTML;
101 gc->proto_data = bd = g_new0(BonjourData, 1);
103 /* Start waiting for jabber connections (iChat style) */
104 bd->jabber_data = g_new0(BonjourJabber, 1);
105 bd->jabber_data->port = purple_account_get_int(account, "port", BONJOUR_DEFAULT_PORT);
106 bd->jabber_data->account = account;
108 if (bonjour_jabber_start(bd->jabber_data) == -1) {
109 /* Send a message about the connection error */
110 purple_connection_error_reason (gc,
111 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
112 _("Unable to listen for incoming IM connections\n"));
113 return;
116 /* Connect to the mDNS daemon looking for buddies in the LAN */
117 bd->dns_sd_data = bonjour_dns_sd_new();
118 bd->dns_sd_data->first = g_strdup(purple_account_get_string(account, "first", default_firstname));
119 bd->dns_sd_data->last = g_strdup(purple_account_get_string(account, "last", default_lastname));
120 bd->dns_sd_data->port_p2pj = bd->jabber_data->port;
121 /* Not engaged in AV conference */
122 bd->dns_sd_data->vc = g_strdup("!");
124 status = purple_account_get_active_status(account);
125 presence = purple_account_get_presence(account);
126 if (purple_presence_is_available(presence))
127 bd->dns_sd_data->status = g_strdup("avail");
128 else if (purple_presence_is_idle(presence))
129 bd->dns_sd_data->status = g_strdup("away");
130 else
131 bd->dns_sd_data->status = g_strdup("dnd");
132 bd->dns_sd_data->msg = g_strdup(purple_status_get_attr_string(status, "message"));
134 bd->dns_sd_data->account = account;
135 if (!bonjour_dns_sd_start(bd->dns_sd_data))
137 purple_connection_error_reason (gc,
138 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
139 _("Unable to establish connection with the local mDNS server. Is it running?"));
140 return;
143 bonjour_dns_sd_update_buddy_icon(bd->dns_sd_data);
145 /* Show the buddy list by telling Purple we have already connected */
146 purple_connection_set_state(gc, PURPLE_CONNECTED);
149 static void
150 bonjour_close(PurpleConnection *connection)
152 PurpleGroup *bonjour_group;
153 BonjourData *bd = connection->proto_data;
155 bonjour_group = purple_find_group(BONJOUR_GROUP_NAME);
157 /* Remove all the bonjour buddies */
158 bonjour_removeallfromlocal(connection, bonjour_group);
160 /* Stop looking for buddies in the LAN */
161 if (bd != NULL && bd->dns_sd_data != NULL)
163 bonjour_dns_sd_stop(bd->dns_sd_data);
164 bonjour_dns_sd_free(bd->dns_sd_data);
167 if (bd != NULL && bd->jabber_data != NULL)
169 /* Stop waiting for conversations */
170 bonjour_jabber_stop(bd->jabber_data);
171 g_free(bd->jabber_data);
174 /* Delete the bonjour group */
175 if (bonjour_group != NULL)
176 purple_blist_remove_group(bonjour_group);
178 /* Cancel any file transfers */
179 while (bd != NULL && bd->xfer_lists) {
180 purple_xfer_cancel_local(bd->xfer_lists->data);
183 g_free(bd);
184 connection->proto_data = NULL;
187 static const char *
188 bonjour_list_icon(PurpleAccount *account, PurpleBuddy *buddy)
190 return BONJOUR_ICON_NAME;
193 static int
194 bonjour_send_im(PurpleConnection *connection, const char *to, const char *msg, PurpleMessageFlags flags)
196 if(!to || !msg)
197 return 0;
199 return bonjour_jabber_send_message(((BonjourData*)(connection->proto_data))->jabber_data, to, msg);
202 static void
203 bonjour_set_status(PurpleAccount *account, PurpleStatus *status)
205 PurpleConnection *gc;
206 BonjourData *bd;
207 gboolean disconnected;
208 PurpleStatusType *type;
209 int primitive;
210 PurplePresence *presence;
211 const char *message, *bonjour_status;
212 gchar *stripped;
214 gc = purple_account_get_connection(account);
215 bd = gc->proto_data;
216 disconnected = purple_account_is_disconnected(account);
217 type = purple_status_get_type(status);
218 primitive = purple_status_type_get_primitive(type);
219 presence = purple_account_get_presence(account);
221 message = purple_status_get_attr_string(status, "message");
222 if (message == NULL)
223 message = "";
224 stripped = purple_markup_strip_html(message);
227 * The three possible status for Bonjour are
228 * -available ("avail")
229 * -idle ("away")
230 * -away ("dnd")
231 * Each of them can have an optional message.
233 if (purple_presence_is_available(presence))
234 bonjour_status = "avail";
235 else if (purple_presence_is_idle(presence))
236 bonjour_status = "away";
237 else
238 bonjour_status = "dnd";
240 bonjour_dns_sd_send_status(bd->dns_sd_data, bonjour_status, stripped);
241 g_free(stripped);
245 * The add_buddy callback removes the buddy from the local list.
246 * Bonjour manages buddies for you, and adding someone locally by
247 * hand is stupid. Perhaps we should change libpurple not to allow adding
248 * if there is no add_buddy callback.
250 static void
251 bonjour_fake_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group) {
252 purple_debug_error("bonjour", "Buddy '%s' manually added; removing. "
253 "Bonjour buddies must be discovered and not manually added.\n",
254 purple_buddy_get_name(buddy));
256 /* I suppose we could alert the user here, but it seems unnecessary. */
258 /* If this causes problems, it can be moved to an idle callback */
259 purple_blist_remove_buddy(buddy);
263 static void bonjour_remove_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group) {
264 if (buddy->proto_data) {
265 bonjour_buddy_delete(buddy->proto_data);
266 buddy->proto_data = NULL;
270 static GList *
271 bonjour_status_types(PurpleAccount *account)
273 GList *status_types = NULL;
274 PurpleStatusType *type;
276 g_return_val_if_fail(account != NULL, NULL);
278 type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
279 BONJOUR_STATUS_ID_AVAILABLE,
280 NULL, TRUE, TRUE, FALSE,
281 "message", _("Message"),
282 purple_value_new(PURPLE_TYPE_STRING), NULL);
283 status_types = g_list_append(status_types, type);
285 type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
286 BONJOUR_STATUS_ID_AWAY,
287 NULL, TRUE, TRUE, FALSE,
288 "message", _("Message"),
289 purple_value_new(PURPLE_TYPE_STRING), NULL);
290 status_types = g_list_append(status_types, type);
292 type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE,
293 BONJOUR_STATUS_ID_OFFLINE,
294 NULL, TRUE, TRUE, FALSE);
295 status_types = g_list_append(status_types, type);
297 return status_types;
300 static void
301 bonjour_convo_closed(PurpleConnection *connection, const char *who)
303 PurpleBuddy *buddy = purple_find_buddy(connection->account, who);
304 BonjourBuddy *bb;
306 if (buddy == NULL || buddy->proto_data == NULL)
309 * This buddy is not in our buddy list, and therefore does not really
310 * exist, so we won't have any data about them.
312 return;
315 bb = buddy->proto_data;
316 bonjour_jabber_close_conversation(bb->conversation);
317 bb->conversation = NULL;
320 static
321 void bonjour_set_buddy_icon(PurpleConnection *conn, PurpleStoredImage *img)
323 BonjourData *bd = conn->proto_data;
324 bonjour_dns_sd_update_buddy_icon(bd->dns_sd_data);
328 static char *
329 bonjour_status_text(PurpleBuddy *buddy)
331 const PurplePresence *presence;
332 const PurpleStatus *status;
333 const char *message;
334 gchar *ret = NULL;
336 presence = purple_buddy_get_presence(buddy);
337 status = purple_presence_get_active_status(presence);
339 message = purple_status_get_attr_string(status, "message");
341 if (message != NULL) {
342 ret = g_markup_escape_text(message, -1);
343 purple_util_chrreplace(ret, '\n', ' ');
346 return ret;
349 static void
350 bonjour_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full)
352 PurplePresence *presence;
353 PurpleStatus *status;
354 BonjourBuddy *bb = buddy->proto_data;
355 const char *status_description;
356 const char *message;
358 presence = purple_buddy_get_presence(buddy);
359 status = purple_presence_get_active_status(presence);
360 message = purple_status_get_attr_string(status, "message");
362 if (purple_presence_is_available(presence))
363 status_description = purple_status_get_name(status);
364 else if (purple_presence_is_idle(presence))
365 status_description = _("Idle");
366 else
367 status_description = purple_status_get_name(status);
369 purple_notify_user_info_add_pair(user_info, _("Status"), status_description);
370 if (message != NULL)
371 purple_notify_user_info_add_pair(user_info, _("Message"), message);
373 if (bb == NULL) {
374 purple_debug_error("bonjour", "Got tooltip request for a buddy without protocol data.\n");
375 return;
378 /* Only show first/last name if there is a nickname set (to avoid duplication) */
379 if (bb->nick != NULL && *bb->nick != '\0') {
380 if (bb->first != NULL && *bb->first != '\0')
381 purple_notify_user_info_add_pair(user_info, _("First name"), bb->first);
382 if (bb->last != NULL && *bb->last != '\0')
383 purple_notify_user_info_add_pair(user_info, _("Last name"), bb->last);
386 if (bb->email != NULL && *bb->email != '\0')
387 purple_notify_user_info_add_pair(user_info, _("Email"), bb->email);
389 if (bb->AIM != NULL && *bb->AIM != '\0')
390 purple_notify_user_info_add_pair(user_info, _("AIM Account"), bb->AIM);
392 if (bb->jid != NULL && *bb->jid != '\0')
393 purple_notify_user_info_add_pair(user_info, _("XMPP Account"), bb->jid);
396 static void
397 bonjour_group_buddy(PurpleConnection *connection, const char *who, const char *old_group, const char *new_group)
399 PurpleBlistNodeFlags oldflags;
400 PurpleBuddy *buddy = purple_find_buddy(connection->account, who);
402 if (buddy == NULL)
403 return;
405 oldflags = purple_blist_node_get_flags((PurpleBlistNode *)buddy);
407 /* If we're moving them out of the bonjour group, make them persistent */
408 if (strcmp(new_group, BONJOUR_GROUP_NAME) == 0)
409 purple_blist_node_set_flags((PurpleBlistNode *)buddy, oldflags | PURPLE_BLIST_NODE_FLAG_NO_SAVE);
410 else
411 purple_blist_node_set_flags((PurpleBlistNode *)buddy, oldflags ^ PURPLE_BLIST_NODE_FLAG_NO_SAVE);
415 static gboolean
416 bonjour_can_receive_file(PurpleConnection *connection, const char *who)
418 PurpleBuddy *buddy = purple_find_buddy(connection->account, who);
420 return (buddy != NULL && buddy->proto_data != NULL);
424 static gboolean
425 plugin_unload(PurplePlugin *plugin)
427 /* These shouldn't happen here because they are allocated in _init() */
429 g_free(default_firstname);
430 g_free(default_lastname);
431 g_free(default_hostname);
433 return TRUE;
436 static PurplePlugin *my_protocol = NULL;
438 static PurplePluginProtocolInfo prpl_info =
440 OPT_PROTO_NO_PASSWORD,
441 NULL, /* user_splits */
442 NULL, /* protocol_options */
443 {"png,gif,jpeg", 0, 0, 96, 96, 65535, PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
444 bonjour_list_icon, /* list_icon */
445 NULL, /* list_emblem */
446 bonjour_status_text, /* status_text */
447 bonjour_tooltip_text, /* tooltip_text */
448 bonjour_status_types, /* status_types */
449 NULL, /* blist_node_menu */
450 NULL, /* chat_info */
451 NULL, /* chat_info_defaults */
452 bonjour_login, /* login */
453 bonjour_close, /* close */
454 bonjour_send_im, /* send_im */
455 NULL, /* set_info */
456 NULL, /* send_typing */
457 NULL, /* get_info */
458 bonjour_set_status, /* set_status */
459 NULL, /* set_idle */
460 NULL, /* change_passwd */
461 bonjour_fake_add_buddy, /* add_buddy */
462 NULL, /* add_buddies */
463 bonjour_remove_buddy, /* remove_buddy */
464 NULL, /* remove_buddies */
465 NULL, /* add_permit */
466 NULL, /* add_deny */
467 NULL, /* rem_permit */
468 NULL, /* rem_deny */
469 NULL, /* set_permit_deny */
470 NULL, /* join_chat */
471 NULL, /* reject_chat */
472 NULL, /* get_chat_name */
473 NULL, /* chat_invite */
474 NULL, /* chat_leave */
475 NULL, /* chat_whisper */
476 NULL, /* chat_send */
477 NULL, /* keepalive */
478 NULL, /* register_user */
479 NULL, /* get_cb_info */
480 NULL, /* get_cb_away */
481 NULL, /* alias_buddy */
482 bonjour_group_buddy, /* group_buddy */
483 NULL, /* rename_group */
484 NULL, /* buddy_free */
485 bonjour_convo_closed, /* convo_closed */
486 NULL, /* normalize */
487 bonjour_set_buddy_icon, /* set_buddy_icon */
488 NULL, /* remove_group */
489 NULL, /* get_cb_real_name */
490 NULL, /* set_chat_topic */
491 NULL, /* find_blist_chat */
492 NULL, /* roomlist_get_list */
493 NULL, /* roomlist_cancel */
494 NULL, /* roomlist_expand_category */
495 bonjour_can_receive_file, /* can_receive_file */
496 bonjour_send_file, /* send_file */
497 bonjour_new_xfer, /* new_xfer */
498 NULL, /* offline_message */
499 NULL, /* whiteboard_prpl_ops */
500 NULL, /* send_raw */
501 NULL, /* roomlist_room_serialize */
503 /* padding */
504 NULL,
505 NULL,
506 NULL,
507 sizeof(PurplePluginProtocolInfo), /* struct_size */
508 NULL
511 static PurplePluginInfo info =
513 PURPLE_PLUGIN_MAGIC,
514 PURPLE_MAJOR_VERSION,
515 PURPLE_MINOR_VERSION,
516 PURPLE_PLUGIN_PROTOCOL, /**< type */
517 NULL, /**< ui_requirement */
518 0, /**< flags */
519 NULL, /**< dependencies */
520 PURPLE_PRIORITY_DEFAULT, /**< priority */
522 "prpl-bonjour", /**< id */
523 "Bonjour", /**< name */
524 DISPLAY_VERSION, /**< version */
525 /** summary */
526 N_("Bonjour Protocol Plugin"),
527 /** description */
528 N_("Bonjour Protocol Plugin"),
529 NULL, /**< author */
530 PURPLE_WEBSITE, /**< homepage */
532 NULL, /**< load */
533 plugin_unload, /**< unload */
534 NULL, /**< destroy */
536 NULL, /**< ui_info */
537 &prpl_info, /**< extra_info */
538 NULL, /**< prefs_info */
539 NULL,
541 /* padding */
542 NULL,
543 NULL,
544 NULL,
545 NULL
548 #ifdef WIN32
549 static gboolean _set_default_name_cb(gpointer data) {
550 gchar *fullname = data;
551 const char *splitpoint;
552 GList *tmp = prpl_info.protocol_options;
553 PurpleAccountOption *option;
555 if (!fullname) {
556 purple_debug_info("bonjour", "Unable to look up First and Last name or Username from system; using defaults.\n");
557 return FALSE;
560 g_free(default_firstname);
561 g_free(default_lastname);
563 /* Split the real name into a first and last name */
564 splitpoint = strchr(fullname, ' ');
565 if (splitpoint != NULL) {
566 default_firstname = g_strndup(fullname, splitpoint - fullname);
567 default_lastname = g_strdup(&splitpoint[1]);
568 } else {
569 default_firstname = g_strdup(fullname);
570 default_lastname = g_strdup("");
572 g_free(fullname);
575 for(; tmp != NULL; tmp = tmp->next) {
576 option = tmp->data;
577 if (strcmp("first", purple_account_option_get_setting(option)) == 0)
578 purple_account_option_set_default_string(option, default_firstname);
579 else if (strcmp("last", purple_account_option_get_setting(option)) == 0)
580 purple_account_option_set_default_string(option, default_lastname);
583 return FALSE;
586 static gpointer _win32_name_lookup_thread(gpointer data) {
587 gchar *fullname = NULL;
588 wchar_t username[UNLEN + 1];
589 DWORD dwLenUsername = UNLEN + 1;
591 GetUserNameW((LPWSTR) &username, &dwLenUsername);
593 if (username != NULL && *username != '\0') {
594 LPBYTE servername = NULL;
595 LPBYTE info = NULL;
597 NetGetDCName(NULL, NULL, &servername);
599 /* purple_debug_info("bonjour", "Looking up the full name from the %s.\n", (servername ? "domain controller" : "local machine")); */
601 if (NetUserGetInfo((LPCWSTR) servername, username, 10, &info) == NERR_Success
602 && info != NULL && ((LPUSER_INFO_10) info)->usri10_full_name != NULL
603 && *(((LPUSER_INFO_10) info)->usri10_full_name) != '\0') {
604 fullname = g_utf16_to_utf8(
605 ((LPUSER_INFO_10) info)->usri10_full_name,
606 -1, NULL, NULL, NULL);
608 /* Fall back to the local machine if we didn't get the full name from the domain controller */
609 else if (servername != NULL) {
610 /* purple_debug_info("bonjour", "Looking up the full name from the local machine"); */
612 if (info != NULL) NetApiBufferFree(info);
613 info = NULL;
615 if (NetUserGetInfo(NULL, username, 10, &info) == NERR_Success
616 && info != NULL && ((LPUSER_INFO_10) info)->usri10_full_name != NULL
617 && *(((LPUSER_INFO_10) info)->usri10_full_name) != '\0') {
618 fullname = g_utf16_to_utf8(
619 ((LPUSER_INFO_10) info)->usri10_full_name,
620 -1, NULL, NULL, NULL);
624 if (info != NULL) NetApiBufferFree(info);
625 if (servername != NULL) NetApiBufferFree(servername);
627 if (!fullname)
628 fullname = g_utf16_to_utf8(username, -1, NULL, NULL, NULL);
631 purple_timeout_add(0, _set_default_name_cb, fullname);
633 return NULL;
635 #endif
637 static void
638 initialize_default_account_values(void)
640 #ifndef _WIN32
641 struct passwd *info;
642 #endif
643 const char *fullname = NULL, *splitpoint, *tmp;
644 gchar *conv = NULL;
646 #ifndef _WIN32
647 /* Try to figure out the user's real name */
648 info = getpwuid(getuid());
649 if ((info != NULL) && (info->pw_gecos != NULL) && (info->pw_gecos[0] != '\0'))
650 fullname = info->pw_gecos;
651 else if ((info != NULL) && (info->pw_name != NULL) && (info->pw_name[0] != '\0'))
652 fullname = info->pw_name;
653 else if (((fullname = getlogin()) != NULL) && (fullname[0] == '\0'))
654 fullname = NULL;
655 #else
656 /* The Win32 username lookup functions are synchronous so we do it in a thread */
657 g_thread_create(_win32_name_lookup_thread, NULL, FALSE, NULL);
658 #endif
660 /* Make sure fullname is valid UTF-8. If not, try to convert it. */
661 if (fullname != NULL && !g_utf8_validate(fullname, -1, NULL)) {
662 fullname = conv = g_locale_to_utf8(fullname, -1, NULL, NULL, NULL);
663 if (conv == NULL || *conv == '\0')
664 fullname = NULL;
667 if (fullname == NULL)
668 fullname = _("Purple Person");
670 /* Split the real name into a first and last name */
671 splitpoint = strchr(fullname, ' ');
672 if (splitpoint != NULL) {
673 default_firstname = g_strndup(fullname, splitpoint - fullname);
674 tmp = &splitpoint[1];
676 /* The last name may be followed by a comma and additional data.
677 * Only use the last name itself.
679 splitpoint = strchr(tmp, ',');
680 if (splitpoint != NULL)
681 default_lastname = g_strndup(tmp, splitpoint - tmp);
682 else
683 default_lastname = g_strdup(tmp);
684 } else {
685 default_firstname = g_strdup(fullname);
686 default_lastname = g_strdup("");
689 g_free(conv);
691 /* Try to figure out a good host name to use */
692 /* TODO: Avoid 'localhost,' if possible */
693 default_hostname = g_strdup(purple_get_host_name());
696 static void
697 init_plugin(PurplePlugin *plugin)
699 PurpleAccountUserSplit *split;
700 PurpleAccountOption *option;
702 initialize_default_account_values();
704 /* Creating the user splits */
705 split = purple_account_user_split_new(_("Hostname"), default_hostname, '@');
706 prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
708 /* Creating the options for the protocol */
709 option = purple_account_option_int_new(_("Local Port"), "port", BONJOUR_DEFAULT_PORT);
710 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
712 option = purple_account_option_string_new(_("First name"), "first", default_firstname);
713 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
715 option = purple_account_option_string_new(_("Last name"), "last", default_lastname);
716 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
718 option = purple_account_option_string_new(_("Email"), "email", "");
719 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
721 option = purple_account_option_string_new(_("AIM Account"), "AIM", "");
722 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
724 option = purple_account_option_string_new(_("XMPP Account"), "jid", "");
725 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
727 my_protocol = plugin;
730 PURPLE_INIT_PLUGIN(bonjour, init_plugin, info);