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; }
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; }
static LmHandlerResult handle_iq_commands_list(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { LmMessage *iq; LmMessageNode *query; const char *requester_jid; const struct adhoc_command *command; const char *node; gboolean from_self; iq = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT); query = lm_message_node_add_child(iq->node, "query", NULL); lm_message_node_set_attribute(query, "xmlns", NS_COMMANDS); node = lm_message_node_get_attribute (lm_message_node_get_child(m->node, "query"), "node"); if (node) lm_message_node_set_attribute(query, "node", node); requester_jid = lm_message_get_from(m); from_self = jid_equal(lm_connection_get_jid(c), requester_jid); for (command = adhoc_command_list ; command->name ; command++) { if (!command->only_for_self || from_self) { lm_message_node_set_attributes (lm_message_node_add_child(query, "item", NULL), "node", command->name, "name", command->description, "jid", lm_connection_get_jid(c), NULL); } } lm_connection_send(c, iq, NULL); lm_message_unref(iq); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
static LmHandlerResult cb_vcard(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer user_data) { LmMessageNode *ansqry; const char *bjid; char *buf, *tmp; // Check IQ result sender bjid = lm_message_get_from(m); if (!bjid) bjid = lm_connection_get_jid(lconnection); // No from means our JID... if (!bjid) { scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:vCard result (no sender name)."); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } // Check for error message if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { scr_LogPrint(LPRINT_LOGNORM, "Received error IQ message (%s)", bjid); display_server_error(lm_message_node_get_child(m->node, "error"), NULL); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } buf = g_strdup_printf("Received IQ:vCard result from <%s>", bjid); scr_LogPrint(LPRINT_LOGNORM, "%s", buf); // Get the vCard node ansqry = lm_message_node_get_child(m->node, "vCard"); if (!ansqry) { scr_LogPrint(LPRINT_LOGNORM, "Empty IQ:vCard result!"); g_free(buf); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } // bjid should really be the "bare JID", let's strip the resource tmp = strchr(bjid, JID_RESOURCE_SEPARATOR); if (tmp) *tmp = '\0'; scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0); g_free(buf); // Get result data... handle_vcard_node(bjid, ansqry); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
static LmHandlerResult cb_last(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer user_data) { LmMessageNode *ansqry; const char *p, *bjid; char *buf, *tmp; // Check IQ result sender bjid = lm_message_get_from(m); if (!bjid) bjid = lm_connection_get_jid(lconnection); // No from means our JID... if (!bjid) { scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:last result (no sender name)."); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } // Check for error message if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { scr_LogPrint(LPRINT_LOGNORM, "Received error IQ message (%s)", bjid); display_server_error(lm_message_node_get_child(m->node, "error"), NULL); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } // Check message contents ansqry = lm_message_node_get_child(m->node, "query"); if (!ansqry) { scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:version result from <%s>!", bjid); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } buf = g_strdup_printf("Received IQ:last result from <%s>", bjid); scr_LogPrint(LPRINT_LOGNORM, "%s", buf); // bjid should now really be the "bare JID", let's strip the resource tmp = strchr(bjid, JID_RESOURCE_SEPARATOR); if (tmp) *tmp = '\0'; scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0); g_free(buf); // Get result data... p = lm_message_node_get_attribute(ansqry, "seconds"); if (p) { long int s; GString *sbuf; sbuf = g_string_new("Idle time: "); s = atol(p); // Days if (s > 86400L) { g_string_append_printf(sbuf, "%ldd ", s/86400L); s %= 86400L; } // hh:mm:ss g_string_append_printf(sbuf, "%02ld:", s/3600L); s %= 3600L; g_string_append_printf(sbuf, "%02ld:%02ld", s/60L, s%60L); scr_WriteIncomingMessage(bjid, sbuf->str, 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); g_string_free(sbuf, TRUE); } else { scr_WriteIncomingMessage(bjid, "No idle time reported.", 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); } p = lm_message_node_get_value(ansqry); if (p) { buf = g_strdup_printf("Status message: %s", p); scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0); g_free(buf); } return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
static LmHandlerResult cb_time(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer user_data) { LmMessageNode *ansqry; const char *p, *bjid; char *buf, *tmp; // Check IQ result sender bjid = lm_message_get_from(m); if (!bjid) bjid = lm_connection_get_jid(lconnection); // No from means our JID... if (!bjid) { scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:time result (no sender name)."); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } // Check for error message if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { scr_LogPrint(LPRINT_LOGNORM, "Received error IQ message (%s)", bjid); display_server_error(lm_message_node_get_child(m->node, "error"), NULL); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } // Check message contents ansqry = lm_message_node_get_child(m->node, "query"); if (!ansqry) { scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:time result from <%s>!", bjid); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } buf = g_strdup_printf("Received IQ:time result from <%s>", bjid); scr_LogPrint(LPRINT_LOGNORM, "%s", buf); // bjid should now really be the "bare JID", let's strip the resource tmp = strchr(bjid, JID_RESOURCE_SEPARATOR); if (tmp) *tmp = '\0'; scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0); g_free(buf); // Get result data... p = lm_message_node_get_child_value(ansqry, "utc"); if (p && *p) { buf = g_strdup_printf("UTC: %s", p); scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); g_free(buf); } p = lm_message_node_get_child_value(ansqry, "tz"); if (p && *p) { buf = g_strdup_printf("TZ: %s", p); scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); g_free(buf); } p = lm_message_node_get_child_value(ansqry, "display"); if (p && *p) { buf = g_strdup_printf("Time: %s", p); scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); g_free(buf); } return LM_HANDLER_RESULT_REMOVE_MESSAGE; }