// muc_get_item_info(...) // Get room member's information from xmlndata. // The variables must be initialized before calling this function, // because they are not touched if the relevant information is missing. // Note that *actor should be freed by the caller. static void muc_get_item_info(const char *from, LmMessageNode *xmldata, enum imrole *mbrole, enum imaffiliation *mbaffil, const char **mbjid, const char **mbnick, char **actor, const char **reason) { LmMessageNode *y, *z; const char *p, *actorjid, *actornick; y = lm_message_node_find_child(xmldata, "item"); if (!y) return; p = lm_message_node_get_attribute(y, "affiliation"); if (p) { if (!strcmp(p, "owner")) *mbaffil = affil_owner; else if (!strcmp(p, "admin")) *mbaffil = affil_admin; else if (!strcmp(p, "member")) *mbaffil = affil_member; else if (!strcmp(p, "outcast")) *mbaffil = affil_outcast; else if (!strcmp(p, "none")) *mbaffil = affil_none; else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"", from, p); } p = lm_message_node_get_attribute(y, "role"); if (p) { if (!strcmp(p, "moderator")) *mbrole = role_moderator; else if (!strcmp(p, "participant")) *mbrole = role_participant; else if (!strcmp(p, "visitor")) *mbrole = role_visitor; else if (!strcmp(p, "none")) *mbrole = role_none; else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"", from, p); } *mbjid = lm_message_node_get_attribute(y, "jid"); *mbnick = lm_message_node_get_attribute(y, "nick"); // For kick/ban, there can be actor and reason tags z = lm_message_node_find_child(y, "actor"); if (z) { actornick = lm_message_node_get_attribute(z, "nick"); actorjid = lm_message_node_get_attribute(z, "jid"); if (actorjid) { if (actornick) { // We have both the actor's jid and nick *actor = g_strdup_printf("%s <%s>", actornick, actorjid); } else { *actor = g_strdup(actorjid); // jid only } } else if (!actorjid && actornick) { // We only have the nickname *actor = g_strdup(actornick); } } *reason = lm_message_node_get_child_value(y, "reason"); if (*reason && !**reason) *reason = NULL; }
void LM::Presentity::push_presence (const std::string resource, LmMessageNode* presence) { if (resource.empty ()) return; ResourceInfo info; LmMessageNode* priority = lm_message_node_find_child (presence, "priority"); if (priority != NULL) { info.priority = atoi (lm_message_node_get_value (priority)); } else { info.priority = 50; } LmMessageNode* status = lm_message_node_find_child (presence, "status"); if (status != NULL) { const gchar* status_str = lm_message_node_get_value (status); if (status_str != NULL) info.status = status_str; } LmMessageNode* away = lm_message_node_find_child (presence, "show"); if (away != NULL) { info.presence = lm_message_node_get_value (away); } else { info.presence = "available"; } const gchar* oftype = lm_message_node_get_attribute (presence, "type"); if (oftype != NULL) { if (oftype == std::string ("unavailable")) { info.presence = "unavailable"; } } infos[resource] = info; if (info.presence == "unavailable") { infos.erase (resource); } updated (); }
static void handle_event(LmMessage* message) { LmMessageNode *child = NULL; XML_Parser p; char *buf = NULL; const char *new_node = NULL; int ret; #ifdef DB_DEBUG printf("message:%s\n",lm_message_node_to_string(message->node)); #endif //If message is a DeviceCreation message, subscribe to new event node child = lm_message_node_find_child(message->node,"Created"); if(child != NULL) { new_node = lm_message_node_get_attribute(child,"name"); #ifdef DB_DEBUG printf("Got DeviceCreation message for '%s'\n",new_node); #endif g_print("Got DeviceCreation message for '%s'\n",new_node); if((ret = subscribe_to_node(xmpp_connection,new_node)) != XMPP_NO_ERROR) printf("Could not subscribe to event node '%s'\n",new_node); return; } //Look for SensorNode in message, and invoke parser to update database entries child = lm_message_node_find_child(message->node,"Device"); if(child == NULL) { return; } buf = lm_message_node_to_string(child); p = XML_ParserCreate(NULL); if(!p) { printf("Couldnt allocate memory for XML Parser\n"); return; } XML_SetElementHandler(p,startElement,endElement); if(XML_Parse(p,buf,strlen(buf),1) == XML_STATUS_ERROR) { printf("Parse Error at line %u:\n%s\n", XML_GetCurrentLineNumber(p), XML_ErrorString(XML_GetErrorCode(p))); return; } XML_ParserFree(p); }
static LmHandlerResult sasl_features_cb (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer user_data) { LmMessageNode *mechanisms; LmSASL *sasl; g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SASL, "Stream features received\n"); mechanisms = lm_message_node_find_child (message->node, "mechanisms"); if (!mechanisms) { return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; } sasl = (LmSASL *) user_data; sasl->features_received = TRUE; sasl_set_auth_type (sasl, mechanisms); if (sasl->start_auth) { sasl_authenticate (sasl); } return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; }
LmHandlerResult handle_iq_disco_info(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { LmMessage *r; LmMessageNode *query, *tmp; const char *node = NULL; const char *param = NULL; if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_RESULT) return LM_HANDLER_RESULT_REMOVE_MESSAGE; r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT); query = lm_message_node_add_child(r->node, "query", NULL); lm_message_node_set_attribute(query, "xmlns", NS_DISCO_INFO); tmp = lm_message_node_find_child(m->node, "query"); if (tmp) { node = lm_message_node_get_attribute(tmp, "node"); param = node+strlen(MCABBER_CAPS_NODE)+1; } if (node && startswith(node, MCABBER_CAPS_NODE "#", FALSE)) disco_info_set_caps(query, param); // client#version else // Basic discovery request disco_info_set_caps(query, NULL); lm_connection_send(c, r, NULL); lm_message_unref(r); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
/* * Получение аттрибута одного из нодов */ gchar* lm_message_node_get_child_attribute(LmMessageNode *node, const gchar *child, const gchar *attribute) { LmMessageNode *tmp; tmp = lm_message_node_find_child(node, child); if(tmp) return (gchar*)lm_message_node_get_attribute(tmp, attribute); else return NULL; }
/* * Получение значения одного из child */ gchar* lm_message_node_get_child_value(LmMessageNode *node, const gchar *child) { LmMessageNode *tmp; tmp = lm_message_node_find_child(node, child); if(tmp) return (gchar*)lm_message_node_get_value(tmp); else return NULL; }
//doc Loudmouth registerAccount(server, username, password) Registers a new account at XMPP server. Returns <code>true</code> or <code>false</code>. IoObject *IoLoudmouth_registerAccount(IoLoudmouth *self, IoObject *locals, IoMessage *m) { char *server = IoMessage_locals_cStringArgAt_(m, locals, 0), *username = IoMessage_locals_cStringArgAt_(m, locals, 1), *password = IoMessage_locals_cStringArgAt_(m, locals, 2), *error_message = "Unknown error"; LmConnection *connection = lm_connection_new(server); LmMessage *xmpp_msg, *xmpp_reply; LmMessageNode *query, *node; int success = 0; if(!lm_connection_open_and_block(connection, NULL)) { error_message = "Could not open connection"; success = 0; } else { xmpp_msg = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_SET); query = lm_message_node_add_child(xmpp_msg->node, "query", NULL); lm_message_node_set_attributes(query, "xmlns", "jabber:iq:register", NULL); lm_message_node_add_child(query, "username", username); lm_message_node_add_child(query, "password", password); xmpp_reply = lm_connection_send_with_reply_and_block(connection, xmpp_msg, NULL); lm_connection_close(connection, NULL); lm_connection_unref(connection); if(!xmpp_reply) { success = 0; error_message = "No reply from server"; } else { switch(lm_message_get_sub_type(xmpp_reply)) { case LM_MESSAGE_SUB_TYPE_RESULT: success = 1; break; case LM_MESSAGE_SUB_TYPE_ERROR: default: success = 0; node = lm_message_node_find_child(xmpp_reply->node, "error"); error_message = (node == NULL) ? lm_message_node_get_value(node) : "Unknown error"; lm_message_node_unref(node); } } lm_message_unref(xmpp_reply); lm_message_unref(xmpp_msg); lm_message_node_unref(query); } free(server); free(username); free(password); IOASSERT(success, error_message); free(error_message); return IOBOOL(self, success); }
const gchar* lm_message_node_get_child_value(LmMessageNode *node, const gchar *child) { LmMessageNode *tmp; tmp = lm_message_node_find_child(node, child); if (tmp) { const gchar *val = lm_message_node_get_value(tmp); return (val ? val : ""); } return NULL; }
LmHandlerResult xmpp_receive_command(LmMessageHandler *handler, LmConnection *conn, LmMessage *m, gpointer udata) { Xinb *x = udata; LmMessageNode *body; gchar *jid; const gchar *from; if(x->state != LM_CONNECTION_STATE_AUTHENTICATED) { log_record(x, LOGS_ERR, "Unable to receive message: not authenticated"); goto out; } from = lm_message_node_get_attribute(m->node, "from"); jid = xmpp_get_jid(from); if(g_strcmp0(jid, g_hash_table_lookup(x->config, "owner"))) { log_record(x, LOGS_ERR, "To command may only owner: '%s'", from); x->to = jid; x->message = g_strdup("You don't have permission to command me"); xmpp_send_message(x, LM_MESSAGE_SUB_TYPE_CHAT); g_free(x->message); goto out; } body = lm_message_node_find_child(m->node, "body"); if(lm_message_get_sub_type(m) != LM_MESSAGE_SUB_TYPE_CHAT) { log_record(x, LOGS_ERR, "Invalid subtype of the command"); goto out; } if(command_run(x, body->value)) { log_record(x, LOGS_INFO, "The command was successfully executed"); } out: g_free(jid); lm_message_unref(m); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
// This callback is reached when mcabber receives the first roster update // after the connection. static LmHandlerResult cb_roster(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer user_data) { LmMessageNode *x; const char *ns; // Only execute the hook if the roster has been successfully retrieved if (lm_message_get_sub_type(m) != LM_MESSAGE_SUB_TYPE_RESULT) return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; x = lm_message_node_find_child(m->node, "query"); if (!x) return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; ns = lm_message_node_get_attribute(x, "xmlns"); if (ns && !strcmp(ns, NS_ROSTER)) handle_iq_roster(NULL, c, m, user_data); // Post-login stuff hk_postconnect(); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
LmHandlerResult LM::HeapRoster::handle_message (LmConnection* /*connection*/, LmMessage* message) { LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; LmMessageNode* node = lm_message_get_node (message); const gchar* from_c = lm_message_node_get_attribute (node, "from"); const gchar* type_attr = lm_message_node_get_attribute (node, "type"); std::string base_jid; if (from_c != 0) { std::string from (from_c); std::string::size_type index = from.find ('/'); base_jid = std::string (from, 0, index); } PresentityPtr item = find_item (base_jid); if (item && (type_attr == NULL || (type_attr != NULL && g_strcmp0 (type_attr, "normal") == 0) || (type_attr != NULL && g_strcmp0 (type_attr, "chat") == 0))) { // let's imagine it's a basic chat message LmMessageNode* body = lm_message_node_find_child (node, "body"); if (body && lm_message_node_get_value (body) != NULL) { result = LM_HANDLER_RESULT_REMOVE_MESSAGE; Ekiga::Message::payload_type payload; payload["text/plain"] = lm_message_node_get_value (body); dialect->push_message (item, payload); } // it could also be an avatar or a pubsub event or... } return result; }
static gboolean update_location_from_msg (GabbleConnection *conn, TpHandle contact, LmMessage *msg) { LmMessageNode *node; GHashTable *location = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_free, (GDestroyNotify) tp_g_value_slice_free); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles ( (TpBaseConnection *) conn, TP_HANDLE_TYPE_CONTACT); const gchar *from = tp_handle_inspect (contact_repo, contact); NodeIter i; const gchar *lang; node = lm_message_node_find_child (wocky_stanza_get_top_node (msg), "geoloc"); if (node == NULL) return FALSE; DEBUG ("LocationsUpdate for %s:", from); lang = lm_message_node_get_attribute (node, "xml:lang"); if (lang != NULL) { g_hash_table_insert (location, g_strdup ("language"), tp_g_value_slice_new_string (lang)); } build_mapping_tables (); for (i = node_iter (node); i; i = node_iter_next (i)) { LmMessageNode *subloc_node = node_iter_data (i); GValue *value = NULL; gchar *xmpp_name; const gchar *str; LocationMapping *mapping; xmpp_name = subloc_node->name; str = lm_message_node_get_value (subloc_node); if (str == NULL) continue; mapping = g_hash_table_lookup (xmpp_to_tp, xmpp_name); if (mapping == NULL) { DEBUG ("Unknown location attribute: %s\n", xmpp_name); continue; } if (mapping->type == G_TYPE_DOUBLE) { gdouble double_value; gchar *end; double_value = g_ascii_strtod (str, &end); if (end == str) continue; value = tp_g_value_slice_new_double (double_value); DEBUG ("\t - %s: %f", xmpp_name, double_value); } else if (strcmp (xmpp_name, "timestamp") == 0) { GTimeVal timeval; if (g_time_val_from_iso8601 (str, &timeval)) { value = tp_g_value_slice_new_int64 (timeval.tv_sec); DEBUG ("\t - %s: %s", xmpp_name, str); } else { DEBUG ("\t - %s: %s: unknown date format", xmpp_name, str); continue; } } else if (mapping->type == G_TYPE_STRING) { value = tp_g_value_slice_new_string (str); DEBUG ("\t - %s: %s", xmpp_name, str); } else { g_assert_not_reached (); } g_hash_table_insert (location, g_strdup (mapping->tp_name), value); } tp_svc_connection_interface_location_emit_location_updated (conn, contact, location); gabble_presence_cache_update_location (conn->presence_cache, contact, location); return TRUE; }
LmHandlerResult LM::HeapRoster::handle_presence (LmConnection* /*connection*/, LmMessage* message) { LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; const gchar* from_c = lm_message_node_get_attribute (lm_message_get_node (message), "from"); const gchar* type_attr = lm_message_node_get_attribute (lm_message_get_node (message), "type"); std::string base_jid; std::string resource; if (from_c != 0) { std::string from (from_c); std::string::size_type index = from.find ('/'); base_jid = std::string (from, 0, index); resource = std::string (from, index + 1, std::string::npos); } PresentityPtr item = find_item (base_jid); if (type_attr != NULL && g_strcmp0 (type_attr, "subscribe") == 0) { result = LM_HANDLER_RESULT_REMOVE_MESSAGE; boost::shared_ptr<Ekiga::FormRequestSimple> request = boost::shared_ptr<Ekiga::FormRequestSimple> (new Ekiga::FormRequestSimple (boost::bind (&LM::HeapRoster::subscribe_from_form_submitted, this, _1, _2))); LmMessageNode* status = lm_message_node_find_child (lm_message_get_node (message), "status"); gchar* instructions = NULL; std::string item_name; if (item) { item_name = item->get_name (); } else { item_name = base_jid; } request->title (_("Authorization to see your presence")); if (status != NULL && lm_message_node_get_value (status) != NULL) { instructions = g_strdup_printf (_("%s asks the permission to see your presence, saying: \"%s\"."), item_name.c_str (), lm_message_node_get_value (status)); } else { instructions = g_strdup_printf (_("%s asks the permission to see your presence."), item_name.c_str ()); } request->instructions (instructions); g_free (instructions); std::map<std::string, std::string> choices; choices["grant"] = _("grant him/her the permission to see your presence"); choices["refuse"] = _("refuse him/her the permission to see your presence"); choices["later"] = _("decide later (also close or cancel this dialog)"); request->single_choice ("answer", _("Your answer is: "), "grant", choices); request->hidden ("jid", base_jid); questions (request); } else { if (item) { result = LM_HANDLER_RESULT_REMOVE_MESSAGE; item->push_presence (resource, lm_message_get_node (message)); } } return result; }
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; }
void handle_muc_presence(const char *from, LmMessageNode *xmldata, const char *roomjid, const char *rname, enum imstatus ust, const char *ustmsg, time_t usttime, char bpprio) { char *mbuf; const char *ournick; enum imrole mbrole = role_none; enum imaffiliation mbaffil = affil_none; enum room_printstatus printstatus; enum room_autowhois autowhois; enum room_flagjoins flagjoins; const char *mbjid = NULL, *mbnick = NULL; const char *reason = NULL; char *actor = NULL; bool new_member = FALSE; // True if somebody else joins the room (not us) bool our_presence = FALSE; // True if this presence is from us (i.e. bears // code 110) guint statuscode = 0; guint nickchange = 0; GSList *room_elt; int log_muc_conf; guint msgflags; log_muc_conf = settings_opt_get_int("log_muc_conf"); room_elt = roster_find(roomjid, jidsearch, 0); if (!room_elt) { // Add room if it doesn't already exist // It shouldn't happen, there is probably something wrong (server or // network issue?) room_elt = roster_add_user(roomjid, NULL, NULL, ROSTER_TYPE_ROOM, sub_none, -1); scr_LogPrint(LPRINT_LOGNORM, "Strange MUC presence message"); } else { // Make sure this is a room (it can be a conversion user->room) buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); } // Get room member's information muc_get_item_info(from, xmldata, &mbrole, &mbaffil, &mbjid, &mbnick, &actor, &reason); // Get our room nickname ournick = buddy_getnickname(room_elt->data); if (!ournick) { // It shouldn't happen, probably a server issue const gchar msg[] = "Unexpected groupchat packet!"; scr_LogPrint(LPRINT_LOGNORM, msg); scr_WriteIncomingMessage(roomjid, msg, 0, HBB_PREFIX_INFO, 0); // Send back an unavailable packet xmpp_setstatus(offline, roomjid, "", TRUE); scr_draw_roster(); return; } #define SETSTATUSCODE(VALUE) \ { \ if (G_UNLIKELY(statuscode)) \ scr_LogPrint(LPRINT_DEBUG, "handle_muc_presence: WARNING: " \ "replacing status code %u with %u.", statuscode, VALUE); \ statuscode = VALUE; \ } { // Get the status code LmMessageNode *node; for (node = xmldata -> children; node; node = node -> next) { if (!g_strcmp0(node -> name, "status")) { const char *codestr = lm_message_node_get_attribute(node, "code"); if (codestr) { const char *mesg = NULL; switch (atoi(codestr)) { // initial case 100: mesg = "The room is not anonymous."; break; case 110: // It is our presence our_presence = TRUE; break; // initial case 170: mesg = "The room is logged."; break; // initial case 201: // Room created SETSTATUSCODE(201); break; // initial case 210: // Your nick change (on join) // FIXME: print nick mesg = "The room has changed your nick!"; buddy_setnickname(room_elt->data, rname); ournick = rname; break; case 301: // User banned SETSTATUSCODE(301); break; case 303: // Nick change SETSTATUSCODE(303); break; case 307: // User kicked SETSTATUSCODE(307); break; // XXX (next three) case 321: mesg = "User leaves room due to affilation change."; break; case 322: mesg = "User leaves room, as room is only for members now."; break; case 332: mesg = "User leaves room due to system shutdown."; break; default: scr_LogPrint(LPRINT_DEBUG, "handle_muc_presence: Unknown MUC status code: %s.", codestr); break; } if (mesg) { scr_WriteIncomingMessage(roomjid, mesg, usttime, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); if (log_muc_conf) hlog_write_message(roomjid, 0, -1, mesg); } } } } } #undef SETSTATUSCODE if (!our_presence) if (ournick && !strcmp(ournick, rname)) our_presence = TRUE; // Get the room's "print_status" settings printstatus = buddy_getprintstatus(room_elt->data); if (printstatus == status_default) { printstatus = (guint) settings_opt_get_int("muc_print_status"); if (printstatus > 3) printstatus = status_default; } // A new room has been created; accept MUC default config if (statuscode == 201) xmpp_room_unlock(roomjid); // Check for nickname change if (statuscode == 303 && mbnick) { mbuf = g_strdup_printf("%s is now known as %s", rname, mbnick); scr_WriteIncomingMessage(roomjid, mbuf, usttime, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); if (log_muc_conf) hlog_write_message(roomjid, 0, -1, mbuf); g_free(mbuf); buddy_resource_setname(room_elt->data, rname, mbnick); // Maybe it's _our_ nickname... if (our_presence) buddy_setnickname(room_elt->data, mbnick); nickchange = TRUE; } autowhois = buddy_getautowhois(room_elt->data); if (autowhois == autowhois_default) autowhois = (settings_opt_get_int("muc_auto_whois") ? autowhois_on : autowhois_off); // Check for departure/arrival if (statuscode != 303 && ust == offline) { // Somebody is leaving enum { leave=0, kick, ban } how = leave; if (statuscode == 307) how = kick; else if (statuscode == 301) how = ban; // If this is a leave, check if it is ourself if (our_presence) { buddy_setinsideroom(room_elt->data, FALSE); buddy_setnickname(room_elt->data, NULL); buddy_del_all_resources(room_elt->data); buddy_settopic(room_elt->data, NULL); scr_update_chat_status(FALSE); update_roster = TRUE; } // The message depends on _who_ left, and _how_ if (how) { gchar *mbuf_end; gchar *reason_msg = NULL; // Forced leave if (actor) { mbuf_end = g_strdup_printf("%s from %s by %s", (how == ban ? "banned" : "kicked"), roomjid, actor); } else { mbuf_end = g_strdup_printf("%s from %s", (how == ban ? "banned" : "kicked"), roomjid); } if (reason) reason_msg = g_strdup_printf("\nReason: %s", reason); if (our_presence) mbuf = g_strdup_printf("You have been %s%s", mbuf_end, reason_msg ? reason_msg : ""); else mbuf = g_strdup_printf("%s has been %s%s", rname, mbuf_end, reason_msg ? reason_msg : ""); g_free(reason_msg); g_free(mbuf_end); } else { // Natural leave if (our_presence) { LmMessageNode *destroynode = lm_message_node_find_child(xmldata, "destroy"); if (destroynode) { reason = lm_message_node_get_child_value(destroynode, "reason"); if (reason && *reason) { mbuf = g_strdup_printf("You have left %s, " "the room has been destroyed: %s", roomjid, reason); } else { mbuf = g_strdup_printf("You have left %s, " "the room has been destroyed", roomjid); } } else { mbuf = g_strdup_printf("You have left %s", roomjid); } } else { if (ust != offline) { // This can happen when a network failure occurs, // this isn't an official leave but the user isn't there anymore. mbuf = g_strdup_printf("%s has disappeared!", rname); ust = offline; } else { if (ustmsg) mbuf = g_strdup_printf("%s has left: %s", rname, ustmsg); else mbuf = g_strdup_printf("%s has left", rname); } } } g_free(actor); // Display the mbuf message if we're concerned // or if the print_status isn't set to none. if (our_presence || printstatus != status_none) { msgflags = HBB_PREFIX_INFO; flagjoins = buddy_getflagjoins(room_elt->data); if (flagjoins == flagjoins_default && settings_opt_get_int("muc_flag_joins") == 2) flagjoins = flagjoins_all; if (!our_presence && flagjoins != flagjoins_all) msgflags |= HBB_PREFIX_NOFLAG; //silent message if someone else joins, and we care about noone scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0); } if (log_muc_conf) hlog_write_message(roomjid, 0, -1, mbuf); if (our_presence) { scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf); g_free(mbuf); return; } g_free(mbuf); } else { enum imstatus old_ust = buddy_getstatus(room_elt->data, rname); if (old_ust == offline && ust != offline) { // Somebody is joining new_member = muc_handle_join(room_elt, rname, roomjid, ournick, printstatus, usttime, log_muc_conf, autowhois, mbjid); } else { // This is a simple member status change if (printstatus == status_all && !nickchange) { const char *old_ustmsg = buddy_getstatusmsg(room_elt->data, rname); if (old_ust != ust || g_strcmp0(old_ustmsg, ustmsg)) { mbuf = g_strdup_printf("%s [%c>%c] %s", rname, imstatus2char[old_ust], imstatus2char[ust], ((ustmsg) ? ustmsg : "")); scr_WriteIncomingMessage(roomjid, mbuf, usttime, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); g_free(mbuf); } } } } // Sanity check, shouldn't happen... if (!rname) return; // Update room member status roster_setstatus(roomjid, rname, bpprio, ust, ustmsg, usttime, mbrole, mbaffil, mbjid); if (new_member && autowhois == autowhois_on) { cmd_room_whois(room_elt->data, rname, FALSE); } scr_draw_roster(); }
gboolean jid_reg(struct _jid *jid, GMainContext *context) { LmConnection *reg_connect; LmMessage *m, *reply; LmMessageNode *query, *node; GError *error = NULL; // Проверяем context if(!context) context = g_main_context_default(); // Подключаемся reg_connect = lm_connection_new_with_context(jid->server, context); // Настраиваем ssl /* if(jid->use_ssl) { LmSSL *ssl; // Проверяем поддержку ssl if(!lm_ssl_is_supported()) { g_print("Your Loudmouth doesn't support SSL. Reinstall loudmouth.\n"); jid->use_ssl = FALSE; } g_print("Configure ssl\n"); ssl = lm_ssl_new(NULL, LM_SSL_RESPONSE_CONTINUE, NULL, NULL); lm_connection_set_ssl(reg_connect, ssl); lm_ssl_unref(ssl); lm_connection_set_port(reg_connect, LM_CONNECTION_DEFAULT_PORT_SSL); } */ // Проверяем коннект if(!lm_connection_open_and_block(reg_connect, &error)) { fprintf(stderr, "Failed to open connection: %s\n", error->message); return FALSE; } // Определяем сообщение m = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_SET); // Составляем запрос query = lm_message_node_add_child(m->node, "query", NULL); lm_message_node_set_attributes(query, "xmlns", "jabber:iq:register", NULL); lm_message_node_add_child(query, "username", jid->username); lm_message_node_add_child(query, "password", jid->password); // Отпревляем сообщение и ждём ответ reply = lm_connection_send_with_reply_and_block(reg_connect, m, &error); if(!reply) { fprintf(stderr, "Failed to send registration request on server \"%s\":\n %s\n", jid->server, error->message); return FALSE; } //Закрываем соединение lm_connection_close(reg_connect, NULL); lm_connection_unref(reg_connect); // Проверяем ответ switch(lm_message_get_sub_type(reply)) { case LM_MESSAGE_SUB_TYPE_RESULT: g_print("Succeeded in register account '%s@%s'\n", jid->username, jid->server); break; case LM_MESSAGE_SUB_TYPE_ERROR: default: g_print("Failed to register account '%s@%s' due to: ", jid->username, jid->server); node = lm_message_node_find_child(reply->node, "error"); if(node) g_print("%s\n", lm_message_node_get_value (node)); else g_print("Unknown error\n"); return FALSE; break; } return TRUE; }