LmHandlerResult handle_iq_last(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { LmMessage *r; LmMessageNode *query; char *seconds; if (!settings_opt_get_int("iq_hide_requests")) { scr_LogPrint(LPRINT_LOGNORM, "Received an IQ last time request from <%s>", lm_message_get_from(m)); } if (settings_opt_get_int("iq_last_disable") || (settings_opt_get_int("iq_last_disable_when_notavail") && xmpp_getstatus() == notavail)) { send_iq_error(c, m, XMPP_ERROR_SERVICE_UNAVAILABLE); 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_LAST); seconds = g_strdup_printf("%.0f", seconds_since_last_use()); lm_message_node_set_attribute(query, "seconds", seconds); g_free(seconds); lm_connection_send(c, r, NULL); lm_message_unref(r); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
// disco_info_set_caps(ansquery, entitycaps) // Add features attributes to ansquery. entitycaps should either be a // valid capabilities hash or NULL. If it is NULL, the node attribute won't // be added to the query child and Entity Capabilities will be announced // as a feature. // Please change the entity version string if you modify mcabber disco // source code, so that it doesn't conflict with the upstream client. static void disco_info_set_caps(LmMessageNode *ansquery, const char *entitycaps) { if (entitycaps) { char *eversion; eversion = g_strdup_printf("%s#%s", MCABBER_CAPS_NODE, entitycaps); lm_message_node_set_attribute(ansquery, "node", eversion); g_free(eversion); } lm_message_node_set_attributes (lm_message_node_add_child(ansquery, "identity", NULL), "category", "client", "name", PACKAGE_STRING, "type", "pc", NULL); if (entitycaps) caps_foreach_feature(entitycaps, _disco_add_feature_helper, ansquery); else { caps_foreach_feature(entity_version(xmpp_getstatus()), _disco_add_feature_helper, ansquery); lm_message_node_set_attribute (lm_message_node_add_child(ansquery, "feature", NULL), "var", NS_CAPS); } }
static LmHandlerResult handle_iq_command_set_status(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { const char *action, *node; char *sessionid; LmMessage *iq; LmMessageNode *command, *x, *y; const struct adhoc_status *s; x = lm_message_node_get_child(m->node, "command"); action = lm_message_node_get_attribute(x, "action"); node = lm_message_node_get_attribute(x, "node"); sessionid = (char *)lm_message_node_get_attribute(x, "sessionid"); iq = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT); command = lm_message_node_add_child(iq->node, "command", NULL); lm_message_node_set_attribute(command, "node", node); lm_message_node_set_attribute(command, "xmlns", NS_COMMANDS); if (!sessionid) { sessionid = generate_session_id("set-status"); lm_message_node_set_attribute(command, "sessionid", sessionid); g_free(sessionid); sessionid = NULL; lm_message_node_set_attribute(command, "status", "executing"); x = lm_message_node_add_child(command, "x", NULL); lm_message_node_set_attribute(x, "type", "form"); lm_message_node_set_attribute(x, "xmlns", "jabber:x:data"); lm_message_node_add_child(x, "title", "Change Status"); lm_message_node_add_child(x, "instructions", "Choose the status and status message"); // TODO see if factorisation is possible y = lm_message_node_add_child(x, "field", NULL); lm_message_node_set_attribute(y, "type", "hidden"); lm_message_node_set_attribute(y, "var", "FORM_TYPE"); lm_message_node_add_child(y, "value", "http://jabber.org/protocol/rc"); y = lm_message_node_add_child(x, "field", NULL); lm_message_node_set_attributes(y, "type", "list-single", "var", "status", "label", "Status", NULL); lm_message_node_add_child(y, "required", NULL); // XXX: ugly lm_message_node_add_child(y, "value", adhoc_status_list[xmpp_getstatus()].name); for (s = adhoc_status_list; s->name; s++) { LmMessageNode *option = lm_message_node_add_child(y, "option", NULL); lm_message_node_add_child(option, "value", s->name); lm_message_node_set_attribute(option, "label", s->description); } // TODO add priority ? // I do not think this is useful, user should not have to care of the // priority like gossip and gajim do (misc) lm_message_node_set_attributes (lm_message_node_add_child(x, "field", NULL), "type", "text-multi", "var", "status-message", "label", "Message", NULL); } else if (action && !strcmp(action, "cancel")) { lm_message_node_set_attribute(command, "status", "canceled"); } else { // (if sessionid and not canceled) y = lm_message_node_find_xmlns(x, "jabber:x:data"); //x?xmlns=jabber:x:data if (y) { const char *value=NULL, *message=NULL; LmMessageNode *fields, *field; field = fields = lm_message_node_get_child(y, "field"); //field?var=status while (field && strcmp("status", lm_message_node_get_attribute(field, "var"))) field = field->next; field = lm_message_node_get_child(field, "value"); if (field) value = lm_message_node_get_value(field); field = fields; //field?var=status-message while (field && strcmp("status-message", lm_message_node_get_attribute(field, "var"))) field = field->next; field = lm_message_node_get_child(field, "value"); if (field) message = lm_message_node_get_value(field); if (value) { for (s = adhoc_status_list; !s->name || strcmp(s->name, value); s++); if (s->name) { char *status = g_strdup_printf("%s %s", s->status, message ? message : ""); cmd_setstatus(NULL, status); g_free(status); lm_message_node_set_attribute(command, "status", "completed"); lm_message_node_add_dataform_result(command, "Status has been changed"); } } } } if (sessionid) lm_message_node_set_attribute(command, "sessionid", sessionid); lm_connection_send(c, iq, NULL); lm_message_unref(iq); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }