📄 bonjour.c
字号:
/* * purple - Bonjour Protocol Plugin * * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <glib.h>#ifndef _WIN32#include <pwd.h>#else#define UNICODE#include <windows.h>#include <lm.h>#endif#include "internal.h"#include "account.h"#include "accountopt.h"#include "debug.h"#include "util.h"#include "version.h"#include "bonjour.h"#include "mdns_common.h"#include "jabber.h"#include "buddy.h"/* * TODO: Should implement an add_buddy callback that removes the buddy * from the local list. Bonjour manages buddies for you, and * adding someone locally by hand is stupid. Or, maybe even better, * if a PRPL does not have an add_buddy callback then do not allow * users to add buddies. */static char *default_firstname;static char *default_lastname;static char *default_hostname;static voidbonjour_removeallfromlocal(PurpleConnection *gc){ PurpleAccount *account = purple_connection_get_account(gc); PurpleBuddyList *blist; PurpleBlistNode *gnode, *cnode, *cnodenext, *bnode, *bnodenext; PurpleBuddy *buddy; blist = purple_get_blist(); if (blist == NULL) return; /* Go through and remove all buddies that belong to this account */ for (gnode = blist->root; gnode; gnode = gnode->next) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; for (cnode = gnode->child; cnode; cnode = cnodenext) { cnodenext = cnode->next; if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; for (bnode = cnode->child; bnode; bnode = bnodenext) { bnodenext = bnode->next; if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; buddy = (PurpleBuddy *)bnode; if (buddy->account != account) continue; purple_prpl_got_user_status(account, buddy->name, "offline", NULL); purple_blist_remove_buddy(buddy); } } }}static voidbonjour_login(PurpleAccount *account){ PurpleConnection *gc = purple_account_get_connection(account); PurpleGroup *bonjour_group; BonjourData *bd; PurpleStatus *status; PurplePresence *presence; gc->flags |= PURPLE_CONNECTION_HTML; gc->proto_data = bd = g_new0(BonjourData, 1); /* Start waiting for jabber connections (iChat style) */ bd->jabber_data = g_new(BonjourJabber, 1); bd->jabber_data->port = BONJOUR_DEFAULT_PORT_INT; bd->jabber_data->account = account; if (bonjour_jabber_start(bd->jabber_data) == -1) { /* Send a message about the connection error */ purple_connection_error(gc, _("Unable to listen for incoming IM connections\n")); return; } /* Connect to the mDNS daemon looking for buddies in the LAN */ bd->dns_sd_data = bonjour_dns_sd_new(); bd->dns_sd_data->first = g_strdup(purple_account_get_string(account, "first", default_firstname)); bd->dns_sd_data->last = g_strdup(purple_account_get_string(account, "last", default_lastname)); bd->dns_sd_data->port_p2pj = bd->jabber_data->port; /* Not engaged in AV conference */ bd->dns_sd_data->vc = g_strdup("!"); status = purple_account_get_active_status(account); presence = purple_account_get_presence(account); if (purple_presence_is_available(presence)) bd->dns_sd_data->status = g_strdup("avail"); else if (purple_presence_is_idle(presence)) bd->dns_sd_data->status = g_strdup("away"); else bd->dns_sd_data->status = g_strdup("dnd"); bd->dns_sd_data->msg = g_strdup(purple_status_get_attr_string(status, "message")); bd->dns_sd_data->account = account; if (!bonjour_dns_sd_start(bd->dns_sd_data)) { purple_connection_error(gc, _("Unable to establish connection with the local mDNS server. Is it running?")); return; } /* Create a group for bonjour buddies */ bonjour_group = purple_group_new(BONJOUR_GROUP_NAME); purple_blist_add_group(bonjour_group, NULL); /* Show the buddy list by telling Purple we have already connected */ purple_connection_set_state(gc, PURPLE_CONNECTED);}static voidbonjour_close(PurpleConnection *connection){ PurpleGroup *bonjour_group; BonjourData *bd = connection->proto_data; /* Stop looking for buddies in the LAN */ if (bd->dns_sd_data != NULL) { bonjour_dns_sd_stop(bd->dns_sd_data); bonjour_dns_sd_free(bd->dns_sd_data); } if (bd->jabber_data != NULL) { /* Stop waiting for conversations */ bonjour_jabber_stop(bd->jabber_data); g_free(bd->jabber_data); } /* Remove all the bonjour buddies */ bonjour_removeallfromlocal(connection); /* Delete the bonjour group */ bonjour_group = purple_find_group(BONJOUR_GROUP_NAME); if (bonjour_group != NULL) purple_blist_remove_group(bonjour_group);}static const char *bonjour_list_icon(PurpleAccount *account, PurpleBuddy *buddy){ return BONJOUR_ICON_NAME;}static intbonjour_send_im(PurpleConnection *connection, const char *to, const char *msg, PurpleMessageFlags flags){ if(!to || !msg) return 0; return bonjour_jabber_send_message(((BonjourData*)(connection->proto_data))->jabber_data, to, msg);}static voidbonjour_set_status(PurpleAccount *account, PurpleStatus *status){ PurpleConnection *gc; BonjourData *bd; gboolean disconnected; PurpleStatusType *type; int primitive; PurplePresence *presence; const char *message, *bonjour_status; gchar *stripped; gc = purple_account_get_connection(account); bd = gc->proto_data; disconnected = purple_account_is_disconnected(account); type = purple_status_get_type(status); primitive = purple_status_type_get_primitive(type); presence = purple_account_get_presence(account); message = purple_status_get_attr_string(status, "message"); if (message == NULL) message = ""; stripped = purple_markup_strip_html(message); /* * The three possible status for Bonjour are * -available ("avail") * -idle ("away") * -away ("dnd") * Each of them can have an optional message. */ if (purple_presence_is_available(presence)) bonjour_status = "avail"; else if (purple_presence_is_idle(presence)) bonjour_status = "away"; else bonjour_status = "dnd"; bonjour_dns_sd_send_status(bd->dns_sd_data, bonjour_status, stripped); g_free(stripped);}static GList *bonjour_status_types(PurpleAccount *account){ GList *status_types = NULL; PurpleStatusType *type; g_return_val_if_fail(account != NULL, NULL); type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, BONJOUR_STATUS_ID_AVAILABLE, NULL, TRUE, TRUE, FALSE, "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL); status_types = g_list_append(status_types, type); type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, BONJOUR_STATUS_ID_AWAY, NULL, TRUE, TRUE, FALSE, "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL); status_types = g_list_append(status_types, type); type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, BONJOUR_STATUS_ID_OFFLINE, NULL, TRUE, TRUE, FALSE); status_types = g_list_append(status_types, type); return status_types;}static voidbonjour_convo_closed(PurpleConnection *connection, const char *who){ PurpleBuddy *buddy = purple_find_buddy(connection->account, who); BonjourBuddy *bb; if (buddy == NULL) { /* * This buddy is not in our buddy list, and therefore does not really * exist, so we won't have any data about them. */ return; } bb = buddy->proto_data; bonjour_jabber_close_conversation(bb->conversation); bb->conversation = NULL;}static char *bonjour_status_text(PurpleBuddy *buddy){ PurplePresence *presence; presence = purple_buddy_get_presence(buddy); if (purple_presence_is_online(presence) && !purple_presence_is_available(presence)) return g_strdup(_("Away")); return NULL;}static voidbonjour_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full){ PurplePresence *presence; PurpleStatus *status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -