Mercurial > pidgin
view libpurple/protocols/msn/user.c @ 29922:05797ab9b2c2
Fix an MSN emoticon crash discovered by Pierre Nogu¸«²s of Meta Security.
committer: John Bailey <rekkanoryo@rekkanoryo.org>
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Wed, 12 May 2010 04:34:54 +0000 |
parents | 7f97370e674b |
children | 6376fc7a092e |
line wrap: on
line source
/** * @file user.c User functions * * purple * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "msn.h" #include "user.h" #include "slp.h" /*new a user object*/ MsnUser * msn_user_new(MsnUserList *userlist, const char *passport, const char *friendly_name) { MsnUser *user; user = g_new0(MsnUser, 1); user->userlist = userlist; msn_user_set_passport(user, passport); msn_user_set_friendly_name(user, friendly_name); return user; } /*destroy a user object*/ void msn_user_destroy(MsnUser *user) { g_return_if_fail(user != NULL); if (user->clientcaps != NULL) g_hash_table_destroy(user->clientcaps); if (user->group_ids != NULL) { GList *l; for (l = user->group_ids; l != NULL; l = l->next) { g_free(l->data); } g_list_free(user->group_ids); } if (user->msnobj != NULL) msn_object_destroy(user->msnobj); g_free(user->passport); g_free(user->friendly_name); g_free(user->uid); if (user->extinfo) { g_free(user->extinfo->media_album); g_free(user->extinfo->media_artist); g_free(user->extinfo->media_title); g_free(user->extinfo->phone_home); g_free(user->extinfo->phone_mobile); g_free(user->extinfo->phone_work); g_free(user->extinfo); } g_free(user->statusline); g_free(user->invite_message); g_free(user); } void msn_user_update(MsnUser *user) { PurpleAccount *account; gboolean offline; g_return_if_fail(user != NULL); account = user->userlist->session->account; offline = (user->status == NULL); if (!offline) { purple_prpl_got_user_status(account, user->passport, user->status, "message", user->statusline, NULL); } else { if (user->mobile) { purple_prpl_got_user_status(account, user->passport, "mobile", NULL); purple_prpl_got_user_status(account, user->passport, "available", NULL); } else { purple_prpl_got_user_status(account, user->passport, "offline", NULL); } } if (!offline || !user->mobile) { purple_prpl_got_user_status_deactive(account, user->passport, "mobile"); } if (!offline && user->extinfo && user->extinfo->media_type != CURRENT_MEDIA_UNKNOWN) { if (user->extinfo->media_type == CURRENT_MEDIA_MUSIC) { purple_prpl_got_user_status(account, user->passport, "tune", PURPLE_TUNE_ARTIST, user->extinfo->media_artist, PURPLE_TUNE_ALBUM, user->extinfo->media_album, PURPLE_TUNE_TITLE, user->extinfo->media_title, NULL); } else if (user->extinfo->media_type == CURRENT_MEDIA_GAMES) { purple_prpl_got_user_status(account, user->passport, "tune", "game", user->extinfo->media_title, NULL); } else if (user->extinfo->media_type == CURRENT_MEDIA_OFFICE) { purple_prpl_got_user_status(account, user->passport, "tune", "office", user->extinfo->media_title, NULL); } else { purple_debug_warning("msn", "Got CurrentMedia with unknown type %d.\n", user->extinfo->media_type); } } else { purple_prpl_got_user_status_deactive(account, user->passport, "tune"); } if (user->idle) purple_prpl_got_user_idle(account, user->passport, TRUE, -1); else purple_prpl_got_user_idle(account, user->passport, FALSE, 0); } void msn_user_set_state(MsnUser *user, const char *state) { const char *status; g_return_if_fail(user != NULL); if (state == NULL) { user->status = NULL; return; } if (!g_ascii_strcasecmp(state, "BSY")) status = "busy"; else if (!g_ascii_strcasecmp(state, "BRB")) status = "brb"; else if (!g_ascii_strcasecmp(state, "AWY")) status = "away"; else if (!g_ascii_strcasecmp(state, "PHN")) status = "phone"; else if (!g_ascii_strcasecmp(state, "LUN")) status = "lunch"; else status = "available"; if (!g_ascii_strcasecmp(state, "IDL")) user->idle = TRUE; else user->idle = FALSE; user->status = status; } void msn_user_set_passport(MsnUser *user, const char *passport) { g_return_if_fail(user != NULL); g_free(user->passport); user->passport = g_strdup(passport); } gboolean msn_user_set_friendly_name(MsnUser *user, const char *name) { g_return_val_if_fail(user != NULL, FALSE); if (user->friendly_name && name && (!strcmp(user->friendly_name, name) || !strcmp(user->passport, name))) return FALSE; g_free(user->friendly_name); user->friendly_name = g_strdup(name); serv_got_alias(purple_account_get_connection(user->userlist->session->account), user->passport, name); return TRUE; } void msn_user_set_statusline(MsnUser *user, const char *statusline) { g_return_if_fail(user != NULL); g_free(user->statusline); user->statusline = g_strdup(statusline); } void msn_user_set_uid(MsnUser *user, const char *uid) { g_return_if_fail(user != NULL); g_free(user->uid); user->uid = g_strdup(uid); } void msn_user_set_op(MsnUser *user, MsnListOp list_op) { g_return_if_fail(user != NULL); user->list_op |= list_op; } void msn_user_unset_op(MsnUser *user, MsnListOp list_op) { g_return_if_fail(user != NULL); user->list_op &= ~list_op; } void msn_user_set_buddy_icon(MsnUser *user, PurpleStoredImage *img) { MsnObject *msnobj; g_return_if_fail(user != NULL); msnobj = msn_object_new_from_image(img, "TFR2C2.tmp", user->passport, MSN_OBJECT_USERTILE); if (!msnobj) purple_debug_error("msn", "Unable to open buddy icon from %s!\n", user->passport); msn_user_set_object(user, msnobj); } /*add group id to User object*/ void msn_user_add_group_id(MsnUser *user, const char* group_id) { MsnUserList *userlist; PurpleAccount *account; PurpleBuddy *b; PurpleGroup *g; const char *passport; const char *group_name; g_return_if_fail(user != NULL); g_return_if_fail(group_id != NULL); user->group_ids = g_list_append(user->group_ids, g_strdup(group_id)); userlist = user->userlist; account = userlist->session->account; passport = msn_user_get_passport(user); group_name = msn_userlist_find_group_name(userlist, group_id); purple_debug_info("msn", "User: group id:%s,name:%s,user:%s\n", group_id, group_name, passport); g = purple_find_group(group_name); if ((group_id == NULL) && (g == NULL)) { g = purple_group_new(group_name); purple_blist_add_group(g, NULL); } b = purple_find_buddy_in_group(account, passport, g); if (b == NULL) { b = purple_buddy_new(account, passport, NULL); purple_blist_add_buddy(b, NULL, g, NULL); } purple_buddy_set_protocol_data(b, user); /*Update the blist Node info*/ } /*check if the msn user is online*/ gboolean msn_user_is_online(PurpleAccount *account, const char *name) { PurpleBuddy *buddy; buddy = purple_find_buddy(account, name); return PURPLE_BUDDY_IS_ONLINE(buddy); } gboolean msn_user_is_yahoo(PurpleAccount *account, const char *name) { MsnSession *session = NULL; MsnUser *user; PurpleConnection *gc; gc = purple_account_get_connection(account); if (gc != NULL) session = gc->proto_data; if ((session != NULL) && (user = msn_userlist_find_user(session->userlist, name)) != NULL) { return (user->networkid == MSN_NETWORK_YAHOO); } return (strstr(name,"@yahoo.") != NULL); } void msn_user_remove_group_id(MsnUser *user, const char *id) { GList *l; g_return_if_fail(user != NULL); g_return_if_fail(id != NULL); l = g_list_find_custom(user->group_ids, id, (GCompareFunc)strcmp); if (l == NULL) return; g_free(l->data); user->group_ids = g_list_delete_link(user->group_ids, l); } void msn_user_set_pending_group(MsnUser *user, const char *group) { user->pending_group = g_strdup(group); } char * msn_user_remove_pending_group(MsnUser *user) { char *group = user->pending_group; user->pending_group = NULL; return group; } void msn_user_set_home_phone(MsnUser *user, const char *number) { g_return_if_fail(user != NULL); if (!number && !user->extinfo) return; if (user->extinfo) g_free(user->extinfo->phone_home); else user->extinfo = g_new0(MsnUserExtendedInfo, 1); user->extinfo->phone_home = g_strdup(number); } void msn_user_set_work_phone(MsnUser *user, const char *number) { g_return_if_fail(user != NULL); if (!number && !user->extinfo) return; if (user->extinfo) g_free(user->extinfo->phone_work); else user->extinfo = g_new0(MsnUserExtendedInfo, 1); user->extinfo->phone_work = g_strdup(number); } void msn_user_set_mobile_phone(MsnUser *user, const char *number) { g_return_if_fail(user != NULL); if (!number && !user->extinfo) return; if (user->extinfo) g_free(user->extinfo->phone_mobile); else user->extinfo = g_new0(MsnUserExtendedInfo, 1); user->extinfo->phone_mobile = g_strdup(number); } void msn_user_set_clientid(MsnUser *user, guint clientid) { g_return_if_fail(user != NULL); user->clientid = clientid; } void msn_user_set_network(MsnUser *user, MsnNetwork network) { g_return_if_fail(user != NULL); user->networkid = network; } void msn_user_set_object(MsnUser *user, MsnObject *obj) { g_return_if_fail(user != NULL); if (user->msnobj != NULL) msn_object_destroy(user->msnobj); user->msnobj = obj; if (user->list_op & MSN_LIST_FL_OP) msn_queue_buddy_icon_request(user); } void msn_user_set_client_caps(MsnUser *user, GHashTable *info) { g_return_if_fail(user != NULL); g_return_if_fail(info != NULL); if (user->clientcaps != NULL) g_hash_table_destroy(user->clientcaps); user->clientcaps = info; } void msn_user_set_invite_message(MsnUser *user, const char *message) { g_return_if_fail(user != NULL); g_free(user->invite_message); user->invite_message = g_strdup(message); } const char * msn_user_get_passport(const MsnUser *user) { g_return_val_if_fail(user != NULL, NULL); return user->passport; } const char * msn_user_get_friendly_name(const MsnUser *user) { g_return_val_if_fail(user != NULL, NULL); return user->friendly_name; } const char * msn_user_get_home_phone(const MsnUser *user) { g_return_val_if_fail(user != NULL, NULL); return user->extinfo ? user->extinfo->phone_home : NULL; } const char * msn_user_get_work_phone(const MsnUser *user) { g_return_val_if_fail(user != NULL, NULL); return user->extinfo ? user->extinfo->phone_work : NULL; } const char * msn_user_get_mobile_phone(const MsnUser *user) { g_return_val_if_fail(user != NULL, NULL); return user->extinfo ? user->extinfo->phone_mobile : NULL; } guint msn_user_get_clientid(const MsnUser *user) { g_return_val_if_fail(user != NULL, 0); return user->clientid; } MsnObject * msn_user_get_object(const MsnUser *user) { g_return_val_if_fail(user != NULL, NULL); return user->msnobj; } GHashTable * msn_user_get_client_caps(const MsnUser *user) { g_return_val_if_fail(user != NULL, NULL); return user->clientcaps; } const char * msn_user_get_invite_message(const MsnUser *user) { g_return_val_if_fail(user != NULL, NULL); return user->invite_message; }