VALUE msg_get_sub_type (VALUE self) { LmMessage *m = rb_lm_message_from_ruby_object (self); return INT2FIX (lm_message_get_sub_type (m)); }
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; }
static LmHandlerResult ft_msg_iq_handler (LmMessageHandler *handler, LmConnection *conn, LmMessage *msg, gpointer user_data) { /* Currently the only IQ message we'll handle is the roster */ LmMessageNode *query = lm_message_node_get_child (msg->node, "query"); int type = lm_message_get_sub_type (msg); if (query) { const char *ns = lm_message_node_get_attribute (query, "xmlns"); if (ns && !g_ascii_strcasecmp (ns, "jabber:iq:roster")) ft_roster_cb (msg); else if (ns && !g_ascii_strcasecmp (ns, "jabber:iq:version")) { if (type == LM_MESSAGE_SUB_TYPE_GET) ft_msg_iq_version_cb (msg); } else if (ns && !g_ascii_strcasecmp (ns, "jabber:iq:last")) { if (type == LM_MESSAGE_SUB_TYPE_GET) ft_msg_iq_last_cb (msg); } else PRINTF (_("[iq received: %s (unhandled yet)]"), ns); } return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
static LmHandlerResult xmpp_presence_callback (LmMessageHandler * handler, LmConnection * connection, LmMessage * message, gpointer user_data) { LmMessageNode * node = message->node; xmpp_user_t user; gchar * jid; gchar * resource = NULL; gchar * delimit; jid = g_strdup (lm_message_node_get_attribute (node, "from")); delimit = strchr (jid, '/'); if (delimit != NULL) { *delimit = '\0'; resource = delimit+1; } switch (lm_message_get_sub_type (message)) { case LM_MESSAGE_SUB_TYPE_AVAILABLE: user = intern_user (jid); user->resource = g_strdup (resource); user->status = ONLINE; break; case LM_MESSAGE_SUB_TYPE_UNAVAILABLE: remuser (jid); break; } g_free (jid); }
//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); }
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; }
// Dummy handler to ignore IQ response LmHandlerResult handle_iq_dummy(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer ud) { LmMessageSubType mstype = lm_message_get_sub_type(m); if (mstype == LM_MESSAGE_SUB_TYPE_ERROR) { display_server_error(lm_message_node_get_child(m->node, "error"), lm_message_get_from(m)); } return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
LmHandlerResult LM::Presentity::handle_edit_reply (LmConnection* /*connection*/, LmMessage* message) { if (lm_message_get_sub_type (message) == LM_MESSAGE_SUB_TYPE_ERROR) { std::cout << "Don't know how to handle : " << lm_message_node_to_string (lm_message_get_node (message)) << std::endl; } 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_stanza(LmMessageHandler *handler, LmConnection *connection, LmMessage *lmsg, gpointer user_data) { XMPP_SERVER_REC *server; int type; const char *id; char *from, *to, *raw; if ((server = XMPP_SERVER(user_data)) == NULL) return LM_HANDLER_RESULT_REMOVE_MESSAGE; raw = xmpp_recode_in(lm_message_node_to_string(lmsg->node)); signal_emit("xmpp xml in", 2, server, raw); g_free(raw); type = lm_message_get_sub_type(lmsg); id = lm_message_node_get_attribute(lmsg->node, "id"); if (id == NULL) id = ""; from = xmpp_recode_in(lm_message_node_get_attribute(lmsg->node, "from")); if (from == NULL) from = g_strdup(""); to = xmpp_recode_in(lm_message_node_get_attribute(lmsg->node, "to")); if (to == NULL) to = g_strdup(""); switch(lm_message_get_type(lmsg)) { case LM_MESSAGE_TYPE_MESSAGE: signal_emit("xmpp recv message", 6, server, lmsg, type, id, from, to); break; case LM_MESSAGE_TYPE_PRESENCE: signal_emit("xmpp recv presence", 6, server, lmsg, type, id, from, to); break; case LM_MESSAGE_TYPE_IQ: signal_emit("xmpp recv iq", 6, server, lmsg, type, id, from, to); break; default: signal_emit("xmpp recv others", 6, server, lmsg, type, id, from, to); break; } g_free(from); g_free(to); 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_storage_bookmarks(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer user_data) { LmMessageNode *x, *ansqry; char *p = NULL; if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { LmMessageNode *error = lm_message_node_get_child(m->node, "error"); // No server support, or no bookmarks? if (error && error->children) p = error->children->name; if (p && !strcmp(p, "item-not-found")) { // item-no-found means the server has Private Storage, but it's // currently empty. if (bookmarks) lm_message_node_unref(bookmarks); bookmarks = lm_message_node_new("storage", "storage:bookmarks"); // We return 0 so that the IQ error message be // not displayed, as it isn't a real error. } else scr_LogPrint(LPRINT_LOGNORM, "Server does not support bookmarks storage."); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } ansqry = lm_message_node_get_child(m->node, "query"); ansqry = lm_message_node_get_child(ansqry, "storage"); if (!ansqry) { scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! (storage:bookmarks)"); return 0; } // Walk through the storage tags for (x = ansqry->children ; x; x = x->next) { // If the current node is a conference item, parse it and update the roster if (x->name && !strcmp(x->name, "conference")) storage_bookmarks_parse_conference(x); } // "Copy" the bookmarks node if (bookmarks) lm_message_node_unref(bookmarks); lm_message_node_deep_ref(ansqry); bookmarks = ansqry; return 0; }
static void sig_send_message(XMPP_SERVER_REC *server, LmMessage *lmsg) { LmMessageNode *node; LmMessageSubType type; type = lm_message_get_sub_type(lmsg); if ((type != LM_MESSAGE_SUB_TYPE_NOT_SET && type != LM_MESSAGE_SUB_TYPE_HEADLINE && type != LM_MESSAGE_SUB_TYPE_NORMAL && type != LM_MESSAGE_SUB_TYPE_CHAT) || (lm_message_node_get_child(lmsg->node, "body") == NULL && lm_message_node_get_child(lmsg->node, "subject") == NULL)) return; /* request composing events */ node = lm_message_node_add_child(lmsg->node, "x", NULL); lm_message_node_set_attribute(node, XMLNS, XMLNS_EVENT); lm_message_node_add_child(node, "composing", NULL); }
/* * Обработчик входящих сообщений */ LmHandlerResult handle_messages(LmMessageHandler *handler, LmConnection *connect, LmMessage *m, gpointer data) { printf("\nОбрабатываю событие LM_MESSAGE_TYPE_MESSAGE\n"); const gchar *from, *to, *body, *xmlns; gchar *str, *sstr = NULL; LmMessageSubType mstype; xmlns = lm_message_node_get_child_attribute(m->node, "x", "xmlns"); if(!xmlns) xmlns = ""; if(!strstr(xmlns, "delay")) { from = lm_message_node_get_attribute(m->node, "from"); to = lm_message_node_get_attribute(m->node, "to"); body = lm_message_node_get_child_value(m->node, "body"); mstype = lm_message_get_sub_type(m); if(body) { str = g_strdup(body); sstr = g_strdup(strtok(str, " ")); } if(sstr) { printf("Incoming message\n\tfrom: %s\n\tto: %s\n\tbody: %s\n", from, to, body); handler_cmd(connect, sstr, strchr(body, ' ')); } free(str); free(sstr); } usleep(100000); lm_message_unref(m); return LM_HANDLER_RESULT_REMOVE_MESSAGE; }
LmHandlerResult LM::HeapRoster::handle_initial_roster_reply (LmConnection* /*connection*/, LmMessage* message) { LmHandlerResult result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; if (lm_message_get_sub_type (message) == LM_MESSAGE_SUB_TYPE_RESULT) { LmMessageNode* node = lm_message_node_get_child (lm_message_get_node (message), "query"); if (node != NULL) { const gchar* xmlns = lm_message_node_get_attribute (node, "xmlns"); if (xmlns != NULL && g_strcmp0 (xmlns, "jabber:iq:roster") == 0) { parse_roster (node); result = LM_HANDLER_RESULT_REMOVE_MESSAGE; } } } return result; }
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; }
static LmHandlerResult cb_storage_rosternotes(LmMessageHandler *h, LmConnection *c, LmMessage *m, gpointer user_data) { LmMessageNode *ansqry; if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { const char *p = NULL; LmMessageNode *error = lm_message_node_get_child(m->node, "error"); // No server support, or no roster notes? if (error && error->children) p = error->children->name; if (p && !strcmp(p, "item-not-found")) { // item-no-found means the server has Private Storage, but it's // currently empty. if (rosternotes) lm_message_node_unref(rosternotes); rosternotes = lm_message_node_new("storage", "storage:rosternotes"); // We return 0 so that the IQ error message be // not displayed, as it isn't a real error. } else scr_LogPrint(LPRINT_LOGNORM, "Server does not support roster notes storage."); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } ansqry = lm_message_node_get_child(m->node, "query"); ansqry = lm_message_node_get_child(ansqry, "storage"); if (!ansqry) { scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! " "(storage:rosternotes)"); return LM_HANDLER_RESULT_REMOVE_MESSAGE; } // Copy the rosternotes node if (rosternotes) lm_message_node_unref(rosternotes); lm_message_node_deep_ref(ansqry); rosternotes = ansqry; return 0; }
// 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; }
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; }
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; }
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; }
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; }