// got_invite(from, to, reason, passwd, reply) // This function should be called when receiving an invitation from user // "from", to enter the room "to". Optional reason and room password can // be provided. void got_invite(const char* from, const char *to, const char* reason, const char* passwd, gboolean reply) { GString *sbuf; char *barejid; GSList *room_elt; sbuf = g_string_new(""); if (reason && reason[0]) { g_string_printf(sbuf, "Received an invitation to <%s>, from <%s>, reason: %s", to, from, reason); } else { g_string_printf(sbuf, "Received an invitation to <%s>, from <%s>", to, from); } barejid = jidtodisp(from); scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0); scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str); { // remove any equal older invites GSList *iel = invitations; while (iel) { event_muc_invitation *invitation = iel->data; iel = iel -> next; if (!g_strcmp0(to, invitation->to) && !g_strcmp0(passwd, invitation->passwd)) { // found a previous invitation // We keep the old one, unless the current one is better and allows us // to send a reply. if (!reply || invitation->reply) { g_free(barejid); return; } scr_LogPrint(LPRINT_DEBUG, "Destroying previous invitation event %s.", invitation->evid); evs_del(invitation->evid); } } } { // create event const char *id; char *desc = g_strdup_printf("<%s> invites you to %s", from, to); event_muc_invitation *invitation; invitation = g_new(event_muc_invitation, 1); invitation->to = g_strdup(to); invitation->from = g_strdup(from); invitation->passwd = g_strdup(passwd); invitation->reason = g_strdup(reason); invitation->reply = reply; invitation->evid = NULL; invitations = g_slist_append(invitations, invitation); id = evs_new(desc, NULL, 0, evscallback_invitation, invitation, (GDestroyNotify)destroy_event_muc_invitation); g_free(desc); if (id) { invitation->evid = g_strdup(id); g_string_printf(sbuf, "Please use /event %s accept|reject", id); } else g_string_printf(sbuf, "Unable to create a new event!"); } scr_WriteIncomingMessage(barejid, sbuf->str, 0, HBB_PREFIX_INFO, 0); scr_LogPrint(LPRINT_LOGNORM, "%s", sbuf->str); g_string_free(sbuf, TRUE); g_free(barejid); // Make sure the MUC room barejid is a room in the roster barejid = jidtodisp(to); room_elt = roster_find(barejid, jidsearch, 0); if (room_elt) buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); g_free(barejid); }
static LmHandlerResult cb_ping(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer user_data) { struct timeval *timestamp = (struct timeval *)user_data; struct timeval now; time_t dsec; suseconds_t dusec; const gchar *fjid; gchar *bjid, *mesg = NULL; gettimeofday(&now, NULL); dsec = now.tv_sec - timestamp->tv_sec; if (now.tv_usec < timestamp->tv_usec) { dusec = now.tv_usec + 1000000 - timestamp->tv_usec; --dsec; } else dusec = now.tv_usec - timestamp->tv_usec; // Check IQ result sender fjid = lm_message_get_from(m); if (!fjid) fjid = lm_connection_get_jid(lconnection); // No from means our JID... if (!fjid) { scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:version result (no sender name)."); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } bjid = jidtodisp(fjid); switch (lm_message_get_sub_type(m)) { case LM_MESSAGE_SUB_TYPE_RESULT: mesg = g_strdup_printf("Pong from <%s>: %d second%s %d ms.", fjid, (int)dsec, dsec > 1 ? "s" : "", (int)(dusec/1000L)); break; case LM_MESSAGE_SUB_TYPE_ERROR: display_server_error(lm_message_node_get_child(m->node, "error"), fjid); mesg = g_strdup_printf("Ping to <%s> failed. " "Response time: %d second%s %d ms.", fjid, (int)dsec, dsec > 1 ? "s" : "", (int)(dusec/1000L)); break; default: g_free(bjid); return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; break; } if (mesg) scr_WriteIncomingMessage(bjid, mesg, 0, HBB_PREFIX_INFO, 0); g_free(mesg); g_free(bjid); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
static void storage_bookmarks_parse_conference(LmMessageNode *node) { const char *fjid, *name, *autojoin; const char *pstatus, *awhois, *fjoins, *group; char *bjid; GSList *room_elt; fjid = lm_message_node_get_attribute(node, "jid"); if (!fjid) return; name = lm_message_node_get_attribute(node, "name"); autojoin = lm_message_node_get_attribute(node, "autojoin"); awhois = lm_message_node_get_attribute(node, "autowhois"); pstatus = lm_message_node_get_child_value(node, "print_status"); fjoins = lm_message_node_get_child_value(node, "flag_joins"); group = lm_message_node_get_child_value(node, "group"); bjid = jidtodisp(fjid); // Bare jid // Make sure this is a room (it can be a conversion user->room) room_elt = roster_find(bjid, jidsearch, 0); if (!room_elt) { room_elt = roster_add_user(bjid, name, group, ROSTER_TYPE_ROOM, sub_none, -1); } else { buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); /* // If the name is available, should we use it? // I don't think so, it would be confusing because this item is already // in the roster. if (name) buddy_setname(room_elt->data, name); // The same question for roster group. if (group) buddy_setgroup(room_elt->data, group); */ } // Set the print_status and auto_whois values if (pstatus) { enum room_printstatus i; for (i = status_none; i <= status_all; i++) if (!strcasecmp(pstatus, strprintstatus[i])) break; if (i <= status_all) buddy_setprintstatus(room_elt->data, i); } if (awhois) { enum room_autowhois i = autowhois_default; if (!g_strcmp0(awhois, "1") || !(g_strcmp0(awhois, "true"))) i = autowhois_on; else if (!g_strcmp0(awhois, "0") || !(g_strcmp0(awhois, "false"))) i = autowhois_off; if (i != autowhois_default) buddy_setautowhois(room_elt->data, i); } if (fjoins) { enum room_flagjoins i; for (i = flagjoins_none; i <= flagjoins_all; i++) if (!strcasecmp(fjoins, strflagjoins[i])) break; if (i <= flagjoins_all) buddy_setflagjoins(room_elt->data, i); } // Is autojoin set? // If it is, we'll look up for more information (nick? password?) and // try to join the room. if (autojoin && !g_strcmp0(autojoin, "1")) { const char *nick, *passwd; char *tmpnick = NULL; nick = lm_message_node_get_child_value(node, "nick"); passwd = lm_message_node_get_child_value(node, "password"); if (!nick || !*nick) nick = tmpnick = default_muc_nickname(NULL); // Let's join now scr_LogPrint(LPRINT_LOGNORM, "Auto-join bookmark <%s>", bjid); xmpp_room_join(bjid, nick, passwd); g_free(tmpnick); } g_free(bjid); buddylist_build(); update_roster = TRUE; }
LmHandlerResult handle_iq_roster(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { LmMessageNode *y; const char *fjid, *name, *group, *sub, *ask; char *cleanalias; enum subscr esub; int need_refresh = FALSE; guint roster_type; y = lm_message_node_find_child(lm_message_node_find_xmlns(m->node, NS_ROSTER), "item"); for ( ; y; y = y->next) { char *name_tmp = NULL; fjid = lm_message_node_get_attribute(y, "jid"); name = lm_message_node_get_attribute(y, "name"); sub = lm_message_node_get_attribute(y, "subscription"); ask = lm_message_node_get_attribute(y, "ask"); if (lm_message_node_find_child(y, "group")) group = lm_message_node_get_value(lm_message_node_find_child(y, "group")); else group = NULL; if (!fjid) continue; cleanalias = jidtodisp(fjid); esub = sub_none; if (sub) { if (!strcmp(sub, "to")) esub = sub_to; else if (!strcmp(sub, "from")) esub = sub_from; else if (!strcmp(sub, "both")) esub = sub_both; else if (!strcmp(sub, "remove")) esub = sub_remove; } if (esub == sub_remove) { roster_del_user(cleanalias); scr_LogPrint(LPRINT_LOGNORM, "Buddy <%s> has been removed " "from the roster", cleanalias); g_free(cleanalias); need_refresh = TRUE; continue; } if (ask && !strcmp(ask, "subscribe")) esub |= sub_pending; if (!name) { if (!settings_opt_get_int("roster_hide_domain")) { name = cleanalias; } else { char *p; name = name_tmp = g_strdup(cleanalias); p = strchr(name_tmp, JID_DOMAIN_SEPARATOR); if (p) *p = '\0'; } } // Tricky... :-\ My guess is that if there is no JID_DOMAIN_SEPARATOR, // this is an agent. if (strchr(cleanalias, JID_DOMAIN_SEPARATOR)) roster_type = ROSTER_TYPE_USER; else roster_type = ROSTER_TYPE_AGENT; roster_add_user(cleanalias, name, group, roster_type, esub, 1); g_free(name_tmp); g_free(cleanalias); } // Acknowledge IQ message if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_SET) { LmMessage *result; result = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT); lm_connection_send(c, result, NULL); lm_message_unref(result); } buddylist_build(); update_roster = TRUE; if (need_refresh) scr_update_buddy_window(); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }