/* Create an IQ response */ static xmpp_stanza_t* create_reply(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza) { xmpp_stanza_t* reply = xmpp_stanza_new(ctx); assert(reply); xmpp_stanza_set_name(reply, "iq"); xmpp_stanza_set_type(reply, "result"); if (xmpp_stanza_get_id(stanza)) { xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza)); } xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from")); return reply; }
void _receipt_request_handler(xmpp_stanza_t *const stanza) { if (!prefs_get_boolean(PREF_RECEIPTS_SEND)) { return; } char *id = xmpp_stanza_get_id(stanza); if (!id) { return; } xmpp_stanza_t *receipts = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS); if (!receipts) { return; } char *receipts_name = xmpp_stanza_get_name(receipts); if (g_strcmp0(receipts_name, "request") != 0) { return; } gchar *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); Jid *jid = jid_create(from); _message_send_receipt(jid->fulljid, id); jid_destroy(jid); }
static int _iq_handle_discoinfo_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata; const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); xmpp_stanza_t *incoming_query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); const char *node_str = xmpp_stanza_get_attribute(incoming_query, STANZA_ATTR_NODE); if (from != NULL) { xmpp_stanza_t *response = xmpp_stanza_new(ctx); xmpp_stanza_set_name(response, STANZA_NAME_IQ); xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza)); xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from); xmpp_stanza_set_type(response, STANZA_TYPE_RESULT); xmpp_stanza_t *query = caps_create_query_response_stanza(ctx); if (node_str != NULL) { xmpp_stanza_set_attribute(query, STANZA_ATTR_NODE, node_str); } xmpp_stanza_add_child(response, query); xmpp_send(conn, response); xmpp_stanza_release(query); xmpp_stanza_release(response); } return 1; }
static int _pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *id = xmpp_stanza_get_id(stanza); char *type = xmpp_stanza_get_type(stanza); if (id != NULL && type != NULL) { // show warning if error if (strcmp(type, STANZA_TYPE_ERROR) == 0) { log_warning("Server ping (id=%s) responded with error", id); // turn off autoping if error type is 'cancel' xmpp_stanza_t *error = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); if (error != NULL) { char *errtype = xmpp_stanza_get_type(error); if (errtype != NULL) { if (strcmp(errtype, "cancel") == 0) { log_warning("Server ping (id=%s) error type 'cancel', disabling autoping.", id); handle_autoping_cancel(); xmpp_timed_handler_delete(conn, _ping_timed_handler); } } } } } // remove this handler return 0; }
static int _disco_items_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata; const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (id != NULL) { log_debug("IQ disco items get handler fired, id: %s.", id); } else { log_debug("IQ disco items get handler fired."); } if (from != NULL) { xmpp_stanza_t *response = xmpp_stanza_new(ctx); xmpp_stanza_set_name(response, STANZA_NAME_IQ); xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza)); xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from); xmpp_stanza_set_type(response, STANZA_TYPE_RESULT); xmpp_stanza_t *query = xmpp_stanza_new(ctx); xmpp_stanza_set_name(query, STANZA_NAME_QUERY); xmpp_stanza_set_ns(query, XMPP_NS_DISCO_ITEMS); xmpp_stanza_add_child(response, query); xmpp_send(conn, response); xmpp_stanza_release(response); } return 1; }
static int _ibb_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ibb_session_t * sess; xmpp_ibb_userdata_t * udata = (xmpp_ibb_userdata_t *) userdata; char *id, *type; id = xmpp_stanza_get_id(stanza); type = xmpp_stanza_get_type(stanza); sess = ilist_finditem_func(g_list, _find_id, id); if (sess != NULL) { if (sess->state == STATE_OPENING) { //session created ack sess->state = STATE_READY; if (udata != NULL && udata->open_cb != NULL) udata->open_cb(sess, type); } else if (sess->state == STATE_SENDING) { sess->state = STATE_READY; if (udata != NULL && udata->recv_cb != NULL) udata->recv_cb(sess, NULL); //data sent ack } else if (sess->state == STATE_CLOSING) { sess->state = STATE_NONE; if (udata != NULL && udata->close_cb != NULL) udata->close_cb(sess, type); _ibb_session_release(sess); } } time(&glast_ping_time); return 1; }
static int _version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *id = xmpp_stanza_get_id(stanza); if (id != NULL) { log_debug("IQ version result handler fired, id: %s.", id); } else { log_debug("IQ version result handler fired."); } const char *jid = xmpp_stanza_get_attribute(stanza, "from"); xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); if (query == NULL) { return 1; } char *ns = xmpp_stanza_get_ns(query); if (g_strcmp0(ns, STANZA_NS_VERSION) != 0) { return 1; } char *name_str = NULL; char *version_str = NULL; char *os_str = NULL; xmpp_stanza_t *name = xmpp_stanza_get_child_by_name(query, "name"); xmpp_stanza_t *version = xmpp_stanza_get_child_by_name(query, "version"); xmpp_stanza_t *os = xmpp_stanza_get_child_by_name(query, "os"); if (name != NULL) { name_str = xmpp_stanza_get_text(name); } if (version != NULL) { version_str = xmpp_stanza_get_text(version); } if (os != NULL) { os_str = xmpp_stanza_get_text(os); } PContact contact; Jid *jidp = jid_create(jid); if (muc_room_is_active(jidp->barejid)) { contact = muc_get_participant(jidp->barejid, jidp->resourcepart); } else { contact = roster_get_contact(jidp->barejid); } Resource *resource = p_contact_get_resource(contact, jidp->resourcepart); const char *presence = string_from_resource_presence(resource->presence); handle_software_version_result(jid, presence, name_str, version_str, os_str); jid_destroy(jidp); return 1; }
/** * This is called when someone sends a RPC method call * Checks for XML-RPC format validation and sends error if so otherwise it calls the * HandleServiceCall for finding the right service and creating the right structures * @return KEEP_THIS_HANDLER_ACTIVE */ int HandleRpcCall(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *reply; xmpp_stanza_t *xmlRpcReply; xmpp_ctx_t *ctx = (xmpp_ctx_t*) userdata; sdvp_from_t* from; sdvp_reply_params_t* replyParams = NULL; int formatInvalid; sdvpIdleCounter = 0; sdvpPingsSent = 0; reply = xmpp_stanza_new(ctx); xmpp_stanza_set_name(reply, "iq"); // TODO: Get the Group and get the jid from = _CreateFrom(xmpp_stanza_get_attribute(stanza, "from"), "TODO", "TODO"); syslog(LOG_DEBUG, "Received a RPC Method call from %s\n", from->name); formatInvalid = _CheckRpcFormat(stanza); if (formatInvalid) { // FIXME: Something here fails! syslog(LOG_WARNING, "Error in XML-RPC format\n"); sdvp_InitiateReplyParameters(&replyParams, 1); replyParams->params[0].strValue = strdup("Error in XML-RPC format\n"); replyParams->params[0].type = IEC_VISIBLE_STRING; xmpp_stanza_set_type(reply, "error"); // TODO: Create a type //HJP var her! xmlRpcReply = _CreateReply(ctx, SDVP_METHOD_UNDEFINED ,replyParams); xmpp_stanza_add_child(reply, xmlRpcReply); //HJP: stanza_add_child laver en kopi, så der skal releases xmpp_stanza_release(xmlRpcReply); sdvp_FreeReplyParameters(replyParams); } else { // The reply from this function should be ready to send xmlRpcReply = _HandleServiceRequest(conn, stanza, userdata); xmpp_stanza_add_child(reply, xmlRpcReply); //HJP: stanza_add_child laver en kopi, så der skal releases xmpp_stanza_release(xmlRpcReply); } xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza)); xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from")); xmpp_stanza_set_type(reply, "result"); xmpp_send(conn, reply); xmpp_stanza_release(reply); // Frees the stanza and all of its children _FreeFrom(from); return KEEP_THIS_HANDLER_ACTIVE; }
void mood_publish(mood_callback_t callback, const char * const usermood, const char * const usertext) { xmpp_stanza_t *iq, *pubsub, *publish, *item, *mood, *stanza, *text; iq = xmpp_stanza_new(ctx); xmpp_stanza_set_name(iq, "iq"); xmpp_stanza_set_type(iq, "set"); xmpp_stanza_set_id(iq, "mood1"); /* FIXME */ pubsub = xmpp_stanza_new(ctx); xmpp_stanza_set_name(pubsub, "pubsub"); xmpp_stanza_set_ns(pubsub, NS_PUBSUB); xmpp_stanza_add_child(iq, pubsub); xmpp_stanza_release(pubsub); publish = xmpp_stanza_new(ctx); xmpp_stanza_set_name(publish, "publish"); xmpp_stanza_set_attribute(publish, "node", NS_MOOD); xmpp_stanza_add_child(pubsub, publish); xmpp_stanza_release(publish); item = xmpp_stanza_new(ctx); xmpp_stanza_set_name(item, "item"); xmpp_stanza_add_child(publish, item); xmpp_stanza_release(item); mood = xmpp_stanza_new(ctx); xmpp_stanza_set_name(mood, "mood"); xmpp_stanza_set_ns(mood, NS_MOOD); xmpp_stanza_add_child(item, mood); xmpp_stanza_release(mood); if (usermood != NULL) { stanza = xmpp_stanza_new(ctx); xmpp_stanza_set_name(stanza, usermood); xmpp_stanza_add_child(mood, stanza); xmpp_stanza_release(stanza); } if (usertext != NULL) { text = xmpp_stanza_new(ctx); xmpp_stanza_set_name(text, "text"); xmpp_stanza_set_text(text, usertext); xmpp_stanza_add_child(mood, text); xmpp_stanza_release(text); } xmpp_id_handler_add(conn, mood_result_handler, xmpp_stanza_get_id(iq), callback); xmpp_send(conn, iq); xmpp_stanza_release(iq); }
static int _zkmuc_source_query(xmpp_ua_t *ua, xmpp_stanza_t *stanza, void *userdata) { zkmuc_ctx_t *ctx = (zkmuc_ctx_t *)userdata; char *from = xmpp_stanza_get_attribute(stanza, "from"); char *id = xmpp_stanza_get_id(stanza); if (id == NULL) { return 0; } xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, "x"); if(x && xmpp_stanza_get_ns(x) && !strcmp(XMPP_NS_SOURCE, xmpp_stanza_get_ns(x))) { char *action = xmpp_stanza_get_attribute(x, "action"); if (!strcmp("query", action)) { xmpp_stanza_t *message = xmpp_stanza_new(_xmpp_ctx); xmpp_stanza_set_name(message, "message"); xmpp_stanza_set_attribute(message, "to", from); xmpp_stanza_set_id(message, id); xmpp_stanza_t *result_x = xmpp_stanza_new(_xmpp_ctx); xmpp_stanza_set_name(result_x, "x"); xmpp_stanza_set_ns(result_x, XMPP_NS_SOURCE); xmpp_stanza_set_attribute(result_x, "action", "result"); WaitForSingleObject(ctx->_mutex_4_source, INFINITE); zkmuc_source_t *item = ctx->head; while (item) { xmpp_stanza_t *stanza_item = xmpp_stanza_new(_xmpp_ctx); xmpp_stanza_set_name(stanza_item, "item"); char buf[32]; xmpp_stanza_set_attribute(stanza_item, "cid", itoa(item->cid, buf, 10)); xmpp_stanza_set_attribute(stanza_item, "sid", itoa(item->sid, buf, 10)); xmpp_stanza_set_attribute(stanza_item, "desc", item->description); xmpp_stanza_set_attribute(stanza_item, "mcu", item->mcu); xmpp_stanza_add_child(result_x, stanza_item); xmpp_stanza_release(stanza_item); item = item->next; } ReleaseMutex(ctx->_mutex_4_source); xmpp_stanza_add_child(message, result_x); xmpp_stanza_release(result_x); xmpp_ua_send(ctx->ua, message); xmpp_stanza_release(message); return 1; } } return 0; }
static void _iq_destroy_instant_room(const char * const room_jid) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_stanza_t *iq = stanza_create_instant_room_destroy_iq(ctx, room_jid); char *id = xmpp_stanza_get_id(iq); xmpp_id_handler_add(conn, _destroy_room_result_handler, id, NULL); xmpp_send(conn, iq); xmpp_stanza_release(iq); }
static void _iq_request_room_config_form(const char * const room_jid) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_stanza_t *iq = stanza_create_room_config_request_iq(ctx, room_jid); char *id = xmpp_stanza_get_id(iq); xmpp_id_handler_add(conn, _room_config_handler, id, NULL); xmpp_send(conn, iq); xmpp_stanza_release(iq); }
static void _iq_submit_room_config(const char * const room, DataForm *form) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_stanza_t *iq = stanza_create_room_config_submit_iq(ctx, room, form); char *id = xmpp_stanza_get_id(iq); xmpp_id_handler_add(conn, _room_config_submit_handler, id, NULL); xmpp_send(conn, iq); xmpp_stanza_release(iq); }
static void _iq_send_ping(const char * const target) { xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_stanza_t *iq = stanza_create_ping_iq(ctx, target); char *id = xmpp_stanza_get_id(iq); GDateTime *now = g_date_time_new_now_local(); xmpp_id_handler_add(conn, _manual_pong_handler, id, now); xmpp_send(conn, iq); xmpp_stanza_release(iq); }
static int _message_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) { char *id = xmpp_stanza_get_id(stanza); char *jid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); char *type = NULL; if (error_stanza) { type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE); } // stanza_get_error never returns NULL char *err_msg = stanza_get_error_message(stanza); GString *log_msg = g_string_new("message stanza error received"); if (id) { g_string_append(log_msg, " id="); g_string_append(log_msg, id); } if (jid) { g_string_append(log_msg, " from="); g_string_append(log_msg, jid); } if (type) { g_string_append(log_msg, " type="); g_string_append(log_msg, type); } g_string_append(log_msg, " error="); g_string_append(log_msg, err_msg); log_info(log_msg->str); g_string_free(log_msg, TRUE); if (!jid) { ui_handle_error(err_msg); } else if (type && (strcmp(type, "cancel") == 0)) { log_info("Recipient %s not found: %s", jid, err_msg); Jid *jidp = jid_create(jid); chat_session_remove(jidp->barejid); jid_destroy(jidp); } else { ui_handle_recipient_error(jid, err_msg); } free(err_msg); return 1; }
static int _ping_timed_handler(xmpp_conn_t * const conn, void * const userdata) { xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata; if (jabber_get_connection_status() == JABBER_CONNECTED) { xmpp_stanza_t *iq = stanza_create_ping_iq(ctx, NULL); char *id = xmpp_stanza_get_id(iq); // add pong handler xmpp_id_handler_add(conn, _pong_handler, id, ctx); xmpp_send(conn, iq); xmpp_stanza_release(iq); } return 1; }
int version_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *reply, *query, *name, *version, *text; char *ns; xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata; printf("Received version request from %s\n", xmpp_stanza_get_attribute(stanza, "from")); reply = xmpp_stanza_new(ctx); xmpp_stanza_set_name(reply, "iq"); xmpp_stanza_set_type(reply, "result"); xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza)); xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from")); query = xmpp_stanza_new(ctx); xmpp_stanza_set_name(query, "query"); ns = xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza)); if (ns) { xmpp_stanza_set_ns(query, ns); } name = xmpp_stanza_new(ctx); xmpp_stanza_set_name(name, "name"); xmpp_stanza_add_child(query, name); text = xmpp_stanza_new(ctx); xmpp_stanza_set_text(text, "libstrophe example bot"); xmpp_stanza_add_child(name, text); version = xmpp_stanza_new(ctx); xmpp_stanza_set_name(version, "version"); xmpp_stanza_add_child(query, version); text = xmpp_stanza_new(ctx); xmpp_stanza_set_text(text, "1.0"); xmpp_stanza_add_child(version, text); xmpp_stanza_add_child(reply, query); xmpp_send(conn, reply); xmpp_stanza_release(reply); return 1; }
static int _cb_iq(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { WaitForSingleObject(_mutex_4_conn, INFINITE); conn_ua_map::iterator iter = _conn_map.find(conn); if (iter == _conn_map.end()) { ReleaseMutex(_mutex_4_conn); return 1; } xmpp_ua_t *ua= iter->second; ReleaseMutex(_mutex_4_conn); char *id = xmpp_stanza_get_id(stanza); WaitForSingleObject(ua->mutex_4_ua, INFINITE); if (id) { std::string string_id(id); map_id_cb::iterator cb_iter = ua->id_cb_map.find(string_id); if (cb_iter != ua->id_cb_map.end()) { cb_iter->second.cb(ua, stanza, cb_iter->second.userdata); ua->id_cb_map.erase(cb_iter); ReleaseMutex(ua->mutex_4_ua); return 1; } } xmpp_ua_cb_list *current = ua->iq_head; while (current) { if (current->data.cb(ua, stanza, current->data.userdata)) { ReleaseMutex(ua->mutex_4_ua); return 1; } current = current->next; } _respond_iq_with_error(ua->conn, stanza, "cancel", "service-unavailable"); ReleaseMutex(ua->mutex_4_ua); return 1; }
static int _message_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *id = xmpp_stanza_get_id(stanza); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); char *type = NULL; if (error_stanza != NULL) { type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE); } // stanza_get_error never returns NULL char *err_msg = stanza_get_error_message(stanza); GString *log_msg = g_string_new("message stanza error received"); if (id != NULL) { g_string_append(log_msg, " id="); g_string_append(log_msg, id); } if (from != NULL) { g_string_append(log_msg, " from="); g_string_append(log_msg, from); } if (type != NULL) { g_string_append(log_msg, " type="); g_string_append(log_msg, type); } g_string_append(log_msg, " error="); g_string_append(log_msg, err_msg); log_info(log_msg->str); g_string_free(log_msg, TRUE); handle_message_error(from, type, err_msg); free(err_msg); return 1; }
static int disco_items_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *reply, *query; const char* myjid = xmpp_conn_get_bound_jid(conn); conflate_handle_t *handle = (conflate_handle_t*) userdata; assert(conn); assert(myjid); assert(stanza); assert(userdata); reply = xmpp_stanza_new(handle->ctx); assert(reply); xmpp_stanza_set_name(reply, "iq"); xmpp_stanza_set_type(reply, "result"); xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza)); xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from")); xmpp_stanza_set_attribute(reply, "from", myjid); query = xmpp_stanza_new(handle->ctx); assert(query); xmpp_stanza_set_name(query, "query"); xmpp_stanza_set_attribute(query, "xmlns", XMPP_NS_DISCO_ITEMS); xmpp_stanza_set_attribute(query, "node", "http://jabber.org/protocol/commands"); add_and_release(reply, query); for (struct command_def *p = commands; p; p = p->next) { add_disco_item(handle->ctx, query, myjid, p->name, p->description); } xmpp_send(conn, reply); xmpp_stanza_release(reply); return 1; }
static int _ibb_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ibb_session_t * sess; char *id; id = xmpp_stanza_get_id(stanza); sess = ilist_finditem_func(g_list, _find_id, id); if (sess != NULL) { xmpp_stanza_t *error; xmpperror_t xerr; error = xmpp_stanza_get_child_by_name(stanza, "error"); xmpp_error_stanza(error, &xerr); xmpp_ibb_userdata_t * udata = (xmpp_ibb_userdata_t *) userdata; sess->state = STATE_FAILED; if (udata != NULL && udata->error_cb != NULL) udata->error_cb(sess, &xerr); _ibb_session_release(sess); } time(&glast_ping_time); return 1; }
/** * Ping handler * Upon receiving a ping from the server this handler sends a "pong" back * The "pong" is an empty iq-result. */ int HandlePing(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *pong; char *id; char *sender; xmpp_ctx_t *ctx = (xmpp_ctx_t *) userdata; sdvpIdleCounter = 0; sdvpPingsSent = 0; id = xmpp_stanza_get_id(stanza); sender = xmpp_stanza_get_attribute(stanza, "from"); pong = xmpp_stanza_new(ctx); xmpp_stanza_set_name(pong, "iq"); xmpp_stanza_set_type(pong, "result"); xmpp_stanza_set_id(pong, id); xmpp_stanza_set_attribute(pong, "to", sender); // xmpp_stanza_set_attribute(pong, "from", "foxg20@einsteinium"); xmpp_send(conn, pong); xmpp_stanza_release(pong); return 1; // Returning 0 = Handler is deleted (Single shot), 1 = Handler is kept }
static int _iq_handle_discoitems_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata; const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (from != NULL) { xmpp_stanza_t *response = xmpp_stanza_new(ctx); xmpp_stanza_set_name(response, STANZA_NAME_IQ); xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza)); xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from); xmpp_stanza_set_type(response, STANZA_TYPE_RESULT); xmpp_stanza_t *query = xmpp_stanza_new(ctx); xmpp_stanza_set_name(query, STANZA_NAME_QUERY); xmpp_stanza_set_ns(query, XMPP_NS_DISCO_ITEMS); xmpp_stanza_add_child(response, query); xmpp_send(conn, response); xmpp_stanza_release(response); } return 1; }
static int version_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *reply, *query, *name, *version, *text; conflate_handle_t *handle = (conflate_handle_t*) userdata; xmpp_ctx_t *ctx = handle->ctx; char *ns; struct utsname un = {}; printf("Received version request from %s\n", xmpp_stanza_get_attribute(stanza, "from")); reply = xmpp_stanza_new(ctx); assert(reply); xmpp_stanza_set_name(reply, "iq"); xmpp_stanza_set_type(reply, "result"); xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza)); xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from")); query = xmpp_stanza_new(ctx); assert(query); xmpp_stanza_set_name(query, "query"); ns = xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza)); if (ns) { xmpp_stanza_set_ns(query, ns); } name = xmpp_stanza_new(ctx); assert(name); xmpp_stanza_set_name(name, "name"); add_and_release(query, name); text = xmpp_stanza_new(ctx); assert(text); xmpp_stanza_set_text(text, handle->conf->software); add_and_release(name, text); version = xmpp_stanza_new(ctx); assert(version); xmpp_stanza_set_name(version, "version"); add_and_release(query, version); text = xmpp_stanza_new(ctx); assert(text); xmpp_stanza_set_text(text, handle->conf->version); add_and_release(version, text); if (uname(&un) == 0) { char os_buf[128]; snprintf(os_buf, sizeof(os_buf), "%s/%s/%s", un.machine, un.sysname, un.release); xmpp_stanza_t *os = xmpp_stanza_new(ctx); assert(os); xmpp_stanza_set_name(os, "os"); add_and_release(query, os); text = xmpp_stanza_new(ctx); assert(text); xmpp_stanza_set_text(text, os_buf); add_and_release(os, text); } add_and_release(reply, query); xmpp_send(conn, reply); xmpp_stanza_release(reply); return 1; }
static int _presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *id = xmpp_stanza_get_id(stanza); char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); char *xmlns = NULL; if (x != NULL) { xmlns = xmpp_stanza_get_ns(x); } char *type = NULL; if (error_stanza != NULL) { type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE); } // handle MUC join errors if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) { Jid *fulljid = jid_create(from); char *error_cond = NULL; xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS); if (reason_st != NULL) { error_cond = xmpp_stanza_get_name(reason_st); } if (error_cond == NULL) { error_cond = "unknown"; } log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond); handle_room_join_error(fulljid->barejid, error_cond); return 1; } // stanza_get_error never returns NULL char *err_msg = stanza_get_error_message(stanza); GString *log_msg = g_string_new("presence stanza error received"); if (id != NULL) { g_string_append(log_msg, " id="); g_string_append(log_msg, id); } if (from != NULL) { g_string_append(log_msg, " from="); g_string_append(log_msg, from); } if (type != NULL) { g_string_append(log_msg, " type="); g_string_append(log_msg, type); } g_string_append(log_msg, " error="); g_string_append(log_msg, err_msg); log_info(log_msg->str); g_string_free(log_msg, TRUE); handle_presence_error(from, type, err_msg); free(err_msg); return 1; }
static void _presence_error_handler(xmpp_stanza_t *const stanza) { const char *xmlns = NULL; xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); if (x) { xmlns = xmpp_stanza_get_ns(x); } const char *from = xmpp_stanza_get_from(stanza); xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR); // handle MUC join errors if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) { const char *error_cond = NULL; xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS); if (reason_st) { error_cond = xmpp_stanza_get_name(reason_st); } if (error_cond == NULL) { error_cond = "unknown"; } Jid *fulljid = jid_create(from); log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond); if (muc_active(fulljid->barejid)) { muc_leave(fulljid->barejid); } cons_show_error("Error joining room %s, reason: %s", fulljid->barejid, error_cond); jid_destroy(fulljid); return; } GString *log_msg = g_string_new("presence stanza error received"); const char *id = xmpp_stanza_get_id(stanza); if (id) { g_string_append(log_msg, " id="); g_string_append(log_msg, id); } if (from) { g_string_append(log_msg, " from="); g_string_append(log_msg, from); } const char *type = NULL; if (error_stanza) { type = xmpp_stanza_get_type(error_stanza); } if (type) { g_string_append(log_msg, " type="); g_string_append(log_msg, type); } // stanza_get_error never returns NULL char *err_msg = stanza_get_error_message(stanza); g_string_append(log_msg, " error="); g_string_append(log_msg, err_msg); log_info(log_msg->str); g_string_free(log_msg, TRUE); if (from) { ui_handle_recipient_error(from, err_msg); } else { ui_handle_error(err_msg); } free(err_msg); }
static int _ibb_set_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *child; xmpp_ibb_userdata_t * udata = (xmpp_ibb_userdata_t *) userdata; xmpp_ibb_session_t * sess; char *from, *id, *type; id = xmpp_stanza_get_id(stanza); from = xmpp_stanza_get_attribute(stanza, "from"); type = xmpp_stanza_get_type(stanza); if ((child = xmpp_stanza_get_child_by_name(stanza, "open")) != NULL) { char *sid = xmpp_stanza_get_attribute(child, "sid"); char *bsize = xmpp_stanza_get_attribute(child, "block-size"); if (sid == NULL || bsize == NULL) { xmpp_iq_ack_error(conn, id, from, "cancel", "not-acceptable"); return 1; } else { xmpp_iq_ack_result(conn, id, from); } sess = _ibb_session_init(conn, from, sid); strncpy(sess->id, id, sizeof(sess->id)); strncpy(sess->peer, from, sizeof(sess->peer)); sess->state = STATE_READY; sess->block_size = atoi(bsize); if (udata != NULL && udata->open_cb != NULL) udata->open_cb(sess, type); ilist_add(g_list, sess); } else if ((child = xmpp_stanza_get_child_by_name(stanza, "data")) != NULL) { char *sid = xmpp_stanza_get_attribute(child, "sid"); sess = ilist_finditem_func(g_list, _find_sid, sid); if (sess != NULL) { xmppdata_t xdata; int seq = 0; char *intext = xmpp_stanza_get_text(child); xmpp_iq_ack_result(conn, id, from); xdata.from = from; strncpy(sess->id, id, sizeof(sess->id)); seq = atoi(xmpp_stanza_get_attribute(child, "seq")); if (seq != (sess->recv_seq + 1)) { //printf("sequence number is not continue. new seq %d last seq %d\n", seq, sess->recv_seq); } sess->recv_seq = seq; xmpp_b64decode(intext, (char **) &xdata.data, (size_t *) &xdata.size); if (udata != NULL && udata->recv_cb != NULL) udata->recv_cb(sess, &xdata); xmpp_b64free(sess->recv_data); sess->recv_data = NULL; } else { //printf("unknown session is not in handle.\n"); xmpp_iq_ack_error(conn, id, from, "cancel", "item-not-found"); } } else if ((child = xmpp_stanza_get_child_by_name(stanza, "close")) != NULL) { char *sid = xmpp_stanza_get_attribute(child, "sid"); sess = ilist_finditem_func(g_list, _find_sid, sid); if (sess != NULL) { xmpp_iq_ack_result(conn, id, from); strncpy(sess->id, id, sizeof(sess->id)); sess->state = STATE_NONE; if (udata != NULL && udata->close_cb != NULL) udata->close_cb(sess, type); _ibb_session_release(sess); } } time(&glast_ping_time); return 1; }
/** Fire off all stanza handlers that match. * This function is called internally by the event loop whenever stanzas * are received from the XMPP server. * * @param conn a Strophe connection object * @param stanza a Strophe stanza object */ void handler_fire_stanza(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza) { xmpp_handlist_t *item, *prev; char *id, *ns, *name, *type; /* call id handlers */ id = xmpp_stanza_get_id(stanza); if (id) { prev = NULL; item = (xmpp_handlist_t *)hash_get(conn->id_handlers, id); while (item) { xmpp_handlist_t *next = item->next; if (item->user_handler && !conn->authenticated) { item = next; continue; } if (!((xmpp_handler)(item->handler))(conn, stanza, item->userdata)) { /* handler is one-shot, so delete it */ if (prev) prev->next = next; else { hash_drop(conn->id_handlers, id); hash_add(conn->id_handlers, id, next); } xmpp_free(conn->ctx, item->id); xmpp_free(conn->ctx, item); item = NULL; } if (item) prev = item; item = next; } } /* call handlers */ ns = xmpp_stanza_get_ns(stanza); name = xmpp_stanza_get_name(stanza); type = xmpp_stanza_get_type(stanza); /* enable all added handlers */ for (item = conn->handlers; item; item = item->next) item->enabled = 1; prev = NULL; item = conn->handlers; while (item) { /* skip newly added handlers */ if (!item->enabled) { prev = item; item = item->next; continue; } /* don't call user handlers until authentication succeeds */ if (item->user_handler && !conn->authenticated) { prev = item; item = item->next; continue; } if ((!item->ns || (ns && strcmp(ns, item->ns) == 0) || xmpp_stanza_get_child_by_ns(stanza, item->ns)) && (!item->name || (name && strcmp(name, item->name) == 0)) && (!item->type || (type && strcmp(type, item->type) == 0))) if (!((xmpp_handler)(item->handler))(conn, stanza, item->userdata)) { /* handler is one-shot, so delete it */ if (prev) prev->next = item->next; else conn->handlers = item->next; if (item->ns) xmpp_free(conn->ctx, item->ns); if (item->name) xmpp_free(conn->ctx, item->name); if (item->type) xmpp_free(conn->ctx, item->type); xmpp_free(conn->ctx, item); item = NULL; } if (item) { prev = item; item = item->next; } else if (prev) item = prev->next; else item = conn->handlers; } }