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; }
LmHandlerResult handle_iq_disco_items(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { LmMessageNode *query; const char *node; query = lm_message_node_get_child(m->node, "query"); node = lm_message_node_get_attribute(query, "node"); if (node) { if (!strcmp(node, NS_COMMANDS)) { return handle_iq_commands_list(NULL, c, m, ud); } else { send_iq_error(c, m, XMPP_ERROR_NOT_IMPLEMENTED); } } else { // not sure about this one send_iq_error(c, m, XMPP_ERROR_NOT_IMPLEMENTED); } return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
// This function borrows some code from the Pidgin project LmHandlerResult handle_iq_time(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { LmMessage *r; LmMessageNode *query; char *buf, *utf8_buf; time_t now_t; struct tm *now; time(&now_t); if (!settings_opt_get_int("iq_hide_requests")) { scr_LogPrint(LPRINT_LOGNORM, "Received an IQ time request from <%s>", lm_message_get_from(m)); } if (settings_opt_get_int("iq_time_hide")) { send_iq_error(c, m, XMPP_ERROR_SERVICE_UNAVAILABLE); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } buf = g_new0(char, 512); 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_TIME); now = gmtime(&now_t); strftime(buf, 512, "%Y%m%dT%T", now); lm_message_node_add_child(query, "utc", buf); now = localtime(&now_t); strftime(buf, 512, "%Z", now); if ((utf8_buf = to_utf8(buf))) { lm_message_node_add_child(query, "tz", utf8_buf); g_free(utf8_buf); } strftime(buf, 512, "%d %b %Y %T", now); if ((utf8_buf = to_utf8(buf))) { lm_message_node_add_child(query, "display", utf8_buf); g_free(utf8_buf); } lm_connection_send(c, r, NULL); lm_message_unref(r); g_free(buf); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
LmHandlerResult handle_iq_commands(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { const char *requester_jid = NULL; LmMessageNode *cmd; const struct adhoc_command *command; // mcabber has only partial XEP-0146 support... if (LM_MESSAGE_SUB_TYPE_SET != lm_message_get_sub_type(m)) return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; requester_jid = lm_message_get_from(m); cmd = lm_message_node_get_child(m->node, "command"); if (!cmd) { //send_iq_error(c, m, XMPP_ERROR_BAD_REQUEST); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } if (jid_equal(lm_connection_get_jid(c), requester_jid)) { const char *action, *node; action = lm_message_node_get_attribute(cmd, "action"); node = lm_message_node_get_attribute(cmd, "node"); // action can be NULL, in which case it seems to take the default, // ie execute if (!action || !strcmp(action, "execute") || !strcmp(action, "cancel") || !strcmp(action, "next") || !strcmp(action, "complete")) { for (command = adhoc_command_list; command->name; command++) { if (!strcmp(node, command->name)) command->callback(h, c, m, ud); } // "prev" action will get there, as we do not implement it, // and do not authorize it } else { LmMessage *r; LmMessageNode *err; r = lm_message_new_iq_error(m, XMPP_ERROR_BAD_REQUEST); if (r) { err = lm_message_node_get_child(r->node, "error"); lm_message_node_set_attribute (lm_message_node_add_child(err, "malformed-action", NULL), "xmlns", NS_COMMANDS); lm_connection_send(c, r, NULL); lm_message_unref(r); } } } else { send_iq_error(c, m, XMPP_ERROR_FORBIDDEN); } return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
LmHandlerResult handle_iq_version(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { LmMessage *r; LmMessageNode *query; if (!settings_opt_get_int("iq_hide_requests")) { scr_LogPrint(LPRINT_LOGNORM, "Received an IQ version request from <%s>", lm_message_get_from(m)); } if (settings_opt_get_int("iq_version_hide")) { 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_VERSION); lm_message_node_add_child(query, "name", PACKAGE_NAME); // MCabber version if (!settings_opt_get_int("iq_version_hide_version")) { char *ver = mcabber_version(); lm_message_node_add_child(query, "version", ver); g_free(ver); } // OS details if (!settings_opt_get_int("iq_version_hide_os")) { char *os; struct utsname osinfo; uname(&osinfo); os = g_strdup_printf("%s %s %s", osinfo.sysname, osinfo.release, osinfo.machine); lm_message_node_add_child(query, "os", os); g_free(os); } lm_connection_send(c, r, NULL); lm_message_unref(r); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
LmHandlerResult handle_iq_vcard(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { send_iq_error(c, m, XMPP_ERROR_SERVICE_UNAVAILABLE); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
// This function borrows some code from the Pidgin project LmHandlerResult handle_iq_time202(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { LmMessage *r; LmMessageNode *query; char *buf, *utf8_buf; time_t now_t; struct tm *now; char const *sign; int diff = 0; time(&now_t); if (!settings_opt_get_int("iq_hide_requests")) { scr_LogPrint(LPRINT_LOGNORM, "Received an IQ time request from <%s>", lm_message_get_from(m)); } if (settings_opt_get_int("iq_time_hide")) { send_iq_error(c, m, XMPP_ERROR_SERVICE_UNAVAILABLE); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } buf = g_new0(char, 512); r = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT); query = lm_message_node_add_child(r->node, "time", NULL); lm_message_node_set_attribute(query, "xmlns", NS_XMPP_TIME); now = localtime(&now_t); if (now->tm_isdst >= 0) { #if defined HAVE_TM_GMTOFF diff = now->tm_gmtoff; #elif defined HAVE_TIMEZONE tzset(); diff = -timezone; #endif } if (diff < 0) { sign = "-"; diff = -diff; } else { sign = "+"; } diff /= 60; snprintf(buf, 512, "%c%02d:%02d", *sign, diff / 60, diff % 60); if ((utf8_buf = to_utf8(buf))) { lm_message_node_add_child(query, "tzo", utf8_buf); g_free(utf8_buf); } now = gmtime(&now_t); strftime(buf, 512, "%Y-%m-%dT%TZ", now); lm_message_node_add_child(query, "utc", buf); lm_connection_send(c, r, NULL); lm_message_unref(r); g_free(buf); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }