Esempio n. 1
0
void yahoo_process_conference_logoff(PurpleConnection *gc, struct yahoo_packet *pkt)
{
	GSList *l;
	char *room = NULL;
	char *who = NULL;
	PurpleConversation *c;

	for (l = pkt->hash; l; l = l->next) {
		struct yahoo_pair *pair = l->data;

		switch (pair->key) {
		case 57:
			g_free(room);
			room = yahoo_string_decode(gc, pair->value, FALSE);
			break;
		case 56:
			who = pair->value;
			break;
		}
	}

	if (who && room) {
		c = yahoo_find_conference(gc, room);
		if (c)
			purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL);
		g_free(room);
	}
}
Esempio n. 2
0
void yahoo_process_chat_exit(PurpleConnection *gc, struct yahoo_packet *pkt)
{
	char *who = NULL;
	char *room = NULL;
	GSList *l;

	for (l = pkt->hash; l; l = l->next) {
		struct yahoo_pair *pair = l->data;

		if (pair->key == 104) {
			g_free(room);
			room = yahoo_string_decode(gc, pair->value, TRUE);
		}
		if (pair->key == 109)
			who = pair->value;
	}

	if (who && room) {
		PurpleConversation *c = purple_find_chat(gc, YAHOO_CHAT_ID);
		if (c && !purple_utf8_strcasecmp(purple_conversation_get_name(c), room))
			purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL);

	}
	g_free(room);
}
Esempio n. 3
0
void irc_msg_kick(struct irc_conn *irc, const char *name, const char *from, char **args)
{
	PurpleConnection *gc = purple_account_get_connection(irc->account);
	PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[0], irc->account);
	char *nick = irc_mask_nick(from), *buf;

	if (!gc) {
		g_free(nick);
		return;
	}

	if (!convo) {
		purple_debug(PURPLE_DEBUG_ERROR, "irc", "Recieved a KICK for unknown channel %s\n", args[0]);
		g_free(nick);
		return;
	}

	if (!purple_utf8_strcasecmp(purple_connection_get_display_name(gc), args[1])) {
		buf = g_strdup_printf(_("You have been kicked by %s: (%s)"), nick, args[2]);
		purple_conv_chat_write(PURPLE_CONV_CHAT(convo), args[0], buf, PURPLE_MESSAGE_SYSTEM, time(NULL));
		g_free(buf);
		serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
	} else {
		buf = g_strdup_printf(_("Kicked by %s (%s)"), nick, args[2]);
		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), args[1], buf);
		g_free(buf);
	}

	g_free(nick);
	return;
}
Esempio n. 4
0
static void irc_chat_remove_buddy(PurpleConversation *convo, char *data[2])
{
	char *message, *stripped;

	stripped = data[1] ? irc_mirc2txt(data[1]) : NULL;
	message = g_strdup_printf("quit: %s", stripped);
	g_free(stripped);

	if (purple_conv_chat_find_user(PURPLE_CONV_CHAT(convo), data[0]))
		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), data[0], message);

	g_free(message);
}
Esempio n. 5
0
/*------------------------------------------------------------------------
 * Another user has left the GroupChat, remove them from the member-list.
 *
 *  @param session		The MXit session object
 *  @param multimx		The MultiMX room object
 *  @param nickname		The nickname of the user who left the room
 */
static void member_removed(struct MXitSession* session, struct multimx* multimx, const char* nickname)
{
	PurpleConversation *convo;

	purple_debug_info(MXIT_PLUGIN_ID, "member_removed: '%s'\n", nickname);

	convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc);
	if (convo == NULL) {
		purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
		return;
	}

	purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nickname, NULL);
}
Esempio n. 6
0
void hon_parse_chat_leave(PurpleConnection *gc,gchar* buffer){
    hon_account* hon = gc->proto_data;
    guint32 account_id;
    guint32 chan_id;
    gchar* nick;
    PurpleConversation* conv;
    account_id = read_guint32(buffer);
    chan_id = read_guint32(buffer);
    nick = g_hash_table_lookup(hon->id2nick,GINT_TO_POINTER(account_id));
    conv = purple_find_chat(gc,chan_id);
    if (conv && nick)
    {
        purple_conv_chat_remove_user(PURPLE_CONV_CHAT(conv),nick,"");
    }
    if (account_id == hon->self.account_id)
        serv_got_chat_left(gc, chan_id);
}
Esempio n. 7
0
static void
bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
	MsnSwitchBoard *swboard;
	const char *user;

	swboard = cmdproc->data;
	user = cmd->params[0];

	/* cmdproc->data is set to NULL when the switchboard is destroyed;
	 * we may get a bye shortly thereafter. */
	g_return_if_fail(swboard != NULL);

	if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL))
		purple_debug_error("msn", "bye_cmd: helper bug\n");

	if (swboard->conv == NULL)
	{
		/* This is a helper switchboard */
		msn_switchboard_destroy(swboard);
	}
	else if ((swboard->current_users > 1) ||
			 (purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
	{
		GList *passport;
		/* This is a switchboard used for a chat */
		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(swboard->conv), user, NULL);

		passport = g_list_find_custom(swboard->users, user, (GCompareFunc)strcmp);
		if (passport)
			g_free(passport->data);
		else
			purple_debug_warning("msn", "Can't find user %s in the switchboard\n", user);
		swboard->users = g_list_delete_link(swboard->users, passport);
		swboard->current_users--;
		if (swboard->current_users == 0)
			msn_switchboard_destroy(swboard);
	}
	else
	{
		/* This is a switchboard used for a im session */
		msn_switchboard_destroy(swboard);
	}
}
Esempio n. 8
0
bool PurpleIMChat::removeContactCbk(void * dataIn)
{
	Mutex::ScopedLock lock(PurpleIMChat::_mutex);

	PurpleIMChatCallbackData* cbData = (PurpleIMChatCallbackData*) dataIn;

	IMChatSession* chatSession = cbData->getIMChatSession();
//	const char * contactId = (const char *)((misc_t *)data)->data_ptr2;
	mConvInfo_t *mConv = FindChatStructById(chatSession->getId());
	PurpleConvChat *conv = PURPLE_CONV_CHAT( mConv->purple_conv_session );	//VOXOX - JRT - 2009.07.09 

	purple_conv_chat_remove_user(conv, cbData->getContactId().c_str(), NULL);

	timeoutRemove( cbData );

	delete cbData;

	return TRUE;
}
Esempio n. 9
0
/*------------------------------------------------------------------------
 * A user was kicked from the GroupChat.
 *
 *  @param session		The MXit session object
 *  @param multimx		The MultiMX room object
 *  @param nickname		The nickname of the user who was kicked
 */
static void member_kicked(struct MXitSession* session, struct multimx* multimx, const char* nickname)
{
	PurpleConversation *convo;

	purple_debug_info(MXIT_PLUGIN_ID, "member_kicked: '%s'\n", nickname);

	convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc);
	if (convo == NULL) {
		purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
		return;
	}

	/* who was kicked? - compare to our original nickname */
	if (purple_utf8_strcasecmp(nickname, multimx->nickname) == 0)
	{
		/* you were kicked */
		purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "MXit", _("You have been kicked from this MultiMX."), PURPLE_MESSAGE_SYSTEM, time(NULL));
		purple_conv_chat_clear_users(PURPLE_CONV_CHAT(convo));
		serv_got_chat_left(session->con, multimx->chatid);
	}
	else
		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nickname, _("was kicked"));
}
Esempio n. 10
0
static void
bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
	MsnSwitchBoard *swboard;
	const char *user;

	swboard = cmdproc->data;
	user = cmd->params[0];

	/* cmdproc->data is set to NULL when the switchboard is destroyed;
	 * we may get a bye shortly thereafter. */
	g_return_if_fail(swboard != NULL);

	if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL))
		purple_debug_error("msn", "bye_cmd: helper bug\n");

	if (swboard->conv == NULL)
	{
		/* This is a helper switchboard */
		msn_switchboard_destroy(swboard);
	}
	else if ((swboard->current_users > 1) ||
			 (purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
	{
		/* This is a switchboard used for a chat */
		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(swboard->conv), user, NULL);
		swboard->current_users--;
		if (swboard->current_users == 0)
			msn_switchboard_destroy(swboard);
	}
	else
	{
		/* This is a switchboard used for a im session */
		msn_switchboard_destroy(swboard);
	}
}
Esempio n. 11
0
void irc_msg_part(struct irc_conn *irc, const char *name, const char *from, char **args)
{
	PurpleConnection *gc = purple_account_get_connection(irc->account);
	PurpleConversation *convo;
	char *nick, *msg, *channel;

	if (!args || !args[0] || !gc)
		return;

	/* Undernet likes to :-quote the channel name, for no good reason
	 * that I can see.  This catches that. */
	channel = (args[0][0] == ':') ? &args[0][1] : args[0];

	convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, channel, irc->account);
	if (!convo) {
		purple_debug(PURPLE_DEBUG_INFO, "irc", "Got a PART on %s, which doesn't exist -- probably closed\n", channel);
		return;
	}

	nick = irc_mask_nick(from);
	if (!purple_utf8_strcasecmp(nick, purple_connection_get_display_name(gc))) {
		char *escaped = g_markup_escape_text(args[1], -1);
		msg = g_strdup_printf(_("You have parted the channel%s%s"),
		                      (args[1] && *args[1]) ? ": " : "",
		                      (escaped && *escaped) ? escaped : "");
		g_free(escaped);
		purple_conv_chat_write(PURPLE_CONV_CHAT(convo), channel, msg, PURPLE_MESSAGE_SYSTEM, time(NULL));
		g_free(msg);
		serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)));
	} else {
		msg = args[1] ? irc_mirc2txt(args[1]) : NULL;
		purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nick, msg);
		g_free(msg);
	}
	g_free(nick);
}
Esempio n. 12
0
static void
nap_callback(gpointer data, gint source, PurpleInputCondition condition) {
    PurpleConnection *gc = data;
    struct nap_data *ndata = gc->proto_data;
    PurpleAccount *account = NULL;
    PurpleConversation *c = NULL;
    PurpleNotifyUserInfo *pnui = NULL;
    gchar *buf = NULL, *buf2 = NULL, *buf3 = NULL, **res = NULL;
    unsigned short header[2] = { 0 , 0 };
    int len = 0;
    int command = 0;
    int i;

    account = purple_connection_get_account(gc);

    if (read(source, (void*)header, 4) != 4) {
        purple_connection_error(gc, _("Unable to read header from server"));
        return;
    }

    len = header[0];
    command = header[1];
    buf = (gchar *)g_malloc((len + 1) * sizeof(gchar));
    buf[len] = '\0';

    i = 0;
    do {
        int tmp = read(source, buf + i, len - i);
        if (tmp <= 0) {
            g_free(buf);
            buf = g_strdup_printf(_("Unable to read message from server: %s.  Command is %hd, length is %hd."), strerror(errno), len, command);
            purple_connection_error(gc, buf);
            g_free(buf);
            return;
        }
        i += tmp;
    } while (i != len);

    purple_debug(PURPLE_DEBUG_MISC, "napster", "R %3hd: %s\n", command, buf);

    switch (command) {
    case 000: /* MSG_SERVER_ERROR */
        purple_notify_error(gc, NULL, buf, NULL);
        purple_input_remove(gc->inpa);
        gc->inpa = 0;
        close(source);
        purple_connection_error(gc, _("Unknown server error."));
        break;

    case 003: /* MSG_SERVER_EMAIL */
        purple_debug(PURPLE_DEBUG_MISC, "napster", "Registered with e-mail address: %s\n", buf);
        ndata->email = g_strdup(buf);

        /* Our signon is complete */
        purple_connection_set_state(gc, PURPLE_CONNECTED);

        /* Send the server our buddy list */
        nap_send_buddylist(gc);

        break;

    case 201: /* MSG_SERVER_SEARCH_RESULT */
        res = g_strsplit(buf, " ", 0);
        purple_prpl_got_user_status(account, res[0], "available", NULL);
        g_strfreev(res);
        break;

    case 202: /* MSG_SERVER_SEARCH_END */
        purple_prpl_got_user_status(account, buf, "offline", NULL);
        break;

    case 205: /* MSG_CLIENT_PRIVMSG */
        res = g_strsplit(buf, " ", 2);
        buf2 = g_markup_escape_text(res[1], -1);
        serv_got_im(gc, res[0], buf2, 0, time(NULL));
        g_free(buf2);
        g_strfreev(res);
        break;

    case 209: /* MSG_SERVER_USER_SIGNON */
        /* USERNAME SPEED */
        res = g_strsplit(buf, " ", 2);
        purple_prpl_got_user_status(account, res[0], "available", NULL);
        g_strfreev(res);
        break;

    case 210: /* MSG_SERVER_USER_SIGNOFF */
        /* USERNAME SPEED */
        res = g_strsplit(buf, " ", 2);
        purple_prpl_got_user_status(account, res[0], "offline", NULL);
        g_strfreev(res);
        break;

    case 214: /* MSG_SERVER_STATS */
        res = g_strsplit(buf, " ", 3);
        buf2 = g_strdup_printf(_("users: %s, files: %s, size: %sGB"), res[0], res[1], res[2]);
        serv_got_im(gc, "server", buf2, 0, time(NULL));
        g_free(buf2);
        g_strfreev(res);
        break;

    case 301: /* MSG_SERVER_HOTLIST_ACK */
        /* Our buddy was added successfully */
        break;

    case 302: /* MSG_SERVER_HOTLIST_ERROR */
        buf2 = g_strdup_printf(_("Unable to add \"%s\" to your Napster hotlist"), buf);
        purple_notify_error(gc, NULL, buf2, NULL);
        g_free(buf2);
        break;

    case 316: /* MSG_SERVER_DISCONNECTING */
        /* we have been kicked off =^( */
        purple_connection_error(gc, _("You were disconnected from the server."));
        break;

    case 401: /* MSG_CLIENT_PART */
        c = nap_find_chat(gc, buf);
        if (c)
            serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)));
        break;

    case 403: /* MSG_SERVER_PUBLIC */
        res = g_strsplit(buf, " ", 3);
        c = nap_find_chat(gc, res[0]);
        if (c)
            serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), res[1], 0, res[2], time((time_t)NULL));
        g_strfreev(res);
        break;

    case 404: /* MSG_SERVER_NOSUCH */
        /* abused by opennap servers to broadcast stuff */
        buf2 = g_markup_escape_text(buf, -1);
        serv_got_im(gc, "server", buf2, 0, time(NULL));
        g_free(buf2);
        break;

    case 405: /* MSG_SERVER_JOIN_ACK */
        c = nap_find_chat(gc, buf);
        if (!c)
            serv_got_joined_chat(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), buf);
        break;

    case 407: /* MSG_SERVER_PART */
        res = g_strsplit(buf, " ", 0);
        c = nap_find_chat(gc, res[0]);
        purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), res[1], NULL);
        g_strfreev(res);
        break;

    case 406: /* MSG_SERVER_JOIN */
    case 408: /* MSG_SERVER_CHANNEL_USER_LIST */
        res = g_strsplit(buf, " ", 4);
        c = nap_find_chat(gc, res[0]);
        purple_conv_chat_add_user(PURPLE_CONV_CHAT(c), res[1], NULL, PURPLE_CBFLAGS_NONE, TRUE);
        g_strfreev(res);
        break;

    case 409: /* MSG_SERVER_CHANNEL_USER_LIST_END */
        break;

    case 410: /* MSG_SERVER_TOPIC */
        /* display the topic in the channel */
        res = g_strsplit(buf, " ", 2);
        c = nap_find_chat(gc, res[0]);
        purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), res[0], res[1]);
        g_strfreev(res);
        break;

    case 603: /* MSG_CLIENT_WHOIS */
        buf2 = g_strdup_printf(_("%s requested your information"), buf);
        serv_got_im(gc, "server", buf2, 0, time(NULL));
        g_free(buf2);
        break;

    case 604: /* MSG_SERVER_WHOIS_RESPONSE */
        /* XXX - Format is:   "Elite" 37 " " "Active" 0 0 0 0 "purple 0.63cvs" 0 0 192.168.1.41 32798 0 unknown flounder */
        res = g_strsplit(buf, " ", 2);
        /* res[0] == username */
        pnui = purple_notify_user_info_new();
        purple_notify_user_info_add_pair(pnui, _("Napster User Info:"), res[1]);
        purple_notify_userinfo(gc, res[0], pnui, NULL, NULL);
        g_strfreev(res);
        break;

    case 621:
    case 622: /* MSG_CLIENT_MOTD */
        /* also replaces MSG_SERVER_MOTD, so we should display it */
        buf2 = g_markup_escape_text(buf, -1);
        serv_got_im(gc, "motd", buf2, 0, time(NULL));
        g_free(buf2);
        break;

    case 627: /* MSG_CLIENT_WALLOP */
        /* abused by opennap server maintainers to broadcast stuff */
        buf2 = g_markup_escape_text(buf, -1);
        serv_got_im(gc, "wallop", buf2, 0, time(NULL));
        g_free(buf2);
        break;

    case 628: /* MSG_CLIENT_ANNOUNCE */
        buf2 = g_markup_escape_text(buf, -1);
        serv_got_im(gc, "announce", buf2, 0, time(NULL));
        g_free(buf);
        break;

    case 748: /* MSG_SERVER_GHOST */
        /* Looks like someone logged in as us! =-O */
        purple_connection_error(gc, _("You have signed on from another location."));
        break;

    case 751: /* MSG_CLIENT_PING */
        buf2 = g_strdup_printf(_("%s requested a PING"), buf);
        serv_got_im(gc, "server", buf2, 0, time(NULL));
        g_free(buf2);
        /* send back a pong */
        /* MSG_CLIENT_PONG */
        nap_write_packet(gc, 752, "%s", buf);
        break;

    case 752: /* MSG_CLIENT_PONG */
        buf2 = g_strdup_printf("Received pong from %s", buf);
        purple_notify_info(gc, NULL, buf2, NULL);
        g_free(buf2);
        break;

    case 824: /* MSG_CLIENT_EMOTE */
        res = g_strsplit(buf, " ", 3);
        buf2 = g_strndup(res[2]+1, strlen(res[2]) - 2); /* chomp off the surround quotes */
        buf3 = g_strdup_printf("/me %s", buf2);
        g_free(buf2);
        if ((c = nap_find_chat(gc, res[0]))) {
            purple_conv_chat_write(PURPLE_CONV_CHAT(c), res[1], buf3, PURPLE_MESSAGE_NICK, time(NULL));
        }
        g_free(buf3);
        g_strfreev(res);
        break;

    default:
        purple_debug(PURPLE_DEBUG_MISC, "napster", "Unknown packet %hd: %s\n", command, buf);
        break;
    }

    g_free(buf);
}
Esempio n. 13
0
static gboolean
handle_presence_chat(JabberStream *js, JabberPresence *presence, xmlnode *packet)
{
	static int i = 1;
	PurpleConvChatBuddyFlags flags = PURPLE_CBFLAGS_NONE;
	JabberChat *chat = presence->chat;

	if (presence->state == JABBER_BUDDY_STATE_ERROR) {
		char *title, *msg = jabber_parse_error(js, packet, NULL);

		if (!chat->conv) {
			title = g_strdup_printf(_("Error joining chat %s"), presence->from);
			purple_serv_got_join_chat_failed(js->gc, chat->components);
		} else {
			title = g_strdup_printf(_("Error in chat %s"), presence->from);
			if (g_hash_table_size(chat->members) == 0)
				serv_got_chat_left(js->gc, chat->id);
		}
		purple_notify_error(js->gc, title, title, msg);
		g_free(title);
		g_free(msg);

		if (g_hash_table_size(chat->members) == 0)
			/* Only destroy the chat if the error happened while joining */
			jabber_chat_destroy(chat);
		return FALSE;
	}

	if (presence->type == JABBER_PRESENCE_AVAILABLE) {
		const char *jid = NULL;
		const char *affiliation = NULL;
		const char *role = NULL;
		gboolean is_our_resource = FALSE; /* Is the presence about us? */
		JabberBuddyResource *jbr;

		/*
		 * XEP-0045 mandates the presence to include a resource (which is
		 * treated as the chat nick). Some non-compliant servers allow
		 * joining without a nick.
		 */
		if (!presence->jid_from->resource)
			return FALSE;

		if (presence->chat_info.item) {
			jid = xmlnode_get_attrib(presence->chat_info.item, "jid");
			affiliation = xmlnode_get_attrib(presence->chat_info.item, "affiliation");
			role = xmlnode_get_attrib(presence->chat_info.item, "role");
		}

		if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(110)) ||
				g_str_equal(presence->jid_from->resource, chat->handle) ||
				purple_strequal(presence->to, jid))
			is_our_resource = TRUE;

		if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(201))) {
			chat->config_dialog_type = PURPLE_REQUEST_ACTION;
			chat->config_dialog_handle =
				purple_request_action(js->gc,
						_("Create New Room"),
						_("Create New Room"),
						_("You are creating a new room.  Would"
							" you like to configure it, or"
							" accept the default settings?"),
						/* Default Action */ 1,
						purple_connection_get_account(js->gc), NULL, chat->conv,
						chat, 2,
						_("_Configure Room"), G_CALLBACK(jabber_chat_request_room_configure),
						_("_Accept Defaults"), G_CALLBACK(jabber_chat_create_instant_room));
		}

		if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(210))) {
			/* server rewrote room-nick */
			g_free(chat->handle);
			chat->handle = g_strdup(presence->jid_from->resource);
		}

		if (purple_strequal(affiliation, "owner"))
			flags |= PURPLE_CBFLAGS_FOUNDER;
		if (role) {
			if (g_str_equal(role, "moderator"))
				flags |= PURPLE_CBFLAGS_OP;
			else if (g_str_equal(role, "participant"))
				flags |= PURPLE_CBFLAGS_VOICE;
		}

		if(!chat->conv) {
			char *room_jid = g_strdup_printf("%s@%s", presence->jid_from->node, presence->jid_from->domain);
			chat->id = i++;
			chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid);
			purple_conv_chat_set_nick(PURPLE_CONV_CHAT(chat->conv), chat->handle);

			jabber_chat_disco_traffic(chat);
			g_free(room_jid);
		}

		jbr = jabber_buddy_track_resource(presence->jb, presence->jid_from->resource, presence->priority, presence->state, presence->status);
		jbr->commands_fetched = TRUE;

		jabber_chat_track_handle(chat, presence->jid_from->resource, jid, affiliation, role);

		if(!jabber_chat_find_buddy(chat->conv, presence->jid_from->resource))
			purple_conv_chat_add_user(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
					jid, flags, chat->joined > 0 && ((!presence->delayed) || (presence->sent > chat->joined)));
		else
			purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
					flags);

		if (is_our_resource && chat->joined == 0)
			chat->joined = time(NULL);

	} else if (presence->type == JABBER_PRESENCE_UNAVAILABLE) {
		gboolean nick_change = FALSE;
		gboolean kick = FALSE;
		gboolean is_our_resource = FALSE; /* Is the presence about us? */

		const char *jid = NULL;

		/* If the chat nick is invalid, we haven't yet joined, or we've
		 * already left (it was probably us leaving after we closed the
		 * chat), we don't care.
		 */
		if (!presence->jid_from->resource || !chat->conv || chat->left) {
			if (chat->left &&
					presence->jid_from->resource && chat->handle && !strcmp(presence->jid_from->resource, chat->handle))
				jabber_chat_destroy(chat);
			return FALSE;
		}

		is_our_resource = g_str_equal(presence->jid_from->resource, chat->handle);

		jabber_buddy_remove_resource(presence->jb, presence->jid_from->resource);

		if (presence->chat_info.item)
			jid = xmlnode_get_attrib(presence->chat_info.item, "jid");

		if (chat->muc) {
			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(110))) {
				is_our_resource = TRUE;
				chat->joined = 0;
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(301))) {
				/* XXX: We got banned.  YAY! (No GIR, that's bad) */
			}


			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(303))) {
				const char *nick = NULL;
				if (presence->chat_info.item)
					nick = xmlnode_get_attrib(presence->chat_info.item, "nick");

				/* nick change */
				if (!nick) {
					purple_debug_warning("jabber", "Chat presence indicating a nick change, but no new nickname!\n");
				} else {
					nick_change = TRUE;

					if (g_str_equal(presence->jid_from->resource, chat->handle)) {
						/* Changing our own nickname */
						g_free(chat->handle);
						/* TODO: This should be resourceprep'd */
						chat->handle = g_strdup(nick);
					}

					purple_conv_chat_rename_user(PURPLE_CONV_CHAT(chat->conv),
					                             presence->jid_from->resource,
					                             nick);
					jabber_chat_remove_handle(chat,
					                          presence->jid_from->resource);
				}
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(307))) {
				/* Someone was kicked from the room */
				const char *actor = NULL;
				char *reason = NULL;
				char *tmp;

				kick = TRUE;

				if (presence->chat_info.item) {
					xmlnode *node;

					node = xmlnode_get_child(presence->chat_info.item, "actor");
					if (node)
						actor = xmlnode_get_attrib(node, "jid");
					node = xmlnode_get_child(presence->chat_info.item, "reason");
					if (node)
						reason = xmlnode_get_data(node);
				}

				if (reason == NULL)
					reason = g_strdup(_("No reason"));

				if (is_our_resource) {
					if (actor)
						tmp = g_strdup_printf(_("You have been kicked by %s: (%s)"),
								actor, reason);
					else
						tmp = g_strdup_printf(_("You have been kicked: (%s)"),
								reason);
				} else {
					if (actor)
						tmp = g_strdup_printf(_("Kicked by %s (%s)"),
								actor, reason);
					else
						tmp = g_strdup_printf(_("Kicked (%s)"),
								reason);
				}

				g_free(presence->status);
				presence->status = tmp;

				g_free(reason);
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(321))) {
				/* XXX: removed due to an affiliation change */
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(322))) {
				/* XXX: removed because room is now members-only */
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(332))) {
				/* XXX: removed due to system shutdown */
			}
		}

		/*
		 * Possibly another connected resource of our JID (see XEP-0045
		 * v1.24 section 7.1.10) being disconnected. Should be
		 * distinguished by the item_jid.
		 * Also possibly works around bits of an Openfire bug. See
		 * #8319.
		 */
		if (is_our_resource && jid && !purple_strequal(presence->to, jid)) {
			/* TODO: When the above is a loop, this needs to still act
			 * sanely for all cases (this code is a little fragile). */
			if (!kick && !nick_change)
				/* Presumably, kicks and nick changes also affect us. */
				is_our_resource = FALSE;
		}

		if(!nick_change) {
			if (is_our_resource) {
				if (kick)
					purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
							presence->status, PURPLE_MESSAGE_SYSTEM, time(NULL));

				serv_got_chat_left(js->gc, chat->id);
				jabber_chat_destroy(chat);
			} else {
				purple_conv_chat_remove_user(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
						presence->status);
				jabber_chat_remove_handle(chat, presence->jid_from->resource);
			}
		}
	}

	return TRUE;
}
Esempio n. 14
0
static char *format_service_msg (struct tgl_state *TLS, struct tgl_message *M) {
  g_return_val_if_fail(M && M->flags & TGLMF_SERVICE, NULL);

  connection_data *conn = TLS->ev_base;
  char *txt = NULL;
  
  tgl_peer_t *fromPeer = tgl_peer_get (TLS, M->from_id);
  g_return_val_if_fail(fromPeer != NULL, NULL);
  
  const char *txt_user = fromPeer->print_name;

  switch (M->action.type) {
    case tgl_message_action_chat_create:
      txt = g_strdup_printf (_("%2$s created chat %1$s."), M->action.title, txt_user);
      break;
    case tgl_message_action_chat_edit_title:
      txt = g_strdup_printf (_("%2$s changed title to %1$s."), M->action.new_title, txt_user);
      break;
    case tgl_message_action_chat_edit_photo:
      txt = g_strdup_printf (_("%s changed photo."), txt_user);
      break;
    case tgl_message_action_chat_delete_photo:
      txt = g_strdup_printf (_("%s deleted photo."), txt_user);
      break;
    case tgl_message_action_chat_add_user_by_link: {
      tgl_peer_t *actionPeer = tgl_peer_get (TLS, TGL_MK_USER (M->action.user));
      if (actionPeer) {
        char *alias = actionPeer->print_name;
        
        PurpleConversation *conv = purple_find_chat (conn->gc, tgl_get_peer_id (M->to_id));
        txt = g_strdup_printf (_("%1$s added user %2$s by link."), alias, txt_user);
        if (conv) {
          p2tgl_conv_add_user (TLS, conv, tgl_get_peer_id (fromPeer->id), NULL, 0, FALSE);
        }

        return txt;
      }
      break;
    }
    case tgl_message_action_chat_add_user: {
      tgl_peer_t *peer = tgl_peer_get (TLS, TGL_MK_USER (M->action.user));
      if (peer) {
        char *alias = peer->print_name;
        txt = g_strdup_printf (_("%2$s added user %1$s."), alias, txt_user);
        PurpleConversation *conv = purple_find_chat (conn->gc, tgl_get_peer_id (M->to_id));
        if (conv) {
          p2tgl_conv_add_user (TLS, conv, M->action.user, NULL, 0, FALSE);
        }
      }
      break;
    }
    case tgl_message_action_chat_delete_user: {
      tgl_peer_t *peer = tgl_peer_get (TLS, TGL_MK_USER (M->action.user));
      if (peer) {

        tgl_peer_t *chatPeer = tgl_peer_get (TLS, M->to_id);
        g_return_val_if_fail(tgl_get_peer_type (chatPeer->id) == TGL_PEER_CHAT, NULL);
        
        // make sure that the chat is showing before deleting the user, otherwise the chat will be
        // initialised after removing the chat and the chat will still contain the deleted user
        PurpleConversation *conv = tgp_chat_show (TLS, &chatPeer->chat);
        if (conv) {
          char *alias = peer->print_name;
          const char *aliasLeft = tgp_blist_lookup_purple_name (TLS, TGL_MK_USER (M->action.user));

          if (tgl_get_peer_id (M->from_id) != tgl_get_peer_id (peer->id)) {
            txt = g_strdup_printf (_("%2$s deleted user %1$s."), alias, txt_user);
          }
          g_return_val_if_fail (aliasLeft, NULL);

          purple_conv_chat_remove_user (purple_conversation_get_chat_data (conv), aliasLeft, txt);
          if (M->action.user == tgl_get_peer_id (TLS->our_id)) {
            purple_conv_chat_left (purple_conversation_get_chat_data (conv));
          }
          
          // conv_del_user already printed a message, prevent a redundant message
          // from being printed by returning NULL
          g_free (txt);
          return NULL;
        }
        
        char *alias = peer->print_name;
        if (tgl_get_peer_id (M->from_id) != tgl_get_peer_id (peer->id)) {
          txt = g_strdup_printf (_("%2$s deleted user %1$s."), alias, txt_user);
        }
      }
      break;
    }
    case tgl_message_action_set_message_ttl:

      txt = g_strdup_printf (P_("%2$s set self destruction timer to %1$d second.",
                                "%2$s set self destruction timer to %1$d seconds.",
                                M->action.ttl),
                             M->action.ttl, txt_user);
      break;
    case tgl_message_action_read_messages:
      txt = g_strdup_printf (P_("%2$s marked %1$d message read.",
                                "%2$s marked %1$d messages read.",
                                M->action.read_cnt),
                             M->action.read_cnt, txt_user);
      break;
    case tgl_message_action_delete_messages:
      txt = g_strdup_printf (P_("%2$s deleted %1$d message.",
                                "%2$s deleted %1$d messages.",
                                M->action.delete_cnt),
                             M->action.delete_cnt, txt_user);
      break;
    case tgl_message_action_screenshot_messages:
      txt = g_strdup_printf (P_("%2$s made a screenshot of %1$d message.",
                                "%2$s made a screenshot of %1$d messages.",
                                M->action.screenshot_cnt),
                             M->action.screenshot_cnt, txt_user);
      break;
    default:
      g_warn_if_reached();
      break;
  }
  return txt;
}
Esempio n. 15
0
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);
}