void msn_got_add_user(MsnSession *session, MsnUser *user, MsnListId list_id, int group_id) { PurpleAccount *account; const char *passport; const char *friendly; account = session->account; passport = msn_user_get_passport(user); friendly = msn_user_get_friendly_name(user); if (list_id == MSN_LIST_FL) { PurpleConnection *gc; gc = purple_account_get_connection(account); serv_got_alias(gc, passport, friendly); if (group_id >= 0) { msn_user_add_group_id(user, group_id); } else { /* session->sync->fl_users_count++; */ } } else if (list_id == MSN_LIST_AL) { purple_privacy_permit_add(account, passport, TRUE); } else if (list_id == MSN_LIST_BL) { purple_privacy_deny_add(account, passport, TRUE); } else if (list_id == MSN_LIST_RL) { PurpleConnection *gc; PurpleConversation *convo; gc = purple_account_get_connection(account); purple_debug_info("msn", "%s has added you to his or her buddy list.\n", passport); convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, passport, account); if (convo) { PurpleBuddy *buddy; char *msg; buddy = purple_find_buddy(account, passport); msg = g_strdup_printf( _("%s has added you to his or her buddy list."), buddy ? purple_buddy_get_contact_alias(buddy) : passport); purple_conv_im_write(PURPLE_CONV_IM(convo), passport, msg, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(msg); } if (!(user->list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP))) { /* * TODO: The friendly name was NULL for me when I * looked at this. Maybe we should use the store * name instead? --KingAnt */ got_new_entry(gc, passport, friendly); } } user->list_op |= (1 << list_id); /* purple_user_add_list_id (user, list_id); */ }
void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { MsnSession *session; MsnSlpLink *slplink; MsnObject *obj; char **tokens; char *smile, *body_str; const char *body, *who, *sha1; guint tok; size_t body_len; PurpleConversation *conv; session = cmdproc->session; if (!purple_account_get_bool_without_default_value(session->account, "custom_smileys")) return; body = msn_message_get_bin_data(msg, &body_len); body_str = g_strndup(body, body_len); /* MSN Messenger 7 may send more than one MSNObject in a single message... * Maybe 10 tokens is a reasonable max value. */ tokens = g_strsplit(body_str, "\t", 10); g_free(body_str); for (tok = 0; tok < 9; tok += 2) { if (tokens[tok] == NULL || tokens[tok + 1] == NULL) { break; } smile = tokens[tok]; { gchar *tmp; tmp = pecan_url_decode (tokens[tok + 1]); obj = msn_object_new_from_string(tmp); g_free(tmp); } if (obj == NULL) break; who = msn_object_get_creator(obj); sha1 = msn_object_get_sha1(obj); slplink = msn_session_get_slplink(session, who); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who, session->account); /* If the conversation doesn't exist then this is a custom smiley * used in the first message in a MSN conversation: we need to create * the conversation now, otherwise the custom smiley won't be shown. * This happens because every GtkIMHtml has its own smiley tree: if * the conversation doesn't exist then we cannot associate the new * smiley with its GtkIMHtml widget. */ if (!conv) { //conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who); } if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) { msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj); } msn_object_destroy(obj); obj = NULL; who = NULL; sha1 = NULL; } g_strfreev(tokens); }
static gboolean handle_presence_contact(JabberStream *js, JabberPresence *presence) { JabberBuddyResource *jbr; PurpleAccount *account; PurpleBuddy *b; char *buddy_name; PurpleConversation *conv; buddy_name = jabber_id_get_bare_jid(presence->jid_from); account = purple_connection_get_account(js->gc); b = purple_find_buddy(account, buddy_name); /* * Unbind/unlock from sending messages to a specific resource on * presence changes. This is locked to a specific resource when * receiving a message (in message.c). */ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy_name, account); if (conv) { purple_debug_info("jabber", "Changed conversation binding from %s to %s\n", purple_conversation_get_name(conv), buddy_name); purple_conversation_set_name(conv, buddy_name); } if (b == NULL) { if (presence->jb != js->user_jb) { purple_debug_warning("jabber", "Got presence for unknown buddy %s on account %s (%p)\n", buddy_name, purple_account_get_username(account), account); g_free(buddy_name); return FALSE; } else { /* this is a different resource of our own account. Resume even when this account isn't on our blist */ } } if (b && presence->vcard_avatar_hash) { const char *ah = presence->vcard_avatar_hash[0] != '\0' ? presence->vcard_avatar_hash : NULL; const char *ah2 = purple_buddy_icons_get_checksum_for_user(b); if (!purple_strequal(ah, ah2)) { /* XXX this is a crappy way of trying to prevent * someone from spamming us with presence packets * and causing us to DoS ourselves...what we really * need is a queue system that can throttle itself, * but i'm too tired to write that right now */ if(!g_slist_find(js->pending_avatar_requests, presence->jb)) { JabberIq *iq; xmlnode *vcard; js->pending_avatar_requests = g_slist_prepend(js->pending_avatar_requests, presence->jb); iq = jabber_iq_new(js, JABBER_IQ_GET); xmlnode_set_attrib(iq->node, "to", buddy_name); vcard = xmlnode_new_child(iq->node, "vCard"); xmlnode_set_namespace(vcard, "vcard-temp"); jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL); jabber_iq_send(iq); } } } if (presence->state == JABBER_BUDDY_STATE_ERROR || presence->type == JABBER_PRESENCE_UNAVAILABLE || presence->type == JABBER_PRESENCE_UNSUBSCRIBED) { jabber_buddy_remove_resource(presence->jb, presence->jid_from->resource); } else { jbr = jabber_buddy_track_resource(presence->jb, presence->jid_from->resource, presence->priority, presence->state, presence->status); jbr->idle = presence->idle ? time(NULL) - presence->idle : 0; } jbr = jabber_buddy_find_resource(presence->jb, NULL); if (jbr) { jabber_google_presence_incoming(js, buddy_name, jbr); purple_prpl_got_user_status(account, buddy_name, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, "message", jbr->status, NULL); purple_prpl_got_user_idle(account, buddy_name, jbr->idle, jbr->idle); if (presence->nickname) serv_got_alias(js->gc, buddy_name, presence->nickname); } else { purple_prpl_got_user_status(account, buddy_name, jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_UNAVAILABLE), presence->status ? "message" : NULL, presence->status, NULL); } g_free(buddy_name); return TRUE; }
static void msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user) { MsnCmdProc *cmdproc; PurpleAccount *account; MsnUserList *userlist; MsnUser *msnuser; char *semicolon; char *passport; g_return_if_fail(swboard != NULL); cmdproc = swboard->cmdproc; account = cmdproc->session->account; semicolon = strchr(user, ';'); /* We don't really care about the machine ID. */ if (semicolon) passport = g_strndup(user, semicolon - user); else passport = g_strdup(user); userlist = swboard->session->userlist; msnuser = msn_userlist_find_user(userlist, passport); /* Don't add multiple endpoints to the conversation. */ if (g_list_find_custom(swboard->users, passport, (GCompareFunc)msn_user_passport_cmp)) { g_free(passport); return; } /* Don't add ourselves either... */ if (g_str_equal(passport, purple_account_get_username(account))) { g_free(passport); return; } if (!msnuser) { purple_debug_info("msn","User %s is not on our list.\n", passport); msnuser = msn_user_new(userlist, passport, NULL); } else msn_user_ref(msnuser); g_free(passport); swboard->users = g_list_prepend(swboard->users, msnuser); swboard->current_users++; swboard->empty = FALSE; if (purple_debug_is_verbose()) purple_debug_info("msn", "user=[%s], total=%d\n", user, swboard->current_users); if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL)) { /* This is a helper switchboard. */ purple_debug_error("msn", "switchboard_add_user: conv != NULL\n"); return; } if ((swboard->conv != NULL) && (purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT)) { purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), msnuser->passport, NULL, PURPLE_CBFLAGS_NONE, TRUE); msn_servconn_set_idle_timeout(swboard->servconn, 0); } else if (swboard->current_users > 1) { msn_servconn_set_idle_timeout(swboard->servconn, 0); if (swboard->conv == NULL || purple_conversation_get_type(swboard->conv) != PURPLE_CONV_TYPE_CHAT) { GList *l; #if 0 /* this is bad - it causes msn_switchboard_close to be called on the * switchboard we're in the middle of using :( */ if (swboard->conv != NULL) purple_conversation_destroy(swboard->conv); #endif swboard->chat_id = msn_switchboard_get_chat_id(); swboard->flag |= MSN_SB_FLAG_IM; swboard->conv = serv_got_joined_chat(account->gc, swboard->chat_id, "MSN Chat"); for (l = swboard->users; l != NULL; l = l->next) { const char *tmp_user; tmp_user = ((MsnUser*)l->data)->passport; purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), tmp_user, NULL, PURPLE_CBFLAGS_NONE, TRUE); } purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), purple_account_get_username(account), NULL, PURPLE_CBFLAGS_NONE, TRUE); g_free(swboard->im_user); swboard->im_user = NULL; } } else if (swboard->conv == NULL) { swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, msnuser->passport, account); } else { purple_debug_warning("msn", "switchboard_add_user: This should not happen!\n"); } }
static void waprpl_process_incoming_events(PurpleConnection *gc) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); PurpleAccount * acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending auth", 1, 4); break; case 2: purple_connection_update_progress(gc, "Waiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connected", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; break; default: break; }; char * msg, * who, * prev, * url, *author; int status; int size; double lat,lng; // Incoming messages while (waAPI_querychat(wconn->waAPI, &who, &msg, &author)) { purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", who,msg); if (isgroup(who)) { // Search fot the combo PurpleBlistNode* node = purple_blist_get_root(); GHashTable* hasht = NULL; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { hasht = purple_chat_get_components(ch); if (strcmp(g_hash_table_lookup(hasht, "id"),who) == 0) { break; } } } node = purple_blist_node_next(node,FALSE); } int convo_id = chatid_to_convo(who); PurpleConversation *convo = purple_find_chat(gc, convo_id); // Create a window if it's not open yet if (!convo) waprpl_chat_join(gc,hasht); if (convo != NULL) { serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), author, PURPLE_MESSAGE_RECV, msg, time(NULL)); }else{ printf("Received group message but could not find the group! %s\n",msg); } }else{ // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, msg, PURPLE_MESSAGE_RECV, time(NULL)); } } while (waAPI_querychatimage(wconn->waAPI, &who, &prev, &size, &url)) { printf("Got chat image %s %s\n",who,url); purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a>",url,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatlocation(wconn->waAPI, &who, &prev, &size, &lat, &lng)) { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", who,(float)lat,(float)lng); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%f&lon=%f&zoom=16\"><img src=\"%u\"></a>",lat,lng,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatsound(wconn->waAPI, &who, &url)) { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\">%s</a>",url,url), PURPLE_MESSAGE_RECV , time(NULL)); } // User status change while (waAPI_querystatus(wconn->waAPI, &who, &status)) { if (status == 1) { purple_prpl_got_user_status(acc, who, "available", "message","", NULL); } else { purple_prpl_got_user_status(acc, who, "unavailable", "message","", NULL); } } // User typing info notify while (waAPI_querytyping(wconn->waAPI, &who, &status)) { if (status == 1) { serv_got_typing(gc,who,0,PURPLE_TYPING); } else { serv_got_typing_stopped(gc,who); } } // User profile picture char * icon, * hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc,who, g_memdup(icon,len),len, hash); } // Groups update if (waAPI_getgroupsupdated(wconn->waAPI)) { // Delete/update the chats that are in our list PurpleBlistNode* node = purple_blist_get_root(); while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { int found = 0; GHashTable *hasht = purple_chat_get_components(ch); char * grid = g_hash_table_lookup(hasht, "id"); char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { if (strcmp(*gplist,grid) == 0) { // The group is in the system, update the fields char *id,*sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); g_hash_table_insert(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(hasht, g_strdup("owner"), g_strdup(own)); found = 1; break; } gplist++; } // The group was deleted if (!found) { PurpleBlistNode* del = node; node = purple_blist_node_next(node,FALSE); purple_blist_remove_chat(del); } } } node = purple_blist_node_next(node,FALSE); } // Add new groups char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { int found = 0; PurpleBlistNode* node = purple_blist_get_root(); PurpleChat * ch; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { char * grid = g_hash_table_lookup(purple_chat_get_components(ch), "id"); if (strcmp(*gplist,grid) == 0) { found = 1; break; } } } node = purple_blist_node_next(node,FALSE); } if (!found) { char *sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", *gplist,sub); GHashTable * htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(*gplist)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc,sub,htable); purple_blist_add_chat(ch,NULL,NULL); } // Now update the open conversation that may exist char * id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation * conv = purple_find_chat(gc, prplid); if (conv) { char *subject, *owner, *part; if (!waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) return; purple_conv_chat_clear_users(purple_conversation_get_chat_data(conv)); gchar **plist = g_strsplit(part,",",0); while (*plist) { purple_conv_chat_add_user (purple_conversation_get_chat_data(conv), *plist,"",PURPLE_CBFLAGS_NONE | (!strcmp(owner,*plist) ? PURPLE_CBFLAGS_FOUNDER : 0),FALSE); plist++; } } gplist++; } } }
void PurpleLine::fetch_conversation_history(PurpleConversation *conv, int count, bool requested) { PurpleConversationType type = conv->type; std::string name(purple_conversation_get_name(conv)); int64_t end_seq = -1; int64_t *end_seq_p = (int64_t *)purple_conversation_get_data(conv, "line-end-seq"); if (end_seq_p) end_seq = *end_seq_p; if (end_seq != -1) c_out->send_getPreviousMessages(name, end_seq - 1, count); else c_out->send_getRecentMessages(name, count); c_out->send([this, requested, type, name, end_seq]() { int64_t new_end_seq = end_seq; std::vector<line::Message> recent_msgs; if (end_seq != -1) c_out->recv_getPreviousMessages(recent_msgs); else c_out->recv_getRecentMessages(recent_msgs); PurpleConversation *conv = purple_find_conversation_with_account(type, name.c_str(), acct); if (!conv) return; // Conversation died while fetching messages auto *queue = (std::vector<line::Message> *) purple_conversation_get_data(conv, "line-message-queue"); purple_conversation_set_data(conv, "line-message-queue", nullptr); // Find least seq value from messages for future history queries for (line::Message &msg: recent_msgs) { if (msg.contentMetadata.count("seq")) { try { int64_t seq = std::stoll(msg.contentMetadata["seq"]); if (new_end_seq == -1 || seq < new_end_seq) new_end_seq = seq; } catch (...) { /* ignore parse error */ } } } if (queue) { // If there's a message queue, remove any already-queued messages in the recent message // list to prevent them showing up twice. recent_msgs.erase( std::remove_if( recent_msgs.begin(), recent_msgs.end(), [&queue](line::Message &rm) { auto r = find_if( queue->begin(), queue->end(), [&rm](line::Message &qm) { return qm.id == rm.id; }); return (r != queue->end()); }), recent_msgs.end()); } if (recent_msgs.size()) { purple_conversation_write( conv, "", "<strong>Message history</strong>", (PurpleMessageFlags)PURPLE_MESSAGE_RAW, time(NULL)); for (auto msgi = recent_msgs.rbegin(); msgi != recent_msgs.rend(); msgi++) write_message(*msgi, true); purple_conversation_write( conv, "", "<hr>", (PurpleMessageFlags)PURPLE_MESSAGE_RAW, time(NULL)); } else { if (requested) { // If history was requested by the user and there is none, let the user know purple_conversation_write( conv, "", "<strong>No more history</strong>", (PurpleMessageFlags)PURPLE_MESSAGE_RAW, time(NULL)); } } // If there's a message queue, play it back now if (queue) { for (line::Message &msg: *queue) write_message(msg, false); delete queue; } int64_t *end_seq_p = (int64_t *)purple_conversation_get_data(conv, "line-end-seq"); if (end_seq_p) delete end_seq_p; purple_conversation_set_data(conv, "line-end-seq", new int64_t(new_end_seq)); }); }
void coincoin_parse_message(HttpHandler* handler, gchar* response, gsize len, gpointer userdata) { CoinCoinAccount* cca = handler->data; PurpleConversation* convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, "board", cca->account); if(!convo) return; // not on the board channel xmlnode* node = coincoin_xmlparse(response, len); xmlnode* post; GSList *last_msg = cca->messages; GSList *iter; GSList *messages = NULL; unsigned i; if(!node) { purple_debug(PURPLE_DEBUG_ERROR, "coincoin", "Unable to parse response.\n"); return; } for(post = xmlnode_get_child(node, "post"); post; post = xmlnode_get_next_twin(post)) { CoinCoinMessage* msg; gint64 id = strtoul(xmlnode_get_attrib(post, "id"), NULL, 10); /* Check if this message has already been showed. */ for(iter = last_msg; iter && ((CoinCoinMessage*)iter->data)->id != id; iter = iter->next) ; if(iter) break; msg = coincoin_message_new(id, post); if(!msg) continue; messages = g_slist_prepend(messages, msg); if(strcmp(msg->from, purple_connection_get_display_name(cca->pc))) { PurpleConvChatBuddy* cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(convo), msg->from); if(!cb) purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo), msg->from, msg->info, PURPLE_CBFLAGS_NONE, FALSE); } } /* Flush messages (in reversed order) */ for(iter = messages; iter; ) { CoinCoinMessage* msg = iter->data; if(!purple_account_get_bool(cca->account, "no_reformat_messages", FALSE)) coincoin_message_ref(msg, cca->messages); serv_got_chat_in(cca->pc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), msg->from, PURPLE_MESSAGE_DELAYED, msg->message, msg->timestamp); if(cca->messages && ((CoinCoinMessage*)cca->messages->data)->timestamp == msg->timestamp) { msg->multiple = ((CoinCoinMessage*)cca->messages->data)->multiple = TRUE; msg->ref = ((CoinCoinMessage*)cca->messages->data)->ref + 1; } GSList* link = iter; iter = iter->next; link->next = cca->messages; cca->messages = link; } /* Now purge extra-messages */ for(i = 0, iter = last_msg; iter; ++i) { if(i < CC_LAST_MESSAGE_MAX) iter = iter->next; else if(i == CC_LAST_MESSAGE_MAX) { GSList* prev; prev = iter; iter = iter->next; prev->next = NULL; } else { /* This user doesn't participate to conversation * anymore. So it can leave channel. */ CoinCoinMessage* cur = iter->data; if(strcmp(cur->from, purple_connection_get_display_name(cca->pc)) && purple_conv_chat_cb_find(PURPLE_CONV_CHAT(convo), cur->from)) { GSList* it = cca->messages; while(it && it != iter && strcmp(((CoinCoinMessage*)it->data)->from, cur->from)) it = it->next; if(it == iter || !it) purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), cur->from, NULL); } coincoin_message_free(cur); iter->data = NULL; iter = g_slist_delete_link(iter, iter); } } xmlnode_free(node); }
void PurpleIMChat::createPurpleChat(PurpleConnection *gGC, int id, GList *users, PurpleIMChat & imChat, PurpleAccount* gAccount) //VOXOX - JRT - 2009.07.10 { char chatName[256]; mConvInfo_t *mConv = FindChatStructById(id); PurpleConversation *gConv = NULL; EnumIMProtocol::IMProtocol protocol = PurpleIMPrcl::GetEnumIMProtocol(gGC->account->protocol_id); if (mConv == NULL) { //Create IMChatSession and copy some values from IMChat. mConv = CreateChatSession(true, imChat); mConv->conv_session->setIMChatType( imChat.getIMChatType() ); // mConv->conv_session->getGroupChatInfo() = imChat.getGroupChatInfo(); } //VOXOX - JRT - 2009.06.15 - purple_conversation_get_name() uses this to id (numeric)! // Since id is ChatSession Address (0x), if you change this, then some 'find's will fail. // You will need your own data members to track alias, etc. // NOTE: This may be JABBER ONLY. // snprintf(chatName, sizeof(chatName), "Chat%d", mConv->conv_id); strcpy( chatName, imChat.getGroupChatInfo().getAlias().c_str() ); if (protocol == EnumIMProtocol::IMProtocolMSN) { //VOXOX - JRT - 2009.06.18 - TODO: check on use of 'chatname'; move to switch in following else-clause. gConv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, chatName, gGC->account); if (!gConv) LOG_FATAL("Chat doesn't exist !!"); mConv->purple_conv_session = gConv; // gConv->ui_data = mConv; } else { GHashTable *components; components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); char *room = NULL; char *server = NULL; g_hash_table_replace(components, g_strdup("room"), g_strdup(chatName)); switch( protocol ) { case EnumIMProtocol::IMProtocolYahoo: g_hash_table_replace(components, g_strdup("topic"), g_strdup("Join my conference...")); g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference")); break; case EnumIMProtocol::IMProtocolAIM: case EnumIMProtocol::IMProtocolICQ: //Defaults for: // "room" - empty or passed in value (NULL below) // "exchange" - "4" components = serv_chat_info_defaults( gGC, NULL ); g_hash_table_replace(components, g_strdup("exchange"), g_strdup("16")); //VOXOX - JRT - 2009.06.14 - why do we use "16"? g_hash_table_replace(components, g_strdup("room"), g_strdup(chatName)); room = (char*)g_hash_table_lookup(components, "room"); // server = (char*)g_hash_table_lookup(components, "server"); //TODO: break; case EnumIMProtocol::IMProtocolJabber: std::string userChatRoomName = (imChat.getGroupChatInfo().getAlias().empty() ? chatName : imChat.getGroupChatInfo().getAlias()); //This will return defaults for: // "server" - conference.im.voxox.com // "room" - user-defined, or parsed from room@server/handle // "handle" - user id without domain. "*****@*****.**" -> "user" components = serv_chat_info_defaults( gGC, NULL ); //VOXOX - JRT - 2009.06.14 - Get defaults, like server (conference.im.voxox.com) g_hash_table_replace(components, g_strdup("room"), g_strdup(chatName)); room = (char*)g_hash_table_lookup(components, "room"); server = (char*)g_hash_table_lookup(components, "server"); break; } std::string fullRoomName = room; if ( server != NULL ) //VOXOX - JRT - 2009.10.12 - AIM gives NULL server. { fullRoomName += "@"; fullRoomName += server; } mConv->conv_session->getGroupChatInfo().setChatRoom( fullRoomName ); mConv->pending_invites = users; // purple_conversation_new(PURPLE_CONV_TYPE_CHAT, gAccount, fullRoomName.c_str()); //JRT-XXX serv_join_chat(gGC, components); g_hash_table_destroy(components); } }
void irc_msg_names(struct irc_conn *irc, const char *name, const char *from, char **args) { char *names, *cur, *end, *tmp, *msg; PurpleConversation *convo; if (!strcmp(name, "366")) { convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, args[1], irc->account); if (!convo) { purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got a NAMES list for %s, which doesn't exist\n", args[1]); g_string_free(irc->names, TRUE); irc->names = NULL; return; } names = cur = g_string_free(irc->names, FALSE); irc->names = NULL; if (purple_conversation_get_data(convo, IRC_NAMES_FLAG)) { msg = g_strdup_printf(_("Users on %s: %s"), args[1], names ? names : ""); if (purple_conversation_get_type(convo) == PURPLE_CONV_TYPE_CHAT) purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "", msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL)); else purple_conv_im_write(PURPLE_CONV_IM(convo), "", msg, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NO_LOG, time(NULL)); g_free(msg); } else { GList *users = NULL; GList *flags = NULL; while (*cur) { PurpleConvChatBuddyFlags f = PURPLE_CBFLAGS_NONE; end = strchr(cur, ' '); if (!end) end = cur + strlen(cur); if (*cur == '@') { f = PURPLE_CBFLAGS_OP; cur++; } else if (*cur == '%') { f = PURPLE_CBFLAGS_HALFOP; cur++; } else if(*cur == '+') { f = PURPLE_CBFLAGS_VOICE; cur++; } else if(irc->mode_chars && strchr(irc->mode_chars, *cur)) { if (*cur == '~') f = PURPLE_CBFLAGS_FOUNDER; cur++; } tmp = g_strndup(cur, end - cur); users = g_list_prepend(users, tmp); flags = g_list_prepend(flags, GINT_TO_POINTER(f)); cur = end; if (*cur) cur++; } if (users != NULL) { GList *l; purple_conv_chat_add_users(PURPLE_CONV_CHAT(convo), users, NULL, flags, FALSE); for (l = users; l != NULL; l = l->next) g_free(l->data); g_list_free(users); g_list_free(flags); } purple_conversation_set_data(convo, IRC_NAMES_FLAG, GINT_TO_POINTER(TRUE)); } g_free(names); } else { if (!irc->names) irc->names = g_string_new(""); if (irc->names->len && irc->names->str[irc->names->len - 1] != ' ') irc->names = g_string_append_c(irc->names, ' '); irc->names = g_string_append(irc->names, args[3]); } }
void irc_msg_mode(struct irc_conn *irc, const char *name, const char *from, char **args) { PurpleConversation *convo; char *nick = irc_mask_nick(from), *buf; if (*args[0] == '#' || *args[0] == '&') { /* Channel */ char *escaped; convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0], irc->account); if (!convo) { purple_debug(PURPLE_DEBUG_ERROR, "irc", "MODE received for %s, which we are not in\n", args[0]); g_free(nick); return; } escaped = (args[2] != NULL) ? g_markup_escape_text(args[2], -1) : NULL; buf = g_strdup_printf(_("mode (%s %s) by %s"), args[1], escaped ? escaped : "", nick); purple_conv_chat_write(PURPLE_CONV_CHAT(convo), args[0], buf, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(escaped); g_free(buf); if(args[2]) { PurpleConvChatBuddyFlags newflag, flags; char *mcur, *cur, *end, *user; gboolean add = FALSE; mcur = args[1]; cur = args[2]; while (*cur && *mcur) { if ((*mcur == '+') || (*mcur == '-')) { add = (*mcur == '+') ? TRUE : FALSE; mcur++; continue; } end = strchr(cur, ' '); if (!end) end = cur + strlen(cur); user = g_strndup(cur, end - cur); flags = purple_conv_chat_user_get_flags(PURPLE_CONV_CHAT(convo), user); newflag = PURPLE_CBFLAGS_NONE; if (*mcur == 'o') newflag = PURPLE_CBFLAGS_OP; else if (*mcur =='h') newflag = PURPLE_CBFLAGS_HALFOP; else if (*mcur == 'v') newflag = PURPLE_CBFLAGS_VOICE; else if(irc->mode_chars && strchr(irc->mode_chars, '~') && (*mcur == 'q')) newflag = PURPLE_CBFLAGS_FOUNDER; if (newflag) { if (add) flags |= newflag; else flags &= ~newflag; purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(convo), user, flags); } g_free(user); cur = end; if (*cur) cur++; if (*mcur) mcur++; } } } else { /* User */ } g_free(nick); }
/************************************************************************** * Message Handlers **************************************************************************/ void msn_plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { PurpleConnection *gc; const char *body; char *body_enc; char *body_final; size_t body_len; const char *passport; const char *value; gc = cmdproc->session->account->gc; body = msn_message_get_bin_data(msg, &body_len); body_enc = g_markup_escape_text(body, body_len); passport = msg->remote_user; if (!strcmp(passport, "*****@*****.**") && strstr(body, "immediate security update")) { return; } #if 0 if ((value = msn_message_get_header_value(msg, "User-Agent")) != NULL) { purple_debug_misc("msn", "User-Agent = '%s'\n", value); } #endif if ((value = msn_message_get_header_value(msg, "X-MMS-IM-Format")) != NULL) { char *pre, *post; msn_parse_format(value, &pre, &post); body_final = g_strdup_printf("%s%s%s", pre ? pre : "", body_enc ? body_enc : "", post ? post : ""); g_free(pre); g_free(post); g_free(body_enc); } else { body_final = body_enc; } if (cmdproc->servconn->type == MSN_SERVCONN_SB) { MsnSwitchBoard *swboard = cmdproc->data; swboard->flag |= MSN_SB_FLAG_IM; if (swboard->current_users > 1 || ((swboard->conv != NULL) && purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT)) { /* If current_users is always ok as it should then there is no need to * check if this is a chat. */ if (swboard->current_users <= 1) purple_debug_misc("msn", "plain_msg: current_users(%d)\n", swboard->current_users); serv_got_chat_in(gc, swboard->chat_id, passport, 0, body_final, time(NULL)); if (swboard->conv == NULL) { swboard->conv = purple_find_chat(gc, swboard->chat_id); swboard->flag |= MSN_SB_FLAG_IM; } } else if (!g_str_equal(passport, purple_account_get_username(gc->account))) { /* Don't im ourselves ... */ serv_got_im(gc, passport, body_final, 0, time(NULL)); if (swboard->conv == NULL) { swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, passport, purple_connection_get_account(gc)); swboard->flag |= MSN_SB_FLAG_IM; } } } else { serv_got_im(gc, passport, body_final, 0, time(NULL)); } g_free(body_final); }
void msn_invite_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { GHashTable *body; const gchar *command; const gchar *cookie; gboolean accepted = FALSE; g_return_if_fail(cmdproc != NULL); g_return_if_fail(msg != NULL); body = msn_message_get_hashtable_from_body(msg); if (body == NULL) { purple_debug_warning("msn", "Unable to parse invite msg body.\n"); return; } /* * GUID is NOT always present but Invitation-Command and Invitation-Cookie * are mandatory. */ command = g_hash_table_lookup(body, "Invitation-Command"); cookie = g_hash_table_lookup(body, "Invitation-Cookie"); if (command == NULL || cookie == NULL) { purple_debug_warning("msn", "Invalid invitation message: either Invitation-Command " "or Invitation-Cookie is missing or invalid.\n" ); return; } else if (!strcmp(command, "INVITE")) { const gchar *guid = g_hash_table_lookup(body, "Application-GUID"); if (guid == NULL) { purple_debug_warning("msn", "Invite msg missing Application-GUID.\n"); accepted = TRUE; } else if (!strcmp(guid, MSN_FT_GUID)) { } else if (!strcmp(guid, "{02D3C01F-BF30-4825-A83A-DE7AF41648AA}")) { purple_debug_info("msn", "Computer call\n"); if (cmdproc->session) { PurpleConversation *conv = NULL; gchar *from = msg->remote_user; gchar *buf = NULL; if (from) conv = purple_find_conversation_with_account( PURPLE_CONV_TYPE_IM, from, cmdproc->session->account); if (conv) buf = g_strdup_printf( _("%s sent you a voice chat " "invite, which is not yet " "supported."), from); if (buf) { purple_conversation_write(conv, NULL, buf, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NOTIFY, time(NULL)); g_free(buf); } } } else { const gchar *application = g_hash_table_lookup(body, "Application-Name"); purple_debug_warning("msn", "Unhandled invite msg with GUID %s: %s.\n", guid, application ? application : "(null)"); } if (!accepted) { MsnSwitchBoard *swboard = cmdproc->data; char *text; MsnMessage *cancel; cancel = msn_message_new(MSN_MSG_TEXT); msn_message_set_content_type(cancel, "text/x-msmsgsinvite"); msn_message_set_charset(cancel, "UTF-8"); msn_message_set_flag(cancel, 'U'); text = g_strdup_printf("Invitation-Command: CANCEL\r\n" "Invitation-Cookie: %s\r\n" "Cancel-Code: REJECT_NOT_INSTALLED\r\n", cookie); msn_message_set_bin_data(cancel, text, strlen(text)); g_free(text); msn_switchboard_send_msg(swboard, cancel, TRUE); msn_message_unref(cancel); } } else if (!strcmp(command, "CANCEL")) { const gchar *code = g_hash_table_lookup(body, "Cancel-Code"); purple_debug_info("msn", "MSMSGS invitation cancelled: %s.\n", code ? code : "no reason given"); } else { /* * Some other already established invitation session. * Can be retrieved by Invitation-Cookie. */ } g_hash_table_destroy(body); }
void qq_process_room_cmd_get_info(guint8 *data, gint data_len, guint32 action, PurpleConnection *gc) { qq_data *qd; qq_room_data *rmd; qq_buddy_data *bd; PurpleChat *chat; PurpleConversation *conv; guint8 organization, role; guint16 max_members; guint32 resend_flag, member_uid, id, qun_id, last_uid; gint bytes; guint num=0; guint8 has_more=0; gchar *topic; g_return_if_fail(data != NULL && data_len > 0); qd = (qq_data *) gc->proto_data; /* qq_show_packet("Room Info", data, data_len); */ bytes = 0; bytes += qq_get32(&id, data + bytes); g_return_if_fail(id > 0); bytes += qq_get32(&qun_id, data + bytes); g_return_if_fail(qun_id > 0); chat = qq_room_find_or_new(gc, id, qun_id); g_return_if_fail(chat != NULL); rmd = qq_room_data_find(gc, id); g_return_if_fail(rmd != NULL); bytes += qq_get32(&resend_flag, data + bytes); //first 00 00 00 03, then 00 00 00 02 if (resend_flag == 0x00000003) { bytes += qq_get8(&(rmd->type8), data + bytes); bytes += 4; //maybe vip sign bytes += qq_get32(&(rmd->creator_uid), data + bytes); if (rmd->creator_uid == qd->uid) rmd->my_role = QQ_ROOM_ROLE_ADMIN; bytes += qq_get8(&(rmd->auth_type), data + bytes); bytes += 4 ; /* oldCategory */ bytes += 2; // 00 00 bytes += qq_get32(&(rmd->category), data + bytes); bytes += qq_get16(&max_members, data + bytes); bytes += 1; bytes += 8; purple_debug_info("QQ", "type: %u creator: %u category: %u max_members: %u\n", rmd->type8, rmd->creator_uid, rmd->category, max_members); bytes += qq_get_vstr(&(rmd->name), NULL, sizeof(guint8), data + bytes); bytes += 2; /* 0x0000 */ bytes += qq_get_vstr(&(rmd->bulletin), NULL, sizeof(guint8), data + bytes); bytes += qq_get_vstr(&(rmd->intro), NULL, sizeof(guint8), data + bytes); bytes += qq_get_vstr(&(rmd->token), NULL, sizeof(guint16), data + bytes); purple_debug_info("QQ", "room [%s] bulletin [%s] intro [%s] \n", rmd->name, rmd->bulletin, rmd->intro); bytes += 2; //Unknown bytes += qq_get32(&last_uid, data + bytes); /* last_uid of this recv, request more with it */ bytes += qq_get8(&has_more, data + bytes); /* if there are more, request again */ /* now comes the member list separated by 0x00 */ } else { /* resend_flag 00 00 00 02 is special, start with random one only 5 bytes */ bytes += qq_get32(&member_uid, data + bytes); num++; bytes += qq_get8(&organization, data + bytes); bd = qq_room_buddy_find_or_new(gc, rmd, member_uid); } while (bytes < data_len) { bytes += qq_get32(&member_uid, data + bytes); num++; bytes += qq_get8(&organization, data + bytes); bytes += qq_get8(&role, data + bytes); #if 0 if(organization != 0 || role != 0) { purple_debug_info("QQ", "%u, organization=%d, role=%d\n", member_uid, organization, role); } #endif bd = qq_room_buddy_find_or_new(gc, rmd, member_uid); if (bd != NULL) bd->role = role; } purple_debug_info("QQ", "Qun \"%s\" has received %d members\n", rmd->name, num); if (has_more) { qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_GET_INFO, id, NULL, 0, 0, last_uid); } else { qq_room_update_chat_info(chat, rmd); if (action == QQ_ROOM_INFO_DISPLAY) { room_info_display(gc, rmd); } conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, rmd->name, purple_connection_get_account(gc)); if(NULL == conv) { purple_debug_warning("QQ", "Conversation \"%s\" is not opened\n", rmd->name); return; } topic = g_strdup_printf("%u %s", rmd->qun_id, rmd->bulletin); purple_debug_info("QQ", "Set chat topic to %s\n", topic); purple_conv_chat_set_topic(PURPLE_CONV_CHAT(conv), NULL, topic); g_free(topic); } }
PurpleStoredImage * purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node, guchar *icon_data, size_t icon_len) { char *old_icon; PurpleStoredImage *old_img; PurpleStoredImage *img = NULL; g_return_val_if_fail(node != NULL, NULL); if (!PURPLE_BLIST_NODE_IS_CONTACT(node) && !PURPLE_BLIST_NODE_IS_CHAT(node) && !PURPLE_BLIST_NODE_IS_GROUP(node)) { return NULL; } old_img = g_hash_table_lookup(pointer_icon_cache, node); if (icon_data != NULL && icon_len > 0) { img = purple_buddy_icon_data_new(icon_data, icon_len, NULL); } old_icon = g_strdup(purple_blist_node_get_string(node, "custom_buddy_icon")); if (img && purple_buddy_icons_is_caching()) { const char *filename = purple_imgstore_get_filename(img); purple_blist_node_set_string(node, "custom_buddy_icon", filename); ref_filename(filename); } else { purple_blist_node_remove_setting(node, "custom_buddy_icon"); } unref_filename(old_icon); if (img) g_hash_table_insert(pointer_icon_cache, node, img); else g_hash_table_remove(pointer_icon_cache, node); if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { PurpleBlistNode *child; for (child = purple_blist_node_get_first_child(node); child; child = purple_blist_node_get_sibling_next(child)) { PurpleBuddy *buddy; PurpleConversation *conv; if (!PURPLE_BLIST_NODE_IS_BUDDY(child)) continue; buddy = (PurpleBuddy *)child; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); if (conv) purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON); /* Is this call necessary anymore? Can the buddies * themselves need updating when the custom buddy * icon changes? */ purple_blist_update_node_icon((PurpleBlistNode*)buddy); } } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleConversation *conv = NULL; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, purple_chat_get_name((PurpleChat*)node), purple_chat_get_account((PurpleChat*)node)); if (conv) { purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON); } } purple_blist_update_node_icon(node); if (old_img) { purple_imgstore_unref(old_img); } else if (old_icon) { /* The old icon may not have been loaded into memory. In that * case, we'll need to uncache the filename. The filenames * are ref-counted, so this is safe. */ purple_buddy_icon_data_uncache_file(old_icon); } g_free(old_icon); return img; }
xmlnode * _h_elim_add_chat( const char *name , const char *id , SEXP_VALUE *args , gpointer data ) { ASSERT_ALISTP( args, id, name ); elim_ping(); const char *aname = ALIST_VAL_STR ( args, "account-name" ); const char *proto = ALIST_VAL_STR ( args, "im-protocol" ); const char *alias = ALIST_VAL_STR ( args, "chat-alias" ); gpointer auid = ALIST_VAL_PTR ( args, "account-uid" ); GHashTable *opts = ALIST_VAL_ALIST( args, "chat-options" ); GHashTable *options = __ghash_str_sexp__str_str( opts ); PurpleAccount *acct = auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto ); if( !acct ) { sexp_val_free( args ); return response_error( ENXIO, id, name, "unknown account" ); } // cook up a chat node. if it's already on our buddy list, uncook it // and use the old one instead (name should be unique per account // so the operation is reasonable - we cannot supply a name as this // parameter can be delegated to the plugin to generate automatically): // this will trigger a new_node call, and possibly a remove call PurpleChat *chat = purple_chat_new( acct, alias, options ); const char *chn = purple_chat_get_name( chat ); PurpleChat *ch_2 = purple_blist_find_chat( acct, chn ); if( ch_2 ) { fprintf( stderr, "(elim-debug chat already exists)\n" ); purple_blist_remove_chat( chat ); chat = ch_2; chn = purple_chat_get_name( chat ); purple_blist_alias_chat( chat, alias ); } fprintf( stderr, "(elim-debug adding chat to blist)\n" ); purple_blist_add_chat( chat, NULL, NULL ); // if we have a conversation already, prod the client to show it fprintf( stderr, "(elim-debug looking for conversation)\n" ); PurpleConversation *conv = purple_find_conversation_with_account( PURPLE_CONV_TYPE_CHAT, chn, acct ); if( conv ) purple_conversation_present( conv ); xmlnode *rval = xnode_new( "alist" ); AL_STR( rval, "account-name", purple_account_get_username (acct) ); AL_STR( rval, "im-protocol" , purple_account_get_protocol_id(acct) ); AL_PTR( rval, "account-uid" , acct ); AL_STR( rval, "chat-name" , chn ); if( conv ) { PurpleConversationType pct = purple_conversation_get_type ( conv ); PurpleConnectionFlags pcf = purple_conversation_get_features( conv ); AL_PTR ( rval, "conv-uid" , conv ); AL_STR ( rval, "conv-name" , purple_conversation_get_name (conv) ); AL_STR ( rval, "conv-title" , purple_conversation_get_title(conv) ); AL_ENUM( rval, "conv-type" , pct, ":conversation-type" ); AL_ENUM( rval, "conv-features", pcf, ":connection-flags" ); } sexp_val_free( args ); return response_value( 0, id, name, rval ); }
/* refresh online member in group conversation window */ void qq_room_conv_set_onlines(PurpleConnection *gc, qq_room_data *rmd) { GList *names, *list, *flags; qq_buddy_data *bd; gchar *member_name, *member_uid; PurpleConversation *conv; gint flag; gboolean is_find; g_return_if_fail(rmd != NULL); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, rmd->title_utf8, purple_connection_get_account(gc)); if (conv == NULL) { purple_debug_warning("QQ", "Conversation \"%s\" is not opened\n", rmd->title_utf8); return; } g_return_if_fail(rmd->members != NULL); names = NULL; flags = NULL; list = rmd->members; while (list != NULL) { bd = (qq_buddy_data *) list->data; /* we need unique identifiers for everyone in the chat or else we'll * run into problems with functions like get_cb_real_name from qq.c */ member_name = (bd->nickname != NULL && *(bd->nickname) != '\0') ? g_strdup_printf("%s (%u)", bd->nickname, bd->uid) : g_strdup_printf("(%u)", bd->uid); member_uid = g_strdup_printf("(%u)", bd->uid); flag = 0; /* TYPING to put online above OP and FOUNDER */ if (is_online(bd->status)) flag |= (PURPLE_CBFLAGS_TYPING | PURPLE_CBFLAGS_VOICE); if(1 == (bd->role & 1)) flag |= PURPLE_CBFLAGS_OP; if(bd->uid == rmd->creator_uid) flag |= PURPLE_CBFLAGS_FOUNDER; is_find = TRUE; if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), member_name)) { purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(conv), member_name, flag); } else if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), member_uid)) { purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(conv), member_uid, flag); purple_conv_chat_rename_user(PURPLE_CONV_CHAT(conv), member_uid, member_name); } else { is_find = FALSE; } if (!is_find) { /* always put it even offline */ names = g_list_append(names, member_name); flags = g_list_append(flags, GINT_TO_POINTER(flag)); } else { g_free(member_name); } g_free(member_uid); list = list->next; } if (names != NULL && flags != NULL) { purple_conv_chat_add_users(PURPLE_CONV_CHAT(conv), names, NULL, flags, FALSE); } /* clean up names */ while (names != NULL) { member_name = (gchar *) names->data; names = g_list_remove(names, member_name); g_free(member_name); } g_list_free(flags); }
static void notify (const gchar *title, const gchar *body, PurpleBuddy *buddy, PurpleConversation *conv) { NotifyNotification *notification = NULL; GdkPixbuf *icon; PurpleBuddyIcon *buddy_icon; gchar *tr_body; PurpleContact *contact; if (buddy) contact = purple_buddy_get_contact (buddy); else contact = NULL; if (body) tr_body = truncate_escape_string (body, 60); else tr_body = NULL; if (!conv && buddy) conv = purple_find_conversation_with_account (PURPLE_CONV_TYPE_ANY, buddy->name, buddy->account); if (conv && conv->ui_ops && conv->ui_ops->has_focus) { #ifndef DEBUG /* in debug mode, always show notifications */ if (conv->ui_ops->has_focus(conv) == TRUE) { purple_debug_info (PLUGIN_ID, "Conversation has focus 0x%lx\n", (unsigned long)conv); return; } #endif } if (contact) notification = g_hash_table_lookup (buddy_hash, contact); else if (conv) notification = g_hash_table_lookup (buddy_hash, conv); else notification = NULL; if (notification != NULL) { notify_notification_update (notification, title, tr_body, NULL); notify_notification_set_timeout(notification, purple_prefs_get_int("/plugins/gtk/libnotify/timeout")); /* this shouldn't be necessary, file a bug */ notify_notification_show (notification, NULL); purple_debug_info (PLUGIN_ID, "notify(), update: " "title: '%s', body: '%s', buddy: '%s'\n", title, tr_body, buddy ? best_name (buddy) : ""); g_free (tr_body); return; } #ifdef LIBNOTIFY_07 notification = notify_notification_new (title, tr_body, NULL); #else notification = notify_notification_new (title, tr_body, NULL, NULL); #endif purple_debug_info (PLUGIN_ID, "notify(), new: " "title: '%s', body: '%s', buddy: '%s'\n", title, tr_body, buddy ? best_name (buddy) : ""); g_free (tr_body); if (buddy) buddy_icon = purple_buddy_get_icon (buddy); else buddy_icon = NULL; if (buddy_icon) { icon = pixbuf_from_buddy_icon (buddy_icon); purple_debug_info (PLUGIN_ID, "notify(), has a buddy icon.\n"); } else if (buddy) { icon = pidgin_create_prpl_icon (buddy->account, 1); purple_debug_info (PLUGIN_ID, "notify(), has a prpl icon.\n"); } else if (conv) { icon = pidgin_create_prpl_icon (conv->account, 1); purple_debug_info (PLUGIN_ID, "notify(), has a prpl icon.\n"); } else { icon = NULL; purple_debug_info (PLUGIN_ID, "notify(), has no icon.\n"); } if (icon) { notify_notification_set_icon_from_pixbuf (notification, icon); g_object_unref (icon); } else { purple_debug_warning (PLUGIN_ID, "notify(), couldn't find any icon!\n"); } if (contact) g_hash_table_insert (buddy_hash, contact, notification); else if (conv) g_hash_table_insert (buddy_hash, conv, notification); g_object_set_data (G_OBJECT(notification), "contact", contact); g_object_set_data (G_OBJECT(notification), "conv", conv); g_object_set_data (G_OBJECT(notification), "buddy", buddy); g_signal_connect (notification, "closed", G_CALLBACK(closed_cb), NULL); notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL); notify_notification_add_action (notification, "show", _("Show"), action_cb, NULL, NULL); notify_notification_set_timeout(notification, purple_prefs_get_int("/plugins/gtk/libnotify/timeout")); if (!notify_notification_show (notification, NULL)) { purple_debug_error (PLUGIN_ID, "notify(), failed to send notification\n"); } }
bool PurpleIMChat::createSessionCbk(void * dataIn) { Mutex::ScopedLock lock(PurpleIMChat::_mutex); PurpleIMChatCallbackData* cbData = (PurpleIMChatCallbackData*) dataIn; PurpleIMChat* imChat = cbData->getPurpleIMChat(); IMContactSet* imContactSet = cbData->getIMContactSet(); // PurpleAccount* gAccount = purple_accounts_find(imChat->getIMAccount().getLogin().c_str(), // PurpleIMPrcl::GetPrclId(imChat->getIMAccount().getProtocol())); PurpleAccount* gAccount = getPurpleAccount( imChat->getIMAccount() ); IMContactSet::const_iterator it; if (imContactSet->empty()) { LOG_FATAL("imContactSet is empty"); } else { switch( imChat->getIMChatType() ) { case IMChat::Chat: { it = imContactSet->begin(); std::string contactId = (*it).getContactId(); PurpleConversation *gConv = NULL; gConv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, contactId.c_str(), gAccount); //If converation already exists, we still do the CreatedEvent so UI responds properly, // then we remove the task from queue. if ( gConv ) { mConvInfo_t *mConv = (mConvInfo_t *)gConv->ui_data; imChat->newIMChatSessionCreatedEvent(*imChat, *(mConv->conv_session)); //VOXOX - JRT - 2009.07.09 timeoutRemove( cbData ); delete cbData; return FALSE; } purple_conversation_new(PURPLE_CONV_TYPE_IM, gAccount, contactId.c_str()); break; } case IMChat::ChatGroup: { //Capture invitees. They will be handled later. PurpleConnection *gGC = purple_account_get_connection(gAccount); GList *mlist = NULL; for (it = imContactSet->begin(); it != imContactSet->end(); it++) { mlist = g_list_append(mlist, strdup(it->getContactId().c_str()) ); } //Does this group chat already exist? std::string chatRoomName = imChat->getGroupChatInfo().getAlias(); //VOXOX - JRT - 2009.06.18 - TODO: use getChatRoom() PurpleConversation *gConv = NULL; gConv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, chatRoomName.c_str(), gAccount); //If converation already exists, we still do the CreatedEvent so UI responds properly, // then we remove the task from queue. if ( gConv ) { mConvInfo_t *mConv = (mConvInfo_t *)gConv->ui_data; imChat->newIMChatSessionCreatedEvent(*imChat, *(mConv->conv_session)); //VOXOX - JRT - 2009.07.09 timeoutRemove( cbData ); delete cbData; return FALSE; } //Create new chat. // purple_conversation_new(PURPLE_CONV_TYPE_CHAT, gAccount, contactId.c_str()); createPurpleChat(gGC, 0, mlist, *imChat, gAccount ); //VOXOX - JRT - 2009.07.10 break; } default: LOG_FATAL("IMChat:IMChatType is improper: ", imChat->getIMChatType()); } } timeoutRemove( cbData ); delete cbData; return TRUE; }
static void silcpurple_buddy_keyagr_cb(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, SilcKeyAgreementStatus status, SilcSKEKeyMaterial *key, void *context) { PurpleConnection *gc = client->application; SilcPurple sg = gc->proto_data; SilcPurpleKeyAgr a = context; if (!sg->conn) return; switch (status) { case SILC_KEY_AGREEMENT_OK: { PurpleConversation *convo; char tmp[128]; /* Set the private key for this client */ silc_client_del_private_message_key(client, conn, client_entry); silc_client_add_private_message_key_ske(client, conn, client_entry, NULL, NULL, key, a->responder); silc_ske_free_key_material(key); /* Open IM window */ convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, client_entry->nickname, sg->account); if (convo) { /* we don't have windows in the core anymore...but we may want to * provide some method for asking the UI to show the window purple_conv_window_show(purple_conversation_get_window(convo)); */ } else { convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, sg->account, client_entry->nickname); } g_snprintf(tmp, sizeof(tmp), "%s [private key]", client_entry->nickname); purple_conversation_set_title(convo, tmp); } break; case SILC_KEY_AGREEMENT_ERROR: purple_notify_error(gc, _("Key Agreement"), _("Error occurred during key agreement"), NULL); break; case SILC_KEY_AGREEMENT_FAILURE: purple_notify_error(gc, _("Key Agreement"), _("Key Agreement failed"), NULL); break; case SILC_KEY_AGREEMENT_TIMEOUT: purple_notify_error(gc, _("Key Agreement"), _("Timeout during key agreement"), NULL); break; case SILC_KEY_AGREEMENT_ABORTED: purple_notify_error(gc, _("Key Agreement"), _("Key agreement was aborted"), NULL); break; case SILC_KEY_AGREEMENT_ALREADY_STARTED: purple_notify_error(gc, _("Key Agreement"), _("Key agreement is already started"), NULL); break; case SILC_KEY_AGREEMENT_SELF_DENIED: purple_notify_error(gc, _("Key Agreement"), _("Key agreement cannot be started with yourself"), NULL); break; default: break; } silc_free(a); }
static void pounce_cb(PurplePounce *pounce, PurplePounceEvent events, void *data) { PurpleConversation *conv; PurpleAccount *account; PurpleBuddy *buddy; const char *pouncee; const char *alias; pouncee = purple_pounce_get_pouncee(pounce); account = purple_pounce_get_pouncer(pounce); buddy = purple_find_buddy(account, pouncee); if (buddy != NULL) { alias = purple_buddy_get_alias(buddy); if (alias == NULL) alias = pouncee; } else alias = pouncee; if (purple_pounce_action_is_enabled(pounce, "open-window")) { if (!purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, pouncee, account)) purple_conversation_new(PURPLE_CONV_TYPE_IM, account, pouncee); } if (purple_pounce_action_is_enabled(pounce, "popup-notify")) { char *tmp = NULL; const char *name_shown; const char *reason; struct { PurplePounceEvent event; const char *format; } messages[] = { {PURPLE_POUNCE_TYPING, _("%s has started typing to you (%s)")}, {PURPLE_POUNCE_TYPED, _("%s has paused while typing to you (%s)")}, {PURPLE_POUNCE_SIGNON, _("%s has signed on (%s)")}, {PURPLE_POUNCE_IDLE_RETURN, _("%s has returned from being idle (%s)")}, {PURPLE_POUNCE_AWAY_RETURN, _("%s has returned from being away (%s)")}, {PURPLE_POUNCE_TYPING_STOPPED, _("%s has stopped typing to you (%s)")}, {PURPLE_POUNCE_SIGNOFF, _("%s has signed off (%s)")}, {PURPLE_POUNCE_IDLE, _("%s has become idle (%s)")}, {PURPLE_POUNCE_AWAY, _("%s has gone away. (%s)")}, {PURPLE_POUNCE_MESSAGE_RECEIVED, _("%s has sent you a message. (%s)")}, {0, NULL} }; int i; reason = purple_pounce_action_get_attribute(pounce, "popup-notify", "reason"); /* * Here we place the protocol name in the pounce dialog to lessen * confusion about what protocol a pounce is for. */ for (i = 0; messages[i].format != NULL; i++) { if (messages[i].event & events) { tmp = g_strdup_printf(messages[i].format, alias, purple_account_get_protocol_name(account)); break; } } if (tmp == NULL) tmp = g_strdup(_("Unknown pounce event. Please report this!")); /* * Ok here is where I change the second argument, title, from * NULL to the account alias if we have it or the account * name if that's all we have */ if ((name_shown = purple_account_get_alias(account)) == NULL) name_shown = purple_account_get_username(account); if (reason == NULL) { purple_notify_info(NULL, name_shown, tmp, purple_date_format_full(NULL)); } else { char *tmp2 = g_strdup_printf("%s\n\n%s", reason, purple_date_format_full(NULL)); purple_notify_info(NULL, name_shown, tmp, tmp2); g_free(tmp2); } g_free(tmp); } if (purple_pounce_action_is_enabled(pounce, "send-message")) { const char *message; message = purple_pounce_action_get_attribute(pounce, "send-message", "message"); if (message != NULL) { conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, pouncee, account); if (conv == NULL) conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, pouncee); purple_conversation_write(conv, NULL, message, PURPLE_MESSAGE_SEND, time(NULL)); serv_send_im(purple_account_get_connection(account), (char *)pouncee, (char *)message, 0); } } if (purple_pounce_action_is_enabled(pounce, "execute-command")) { const char *command; command = purple_pounce_action_get_attribute(pounce, "execute-command", "command"); if (command != NULL) { char *localecmd = g_locale_from_utf8(command, -1, NULL, NULL, NULL); if (localecmd != NULL) { int pid = fork(); if (pid == 0) { char *args[4]; args[0] = "sh"; args[1] = "-c"; args[2] = (char *)localecmd; args[3] = NULL; execvp(args[0], args); _exit(0); } g_free(localecmd); } } } if (purple_pounce_action_is_enabled(pounce, "play-beep")) { beep(); } }
xmlnode * _h_elim_command ( const char *name , const char *id , SEXP_VALUE *args , gpointer data ) { fprintf(stderr, "(elim-debug entered _h_elim_command)"); ASSERT_ALISTP( args, id, name ); elim_ping(); const char *aname = ALIST_VAL_STR( args, "account-name" ); const char *proto = ALIST_VAL_STR( args, "im-protocol" ); gpointer auid = ALIST_VAL_PTR( args, "account-uid" ); PurpleAccount *acct = auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto ); if( !acct ) { sexp_val_free( args ); return response_error( ENXIO, id, name, "unknown account" ); } PurpleConversationType pt = PURPLE_CONV_TYPE_UNKNOWN; gpointer cuid = ALIST_VAL_PTR( args, "conv-uid" ); const char *cname = ALIST_VAL_STR( args, "conv-name" ); PurpleConversation *pc = find_conv_by_acct_uid( acct, cuid ); if ( pc ) pt = purple_conversation_get_type( pc ); else { pt = PURPLE_CONV_TYPE_ANY; pc = purple_find_conversation_with_account( pt, cname, acct ); if( !pc ) { sexp_val_free( args ); return response_error( ENOENT, id, name, "conversation not found" ); } else { pt = purple_conversation_get_type( pc ); } } PurpleCmdStatus c_s = PURPLE_CMD_STATUS_FAILED; const char *cmd = ALIST_VAL_STRING( args, "command" ); char *esc = g_markup_escape_text( cmd, -1 ); char *err = NULL; const char *error = NULL; c_s = purple_cmd_do_command( pc, cmd, esc, &err ); if( c_s != PURPLE_CMD_STATUS_OK && (!err || !*err) ) switch( c_s ) { case PURPLE_CMD_STATUS_FAILED : error = "Command failed"; break; case PURPLE_CMD_STATUS_NOT_FOUND : error = "Command not found"; break; case PURPLE_CMD_STATUS_WRONG_ARGS: error = "Bad command arguments"; break; case PURPLE_CMD_STATUS_WRONG_PRPL: error = "Command not valid for this IM protocol"; break; case PURPLE_CMD_STATUS_WRONG_TYPE: error = "Command not valid in this conversation"; break; default: error = "Unknown command error"; } xmlnode *rval = xnode_new( "alist" ); AL_PTR ( rval, "conv-uid" , pc ); AL_STR ( rval, "conv-name" , purple_conversation_get_name(pc) ); AL_ENUM( rval, "command-status", c_s , ":cmd-status" ); AL_STR ( rval, "command-error" , err ? err : error ); AL_STR ( rval, "command-line" , cmd ); g_free ( err ); g_free ( esc ); sexp_val_free( args ); fprintf(stderr, "(elim-debug leaving _h_elim_command)"); return response_value( 0, id, name, rval ); }
xmlnode * _h_elim_message ( const char *name , const char *id , SEXP_VALUE *args , gpointer data ) { fprintf(stderr, "(elim-debug entered _h_elim_message)"); ASSERT_ALISTP( args, id, name ); elim_ping(); const char *aname = ALIST_VAL_STR( args, "account-name" ); const char *proto = ALIST_VAL_STR( args, "im-protocol" ); gpointer auid = ALIST_VAL_PTR( args, "account-uid" ); PurpleAccount *acct = auid ? find_acct_by_uid( auid ) : purple_accounts_find( aname, proto ); if( !acct ) { sexp_val_free( args ); return response_error( ENXIO, id, name, "unknown account" ); } PurpleConversationType pt = PURPLE_CONV_TYPE_UNKNOWN; gpointer cuid = ALIST_VAL_PTR( args, "conv-uid" ); const char *cname = ALIST_VAL_STR( args, "conv-name" ); PurpleConversation *pc = find_conv_by_acct_uid( acct, cuid ); if ( pc ) pt = purple_conversation_get_type( pc ); else { pt = PURPLE_CONV_TYPE_ANY; pc = purple_find_conversation_with_account( pt, cname, acct ); if( !pc ) { pt = PURPLE_CONV_TYPE_IM; pc = purple_conversation_new( pt, acct, cname ); } else { pt = purple_conversation_get_type( pc ); } } if( !pc ) { sexp_val_free( args ); return response_error( ENXIO, id, name, "new conversation failed" ); } PurpleConvIm *pci = NULL; PurpleConvChat *pcc = NULL; const char *msg = ALIST_VAL_STRING( args, "text" ); char *esc = g_markup_escape_text( msg, -1 ); int len = strlen( esc ); switch( pt ) { case PURPLE_CONV_TYPE_IM: pci = purple_conversation_get_im_data( pc ); purple_conv_im_send( pci, esc ); break; case PURPLE_CONV_TYPE_CHAT: pcc = purple_conversation_get_chat_data( pc ); purple_conv_chat_send( pcc, esc ); break; default: g_free ( esc ); sexp_val_free( args ); return response_error( EINVAL, id, name, "unknown conversation type" ); } xmlnode *rval = xnode_new( "alist" ); AL_INT( rval, "bytes" , len ); AL_PTR( rval, "conv-uid" , pc ); AL_STR( rval, "conv-name", purple_conversation_get_name(pc) ); g_free ( esc ); sexp_val_free( args ); fprintf(stderr, "(elim-debug leaving _h_elim_message)"); return response_value( 0, id, name, rval ); }
static void pb_got_phone_thread(PushBulletAccount *pba, JsonNode *node, gpointer user_data) { PurpleAccount *account = pba->account; PurpleConnection *pc = pba->pc; JsonObject *rootobj = json_node_get_object(node); JsonObject *data = json_object_get_object_member(rootobj, "data"); JsonArray *thread = json_object_get_array_member(data, "thread"); gint i; guint len; gchar *from = user_data; PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, account); gint purple_last_message_timestamp = purple_account_get_int(account, "last_message_timestamp", 0); gint newest_phone_message_id = purple_account_get_int(account, "newest_phone_message_id", 0); /* {"id":"652","type":"sms","timestamp":1440484608,"direction":"outgoing","body":"message","status":"sent"}, {"id":"5","type":"mms","timestamp":1440484096,"direction":"incoming","recipient_index":0,"body":"","image_urls":["url1234"]} */ for(i = json_array_get_length(thread); i > 0; i--) { JsonObject *message = json_array_get_object_element(thread, i - 1); gint64 timestamp = json_object_get_int_member(message, "timestamp"); const gchar *direction = json_object_get_string_member(message, "direction"); const gchar *body = json_object_get_string_member(message, "body"); gint id = atoi(json_object_get_string_member(message, "id")); if (timestamp > purple_last_message_timestamp || id > newest_phone_message_id) { gchar *body_html = purple_strdup_withhtml(body); if (direction[0] != 'o') { serv_got_im(pc, from, body_html, PURPLE_MESSAGE_RECV, timestamp); } else { const gchar *guid = json_object_get_string_member(message, "guid"); if (!guid || !g_hash_table_remove(pba->sent_messages_hash, guid)) { if (conv == NULL) { conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, from); } purple_conversation_write(conv, from, body_html, PURPLE_MESSAGE_SEND, timestamp); } } g_free(body_html); if (json_object_has_member(message, "image_urls")) { JsonArray *image_urls = json_object_get_array_member(message, "image_urls"); guint j, image_urls_len; if (conv == NULL) { conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, from); } for(j = 0, image_urls_len = json_array_get_length(image_urls); j < image_urls_len; j++) { const gchar *image_url = json_array_get_string_element(thread, j); pb_download_image_to_conv(image_url, conv); } } purple_account_set_int(account, "last_message_timestamp", MAX(purple_account_get_int(account, "last_message_timestamp", 0), timestamp)); purple_account_set_int(account, "newest_phone_message_id", MAX(purple_account_get_int(account, "newest_phone_message_id", 0), id)); } } g_free(from); }
/* refresh online member in group conversation window */ void qq_group_conv_refresh_online_member(PurpleConnection *gc, qq_group *group) { GList *names, *list, *flags; qq_buddy *member; gchar *member_name, *member_uid; PurpleConversation *conv; gint flag; g_return_if_fail(group != NULL); names = NULL; flags = NULL; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group->group_name_utf8, purple_connection_get_account(gc)); if (conv != NULL && group->members != NULL) { list = group->members; while (list != NULL) { member = (qq_buddy *) list->data; /* we need unique identifiers for everyone in the chat or else we'll * run into problems with functions like get_cb_real_name from qq.c */ member_name = (member->nickname != NULL && *(member->nickname) != '\0') ? g_strdup_printf("%s (qq-%u)", member->nickname, member->uid) : g_strdup_printf("(qq-%u)", member->uid); member_uid = g_strdup_printf("(qq-%u)", member->uid); flag = 0; /* TYPING to put online above OP and FOUNDER */ if (is_online(member->status)) flag |= (PURPLE_CBFLAGS_TYPING | PURPLE_CBFLAGS_VOICE); if(1 == (member->role & 1)) flag |= PURPLE_CBFLAGS_OP; if(member->uid == group->creator_uid) flag |= PURPLE_CBFLAGS_FOUNDER; if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), member_name)) { purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(conv), member_name, flag); } else if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(conv), member_uid)) { purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(conv), member_uid, flag); purple_conv_chat_rename_user(PURPLE_CONV_CHAT(conv), member_uid, member_name); } else { /* always put it even offline */ names = g_list_append(names, member_name); flags = g_list_append(flags, GINT_TO_POINTER(flag)); } g_free(member_uid); list = list->next; } purple_conv_chat_add_users(PURPLE_CONV_CHAT(conv), names, NULL, flags, FALSE); } /* clean up names */ while (names != NULL) { member_name = (gchar *) names->data; names = g_list_remove(names, member_name); g_free(member_name); } g_list_free(flags); }
static void pb_got_everything(PushBulletAccount *pba, JsonNode *node, gpointer user_data) { JsonObject *rootobj = json_node_get_object(node); JsonArray *devices = json_object_has_member(rootobj, "devices") ? json_object_get_array_member(rootobj, "devices") : NULL; JsonArray *pushes = json_object_has_member(rootobj, "pushes") ? json_object_get_array_member(rootobj, "pushes") : NULL; JsonArray *contacts = json_object_has_member(rootobj, "contacts") ? json_object_get_array_member(rootobj, "contacts") : NULL; JsonArray *chats = json_object_has_member(rootobj, "chats") ? json_object_get_array_member(rootobj, "chats") : NULL; JsonArray *texts = json_object_has_member(rootobj, "texts") ? json_object_get_array_member(rootobj, "texts") : NULL; gint i; guint len; PurpleGroup *pbgroup; pbgroup = purple_find_group("PushBullet"); if (!pbgroup) { pbgroup = purple_group_new("PushBullet"); purple_blist_add_group(pbgroup, NULL); } if (json_object_has_member(rootobj, "error")) { JsonObject *error = json_object_get_object_member(rootobj, "error"); const gchar *type = json_object_get_string_member(error, "type"); const gchar *message = json_object_get_string_member(error, "message"); //TODO check type purple_connection_error_reason(pba->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, message); return; } if (devices != NULL) { for(i = 0, len = json_array_get_length(devices); i < len; i++) { JsonObject *device = json_array_get_object_element(devices, i); if (pba->main_sms_device == NULL && json_object_get_boolean_member(device, "has_sms")) { pba->main_sms_device = g_strdup(json_object_get_string_member(device, "iden")); purple_account_set_string(pba->account, "main_sms_device", pba->main_sms_device); pb_get_phonebook(pba, pba->main_sms_device); if (!pba->websocket) { pb_start_polling(pba); } break; //TODO handle more than one } } } if (pushes != NULL) { gint last_message_timestamp = purple_account_get_int(pba->account, "last_message_timestamp", 0); for(i = json_array_get_length(pushes); i > 0; i--) { JsonObject *push = json_array_get_object_element(pushes, i - 1); const gchar *type = json_object_get_string_member(push, "type"); gdouble modified; time_t timestamp; gboolean dismissed; if (!type) continue; modified = json_object_get_double_member(push, "modified"); timestamp = (time_t) modified; dismissed = json_object_get_boolean_member(push, "dismissed"); if (timestamp <= last_message_timestamp || dismissed) { continue; } // {"active":true,"iden":"uffvytgsjApuAUIFRk","created":1.438895081423904e+09,"modified":1.438895081432786e+09,"type":"file","dismissed":false,"guid":"153b70f0-f7a6-4db9-a6f4-28b99fa416f1","direction":"self","sender_iden":"uffvytg","sender_email":"*****@*****.**","sender_email_normalized":"*****@*****.**","sender_name":"Eion Robb","receiver_iden":"uffvytg","receiver_email":"*****@*****.**","receiver_email_normalized":"*****@*****.**","target_device_iden":"uffvytgsjz7O3P0Jl6","source_device_iden":"uffvytgsjAoIRwhIL6","file_name":"IMG_20150807_084618.jpg","file_type":"image/jpeg","file_url":"https://dl.pushbulletusercontent.com/FHOZdyzfvnoYZY0DP6oK1rGKiJpWCPc0/IMG_20150807_084618.jpg","image_width":4128,"image_height":2322,"image_url":"https://lh3.googleusercontent.com/WY5TK7h3mzD32qMcnxtqt-4PrYcWW1uWDHnRW2x1oJK8mnYk2v4HbZrRjIQkiYdxMKQSdNI8GGPqfO6s6tEyuRVLzeA"} if (purple_strequal(type, "note") || purple_strequal(type, "link") || purple_strequal(type, "file")) { const gchar *from = json_object_get_string_member(push, "sender_email_normalized"); const gchar *body = json_object_get_string_member(push, "body"); const gchar *direction = json_object_get_string_member(push, "direction"); gchar *body_html; if (from == NULL) { if (!json_object_has_member(push, "sender_name")) { purple_debug_error("pushbullet", "no sender name/email\n"); continue; } from = json_object_get_string_member(push, "sender_name"); } if (body && *body) { body_html = purple_strdup_withhtml(body); } else { const gchar *title = json_object_get_string_member(push, "title"); if (title && *title) { body_html = purple_strdup_withhtml(title); } else { body_html = "Message"; } } if (json_object_has_member(push, "url")) { gchar *body_with_link = g_strconcat("<a href=\"", json_object_get_string_member(push, "url"), "\">", body_html, "</a>", NULL); g_free(body_html); body_html = body_with_link; } else if (json_object_has_member(push, "image_url")) { const gchar *image_url = json_object_get_string_member(push, "image_url"); PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, pba->account); if (conv == NULL) { conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, pba->account, from); } pb_download_image_to_conv(image_url, conv); } else if (json_object_has_member(push, "file_url")) { gchar *body_with_link; const gchar *file_name = json_object_get_string_member(push, "file_name"); if (file_name && *file_name) { g_free(body_html); body_html = purple_strdup_withhtml(file_name); } body_with_link= g_strconcat("<a href=\"", json_object_get_string_member(push, "file_url"), "\">", json_object_get_string_member(push, "file_name"), "</a>", NULL); g_free(body_html); body_html = body_with_link; } if (direction[0] != 'o') { serv_got_im(pba->pc, from, body_html, PURPLE_MESSAGE_RECV, timestamp); } else { const gchar *guid = json_object_get_string_member(push, "guid"); from = json_object_get_string_member(push, "receiver_email_normalized"); if (!guid || !g_hash_table_remove(pba->sent_messages_hash, guid)) { PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, pba->account); if (conv == NULL) { conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, pba->account, from); } purple_conversation_write(conv, from, body_html, PURPLE_MESSAGE_SEND, timestamp); } } g_free(body_html); } purple_account_set_int(pba->account, "last_message_timestamp", MAX(purple_account_get_int(pba->account, "last_message_timestamp", 0), timestamp)); } } if (contacts != NULL) { for(i = 0, len = json_array_get_length(contacts); i < len; i++) { JsonObject *contact = json_array_get_object_element(contacts, i); const gchar *email = json_object_get_string_member(contact, "email_normalized"); const gchar *name = json_object_get_string_member(contact, "name"); const gchar *image_url = json_object_get_string_member(contact, "image_url"); PurpleBuddy *buddy = purple_find_buddy(pba->account, email); if (buddy == NULL) { buddy = purple_buddy_new(pba->account, email, name); purple_blist_add_buddy(buddy, NULL, pbgroup, NULL); } purple_prpl_got_user_status(pba->account, email, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL); } } if (chats != NULL) { for(i = 0, len = json_array_get_length(chats); i < len; i++) { JsonObject *chat = json_array_get_object_element(chats, i); JsonObject *contact = json_object_get_object_member(chat, "with"); const gchar *email = json_object_get_string_member(contact, "email_normalized"); const gchar *name = json_object_get_string_member(contact, "name"); const gchar *image_url = json_object_get_string_member(contact, "image_url"); PurpleBuddy *buddy = purple_find_buddy(pba->account, email); if (buddy == NULL) { buddy = purple_buddy_new(pba->account, email, name); purple_blist_add_buddy(buddy, NULL, pbgroup, NULL); } purple_prpl_got_user_status(pba->account, email, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL); } } if (texts != NULL) { for(i = 0, len = json_array_get_length(texts); i < len; i++) { JsonObject *text = json_array_get_object_element(texts, i); } } }
static gboolean yahoo_uri_handler(const char *proto, const char *cmd, GHashTable *params) { char *acct_id = g_hash_table_lookup(params, "account"); PurpleAccount *acct; if (g_ascii_strcasecmp(proto, "ymsgr")) return FALSE; acct = find_acct(purple_plugin_get_id(my_protocol), acct_id); if (!acct) return FALSE; /* ymsgr:SendIM?screename&m=The+Message */ if (!g_ascii_strcasecmp(cmd, "SendIM")) { char *sname = NULL; g_hash_table_foreach(params, yahoo_find_uri_novalue_param, &sname); if (sname) { char *message = g_hash_table_lookup(params, "m"); PurpleConversation *conv = purple_find_conversation_with_account( PURPLE_CONV_TYPE_IM, sname, acct); if (conv == NULL) conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, sname); purple_conversation_present(conv); if (message) { /* Spaces are encoded as '+' */ g_strdelimit(message, "+", ' '); purple_conv_send_confirm(conv, message); } } /* else **If pidgindialogs_im() was in the core, we could use it here. * It is all purple_request_* based, but I'm not sure it really belongs in the core pidgindialogs_im(); */ return TRUE; } /* ymsgr:Chat?roomname */ else if (!g_ascii_strcasecmp(cmd, "Chat")) { char *rname = NULL; g_hash_table_foreach(params, yahoo_find_uri_novalue_param, &rname); if (rname) { /* This is somewhat hacky, but the params aren't useful after this command */ g_hash_table_insert(params, g_strdup("room"), g_strdup(rname)); g_hash_table_insert(params, g_strdup("type"), g_strdup("Chat")); serv_join_chat(purple_account_get_connection(acct), params); } /* else ** Same as above (except that this would have to be re-written using purple_request_*) pidgin_blist_joinchat_show(); */ return TRUE; } /* ymsgr:AddFriend?name */ else if (!g_ascii_strcasecmp(cmd, "AddFriend")) { char *name = NULL; g_hash_table_foreach(params, yahoo_find_uri_novalue_param, &name); purple_blist_request_add_buddy(acct, name, NULL, NULL); return TRUE; } return FALSE; }
void purple_buddy_icon_update(PurpleBuddyIcon *icon) { PurpleConversation *conv; PurpleAccount *account; const char *username; PurpleBuddyIcon *icon_to_set; GSList *buddies; g_return_if_fail(icon != NULL); account = purple_buddy_icon_get_account(icon); username = purple_buddy_icon_get_username(icon); /* If no data exists (icon->img == NULL), then call the functions below * with NULL to unset the icon. They will then unref the icon and it should * be destroyed. The only way it wouldn't be destroyed is if someone * else is holding a reference to it, in which case they can kill * the icon when they realize it has no data. */ icon_to_set = icon->img ? icon : NULL; /* Ensure that icon remains valid throughout */ purple_buddy_icon_ref(icon); buddies = purple_find_buddies(account, username); while (buddies != NULL) { PurpleBuddy *buddy = (PurpleBuddy *)buddies->data; char *old_icon; purple_buddy_set_icon(buddy, icon_to_set); old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)buddy, "buddy_icon")); if (icon->img && purple_buddy_icons_is_caching()) { const char *filename = purple_imgstore_get_filename(icon->img); purple_blist_node_set_string((PurpleBlistNode *)buddy, "buddy_icon", filename); if (icon->checksum && *icon->checksum) { purple_blist_node_set_string((PurpleBlistNode *)buddy, "icon_checksum", icon->checksum); } else { purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "icon_checksum"); } ref_filename(filename); } else if (!icon->img) { purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "buddy_icon"); purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "icon_checksum"); } unref_filename(old_icon); g_free(old_icon); buddies = g_slist_delete_link(buddies, buddies); } conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account); if (conv != NULL) purple_conv_im_set_icon(PURPLE_CONV_IM(conv), icon_to_set); /* icon's refcount was incremented above */ purple_buddy_icon_unref(icon); }
void msn_got_rem_user(MsnSession *session, MsnUser *user, MsnListId list_id, int group_id) { PurpleAccount *account; const char *passport; account = session->account; passport = msn_user_get_passport(user); if (list_id == MSN_LIST_FL) { /* TODO: When is the user totally removed? */ if (group_id >= 0) { msn_user_remove_group_id(user, group_id); return; } else { /* session->sync->fl_users_count--; */ } } else if (list_id == MSN_LIST_AL) { purple_privacy_permit_remove(account, passport, TRUE); } else if (list_id == MSN_LIST_BL) { purple_privacy_deny_remove(account, passport, TRUE); } else if (list_id == MSN_LIST_RL) { PurpleConversation *convo; purple_debug_info("msn", "%s has removed you from his or her buddy list.\n", passport); convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, passport, account); if (convo) { PurpleBuddy *buddy; char *msg; buddy = purple_find_buddy(account, passport); msg = g_strdup_printf( _("%s has removed you from his or her buddy list."), buddy ? purple_buddy_get_contact_alias(buddy) : passport); purple_conv_im_write(PURPLE_CONV_IM(convo), passport, msg, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(msg); } } user->list_op &= ~(1 << list_id); /* purple_user_remove_list_id (user, list_id); */ if (user->list_op == 0) { purple_debug_info("msn", "Buddy '%s' shall be deleted?.\n", passport); } }
void fb_got_facepile(FacebookAccount *fba, const gchar *data, gsize data_len, gpointer user_data) { gchar *group = user_data; JsonParser *parser; JsonObject *object, *payload, *user_obj; JsonArray *facepile; PurpleConversation *conv; PurpleConvChat *chat; gchar *uid; guint i; PurpleGroup *pgroup; purple_debug_info("facebook", "got facepile %s\n", data?data:"(null)"); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, group, fba->account); chat = PURPLE_CONV_CHAT(conv); parser = fb_get_parser(data, data_len); if (!parser) { purple_debug_warning("facebook", "could not fetch facepile for group %s\n", group); g_free(group); return; } object = fb_get_json_object(parser, NULL); payload = json_node_get_object( json_object_get_member(object, "payload")); facepile = json_node_get_array( json_object_get_member(payload, "facepile_click_info")); pgroup = purple_find_group(DEFAULT_GROUP_NAME); if (!pgroup) { pgroup = purple_group_new(DEFAULT_GROUP_NAME); purple_blist_add_group(pgroup, NULL); } purple_conv_chat_clear_users(chat); uid = g_strdup_printf("%" G_GINT64_FORMAT, fba->uid); purple_conv_chat_add_user(chat, uid, NULL, PURPLE_CBFLAGS_NONE, FALSE); if (!purple_find_buddy(fba->account, uid)) { PurpleBuddy *buddy = purple_buddy_new(fba->account, uid, "You"); purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE); purple_blist_add_buddy(buddy, NULL, pgroup, NULL); } g_free(uid); for (i = 0; i < json_array_get_length(facepile); i++) { user_obj = json_node_get_object( json_array_get_element(facepile, i)); uid = g_strdup_printf("%" G_GINT64_FORMAT, (gint64)json_node_get_int(json_object_get_member(user_obj, "uid"))); purple_conv_chat_add_user(PURPLE_CONV_CHAT(conv), uid, NULL, PURPLE_CBFLAGS_NONE, FALSE); if (!purple_find_buddy(fba->account, uid)) { const char *alias = json_node_get_string(json_object_get_member(user_obj, "name")); PurpleBuddy *buddy = purple_buddy_new(fba->account, uid, alias); purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE); purple_blist_add_buddy(buddy, NULL, pgroup, NULL); } g_free(uid); } g_free(group); }