int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *reply, *body, *text; char *intext, *replytext; xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata; if(!xmpp_stanza_get_child_by_name(stanza, "body")) return 1; intext = xmpp_stanza_get_text(xmpp_stanza_get_child_by_name(stanza, "body")); printf("Incoming message from %s: %s\n", xmpp_stanza_get_attribute(stanza, "from"), intext); reply = xmpp_stanza_new(ctx); xmpp_stanza_set_name(reply, "message"); xmpp_stanza_set_type(reply, xmpp_stanza_get_type(stanza)?xmpp_stanza_get_type(stanza):"chat"); xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from")); body = xmpp_stanza_new(ctx); xmpp_stanza_set_name(body, "body"); replytext = malloc(strlen(" to you too!") + strlen(intext) + 1); strcpy(replytext, intext); strcat(replytext, " to you too!"); text = xmpp_stanza_new(ctx); xmpp_stanza_set_text(text, replytext); xmpp_stanza_add_child(body, text); xmpp_stanza_add_child(reply, body); xmpp_send(conn, reply); xmpp_stanza_release(reply); free(replytext); 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; }
int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata; xmpp_stanza_t *reply; char *intext, *replytext; if (!xmpp_stanza_get_child_by_name(stanza, "body")) return 1; if (xmpp_stanza_get_type(stanza) != NULL && !strcmp(xmpp_stanza_get_type(stanza), "error")) return 1; intext = xmpp_stanza_get_text(xmpp_stanza_get_child_by_name(stanza, "body")); printf("Incoming message from %s: %s\n", xmpp_stanza_get_from(stanza), intext); reply = xmpp_stanza_reply(stanza); if (xmpp_stanza_get_type(reply) == NULL) xmpp_stanza_set_type(reply, "chat"); replytext = (char *) malloc(strlen(" to you too!") + strlen(intext) + 1); strcpy(replytext, intext); strcat(replytext, " to you too!"); xmpp_free(ctx, intext); xmpp_message_set_body(reply, replytext); xmpp_send(conn, reply); xmpp_stanza_release(reply); free(replytext); return 1; }
int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *reply, *body, *text; char *intext; xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata; if (!xmpp_stanza_get_child_by_name(stanza, "body")) return 1; if (xmpp_stanza_get_attribute(stanza, "type") != NULL && !strcmp(xmpp_stanza_get_attribute(stanza, "type"), "error")) return 1; intext = xmpp_stanza_get_text(xmpp_stanza_get_child_by_name(stanza, "body")); printf("Incoming message from %s: %s\n", xmpp_stanza_get_attribute(stanza, "from"), intext); reply = xmpp_stanza_new(ctx); xmpp_stanza_set_name(reply, "message"); xmpp_stanza_set_type(reply, xmpp_stanza_get_type(stanza) ? xmpp_stanza_get_type(stanza) : "chat"); xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from")); body = xmpp_stanza_new(ctx); xmpp_stanza_set_name(body, "body"); char replytext[1024]; scanf("%[^\n]", replytext); text = xmpp_stanza_new(ctx); xmpp_stanza_set_text(text, replytext); xmpp_stanza_add_child(body, text); xmpp_stanza_add_child(reply, body); xmpp_send(conn, reply); xmpp_stanza_release(reply); return 1; }
static int _handle_session(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *type; /* delete missing session handler */ xmpp_timed_handler_delete(conn, _handle_missing_session); /* server has replied to the session request */ type = xmpp_stanza_get_type(stanza); if (type && strcmp(type, "error") == 0) { xmpp_error(conn->ctx, "xmpp", "Session establishment failed."); xmpp_disconnect(conn); } else if (type && strcmp(type, "result") == 0) { xmpp_debug(conn->ctx, "xmpp", "Session establishment successful."); conn->authenticated = 1; /* call connection handler */ conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata); } else { xmpp_error(conn->ctx, "xmpp", "Server sent malformed session reply."); xmpp_disconnect(conn); } return 0; }
static int _handle_register(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *type; /* delete missing handler */ xmpp_timed_handler_delete(conn, _handle_missing_register); /* server responded to legacy auth request */ type = xmpp_stanza_get_type(stanza); if (!type) { xmpp_error(conn->ctx, "xmpp", "Server sent us an unexpected response "\ "to register request."); xmpp_disconnect(conn); } else if (strcmp(type, "error") == 0) { /* legacy client auth failed, no more fallbacks */ xmpp_error(conn->ctx, "xmpp", "Register clientfailed."); xmpp_disconnect(conn); } else if (strcmp(type, "result") == 0) { /* auth succeeded */ xmpp_debug(conn->ctx, "xmpp", "Register succeeded."); _auth(conn); } else { xmpp_error(conn->ctx, "xmpp", "Server sent us a register" \ "response with a bad type."); xmpp_disconnect(conn); } return 0; }
static gboolean _is_valid_form_element(xmpp_stanza_t *stanza) { const char *name = xmpp_stanza_get_name(stanza); if (g_strcmp0(name, STANZA_NAME_X) != 0) { log_error("Error parsing form, root element not <x/>."); return FALSE; } const char *ns = xmpp_stanza_get_ns(stanza); if (g_strcmp0(ns, STANZA_NS_DATA) != 0) { log_error("Error parsing form, namespace not %s.", STANZA_NS_DATA); return FALSE; } const char *type = xmpp_stanza_get_type(stanza); if ((g_strcmp0(type, "form") != 0) && (g_strcmp0(type, "submit") != 0) && (g_strcmp0(type, "cancel") != 0) && (g_strcmp0(type, "result") != 0)) { log_error("Error parsing form, unknown type."); return FALSE; } return TRUE; }
static int _handle_legacy(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *type, *name; /* delete missing handler */ xmpp_timed_handler_delete(conn, _handle_missing_legacy); /* server responded to legacy auth request */ type = xmpp_stanza_get_type(stanza); name = xmpp_stanza_get_name(stanza); if (!type || strcmp(name, "iq") != 0) { xmpp_error(conn->ctx, "xmpp", "Server sent us an unexpected response "\ "to legacy authentication request."); xmpp_disconnect(conn); } else if (strcmp(type, "error") == 0) { /* legacy client auth failed, no more fallbacks */ xmpp_error(conn->ctx, "xmpp", "Legacy client authentication failed."); xmpp_disconnect(conn); } else if (strcmp(type, "result") == 0) { /* auth succeeded */ xmpp_debug(conn->ctx, "xmpp", "Legacy auth succeeded."); conn->authenticated = 1; conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata); } else { xmpp_error(conn->ctx, "xmpp", "Server sent us a legacy authentication "\ "response with a bad type."); xmpp_disconnect(conn); } return 0; }
static int _room_config_submit_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); const char *type = xmpp_stanza_get_type(stanza); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (id != NULL) { log_debug("IQ room config submit handler fired, id: %s.", id); } else { log_debug("IQ room config submit handler fired."); } // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); handle_room_config_submit_result_error(from, error_message); free(error_message); return 0; } handle_room_config_submit_result(from); return 0; }
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 _manual_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); char *type = xmpp_stanza_get_type(stanza); // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); handle_ping_error_result(from, error_message); free(error_message); return 0; } GDateTime *sent = (GDateTime *)userdata; GDateTime *now = g_date_time_new_now_local(); GTimeSpan elapsed = g_date_time_difference(now, sent); int elapsed_millis = elapsed / 1000; g_date_time_unref(sent); g_date_time_unref(now); handle_ping_result(from, elapsed_millis); return 0; }
int handle_reply(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *query, *item; char *type, *name; type = xmpp_stanza_get_type(stanza); if (strcmp(type, "error") == 0) fprintf(stderr, "ERROR: query failed\n"); else { query = xmpp_stanza_get_child_by_name(stanza, "query"); printf("Roster:\n"); for (item = xmpp_stanza_get_children(query); item; item = xmpp_stanza_get_next(item)) if ((name = xmpp_stanza_get_attribute(item, "name"))) printf("\t %s (%s) sub=%s\n", name, xmpp_stanza_get_attribute(item, "jid"), xmpp_stanza_get_attribute(item, "subscription")); else printf("\t %s sub=%s\n", xmpp_stanza_get_attribute(item, "jid"), xmpp_stanza_get_attribute(item, "subscription")); printf("END OF LIST\n"); } /* disconnect */ xmpp_disconnect(conn); return 0; }
static void _muc_user_handler(xmpp_stanza_t *const stanza) { inp_nonblocking(TRUE); const char *type = xmpp_stanza_get_type(stanza); // handler still fires if error if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { return; } const char *from = xmpp_stanza_get_from(stanza); if (!from) { log_warning("MUC User stanza received with no from attribute"); return; } Jid *from_jid = jid_create(from); if (from_jid == NULL || from_jid->resourcepart == NULL) { log_warning("MUC User stanza received with invalid from attribute: %s", from); jid_destroy(from_jid); return; } jid_destroy(from_jid); if (stanza_is_muc_self_presence(stanza, connection_get_fulljid())) { _muc_user_self_handler(stanza); } else { _muc_user_occupant_handler(stanza); } }
static int _on_room_info(xmpp_ua_t *ua, xmpp_stanza_t * const stanza, void * const userdata) { room_info_data *info_data = (room_info_data *)userdata; char *type = xmpp_stanza_get_type(stanza); if (strcmp(type, "result")) { info_data->cb(info_data->ctx, NULL, -2, info_data->user_data); free(info_data); return 1; } xmpp_stanza_t *stanza_query = xmpp_stanza_get_child_by_name(stanza, "query"); if (stanza_query) { xmpp_stanza_t *stanza_identity = xmpp_stanza_get_child_by_name(stanza_query, "identity"); if (stanza_identity) { char *room_desc = xmpp_stanza_get_attribute(stanza_identity, "name"); info_data->cb(info_data->ctx, room_desc, 0, info_data->user_data); free(info_data); return 1; } } info_data->cb(info_data->ctx, NULL, -1, info_data->user_data); free(info_data); return 1; }
static int zkmuc_group_msg_handler(xmpp_ua_t *ua, xmpp_stanza_t *stanza, void *userdata) { char *type = xmpp_stanza_get_type(stanza); if (type && !strcmp(type, "groupchat")) { zkmuc_ctx_t *ctx = (zkmuc_ctx_t *)userdata; // char *from = xmpp_stanza_get_attribute(stanza, "from"); xmpp_stanza_t *stanza_body = xmpp_stanza_get_child_by_name(stanza, "zonekey"); if (!stanza_body) { return 0; } xmpp_stanza_t *stanza_jid = xmpp_stanza_get_child_by_name(stanza_body, "jid"); char *jid_value = xmpp_stanza_get_text(stanza_jid); char *text = xmpp_stanza_get_text(stanza_body); if (text && ctx->room_cbs.on_broadcast_message) { ctx->room_cbs.on_broadcast_message(ctx, /*from*/jid_value, text, ctx->room_data); } xmpp_free(_xmpp_ctx, jid_value); xmpp_free(_xmpp_ctx, text); return 1; } return 0; }
/** * This handles a status response iq be printing it out */ int PresenceHandler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { // xmpp_stanza_t *reply; char *type; // char *id; char *sender; xmpp_ctx_t *ctx = (xmpp_ctx_t *) userdata; sdvpIdleCounter = 0; sdvpPingsSent = 0; // type is NULL if initial presence is received type = xmpp_stanza_get_type(stanza); if (type != NULL ) { if (strcmp(type, "error") == 0) { syslog(LOG_WARNING, "ERROR: Received presence with type of error\n"); } else { // id = xmpp_stanza_get_id(stanza); sender = xmpp_stanza_get_attribute(stanza, "from"); // reply = xmpp_stanza_new(ctx); // xmpp_stanza_set_name(reply, "presence"); // xmpp_stanza_set_type(reply, "result"); // if (id != NULL ) { // xmpp_stanza_set_id(reply, id); // } // xmpp_stanza_set_attribute(reply, "to", sender); // xmpp_send(conn, reply); // xmpp_stanza_release(reply); } } else { // id = xmpp_stanza_get_id(stanza); sender = strdup(xmpp_stanza_get_attribute(stanza, "from")); // Check if the presence is from the server user char *senderUsername; senderUsername = GetUsernameFromJid(sender); if (strcmp(sdvpServerUsername, senderUsername) == 0) { sdvpServerFullJid = strdup(sender); // Send status-request _SendRpcCall(conn, ctx, sdvpServerFullJid); } free(sender); // Dont send reply as the server should do this automatically // to all connected users on the roster // reply = xmpp_stanza_new(ctx); // xmpp_stanza_set_name(reply, "presence"); // xmpp_stanza_set_type(reply, "result"); // if (id != NULL ) { // xmpp_stanza_set_id(reply, id); // } // xmpp_stanza_set_attribute(reply, "to", sender); // xmpp_send(conn, reply); // xmpp_stanza_release(reply); } return 1; }
static int _room_config_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); const char *type = xmpp_stanza_get_type(stanza); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (id != NULL) { log_debug("IQ room config handler fired, id: %s.", id); } else { log_debug("IQ room config handler fired."); } // handle error responses if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { char *error_message = stanza_get_error_message(stanza); handle_room_configuration_form_error(from, error_message); free(error_message); return 0; } if (from == NULL) { log_warning("No from attribute for IQ config request result"); handle_room_configuration_form_error(from, "No from attribute for room cofig response."); return 0; } xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); if (query == NULL) { log_warning("No query element found parsing room config response"); handle_room_configuration_form_error(from, "No query element found parsing room config response"); return 0; } xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA); if (x == NULL) { log_warning("No x element found with %s namespace parsing room config response", STANZA_NS_DATA); handle_room_configuration_form_error(from, "No form configuration options available"); return 0; } char *form_type = xmpp_stanza_get_attribute(x, STANZA_ATTR_TYPE); if (g_strcmp0(form_type, "form") != 0) { log_warning("x element not of type 'form' parsing room config response"); handle_room_configuration_form_error(from, "Form not of type 'form' parsing room config response."); return 0; } DataForm *form = form_create(x); handle_room_configure(from, form); return 0; }
static int _presence_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) { log_debug("Presence stanza handler fired"); char *text = NULL; size_t text_size; xmpp_stanza_to_text(stanza, &text, &text_size); gboolean cont = plugins_on_presence_stanza_receive(text); xmpp_free(connection_get_ctx(), text); if (!cont) { return 1; } const char *type = xmpp_stanza_get_type(stanza); if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { _presence_error_handler(stanza); } if (g_strcmp0(type, STANZA_TYPE_UNAVAILABLE) == 0) { _unavailable_handler(stanza); } if (g_strcmp0(type, STANZA_TYPE_SUBSCRIBE) == 0) { _subscribe_handler(stanza); } if (g_strcmp0(type, STANZA_TYPE_SUBSCRIBED) == 0) { _subscribed_handler(stanza); } if (g_strcmp0(type, STANZA_TYPE_UNSUBSCRIBED) == 0) { _unsubscribed_handler(stanza); } xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); if (mucuser) { _muc_user_handler(stanza); } _available_handler(stanza); return 1; }
static int zkmuc_unlock_room_result(xmpp_ua_t *ua, xmpp_stanza_t *stanza, void *userdata) { zkmuc_ctx_t *ctx = (zkmuc_ctx_t *)userdata; char *type = xmpp_stanza_get_type(stanza); if (!strcmp("result", type)) { if (ctx->room_cbs.on_room_result) { ctx->room_cbs.on_room_result(ctx, 0, ctx->room_data); } } else { _zkmuc_destroy_room(xmpp_stanza_get_attribute(stanza, "from"), ctx->ua); if (ctx->room_cbs.on_room_result) { ctx->room_cbs.on_room_result(ctx, -1, ctx->room_data); } } return 1; }
static int _zkmse_receive_rsp(xmpp_ua_t *ua, xmpp_stanza_t *stanza, void *userdata) { char *type = xmpp_stanza_get_type(stanza); if (!type || strcmp(type, "chat")) return 0; char *from = xmpp_stanza_get_attribute(stanza, "from"); if (!from) return 0; xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, "body"); if (!body) return 0; char *str_body = xmpp_stanza_get_text(body); if (!str_body) return 0; char cmd_type[16]; char result[128]; char *option = (char *)malloc(strlen(str_body)); int msg_id; int rc = sscanf(str_body, "%15[^|]|%d|%*[^|]|%127[^|]|%[^\0]", cmd_type, &msg_id, result, option); if (rc < 4) { free(option); return 0; } if (!strcmp(cmd_type, "AckCmd")) { WaitForSingleObject(ua->mutex_4_ua, INFINITE); mse_cmd_map::iterator iter = ua->mse_map.find(msg_id); if (iter == ua->mse_map.end()) { free(option); ReleaseMutex(ua->mutex_4_ua); return 0; } mse_cmd_data data = iter->second; data.cb(ua, from, result, option, data.userdata); free(option); ReleaseMutex(ua->mutex_4_ua); return 1; } free(option); return 0; }
static int _blocklist_result_handler(xmpp_stanza_t *const stanza, void *const userdata) { log_info("Blocked list result handler fired."); const char *type = xmpp_stanza_get_type(stanza); if (g_strcmp0(type, "result") != 0) { log_info("Received blocklist without result type"); return 0; } xmpp_stanza_t *blocklist = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BLOCKLIST); if (!blocklist) { log_info("Received blocklist without blocklist element"); return 0; } if (blocked) { g_list_free_full(blocked, free); blocked = NULL; } xmpp_stanza_t *items = xmpp_stanza_get_children(blocklist); if (!items) { log_info("No blocked users."); return 0; } xmpp_stanza_t *curr = items; while (curr) { const char *name = xmpp_stanza_get_name(curr); if (g_strcmp0(name, "item") == 0) { const char *jid = xmpp_stanza_get_attribute(curr, STANZA_ATTR_JID); if (jid) { blocked = g_list_append(blocked, strdup(jid)); autocomplete_add(blocked_ac, jid); } } curr = xmpp_stanza_get_next(curr); } return 0; }
//TODO: Create structure for holding the roster static int _HandleRosterReply(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *query, *item, *group; char *type, *name, *jid, *sub, groups[200], *groupName; char *g; int r_count = 0; sdvpIdleCounter = 0; sdvpPingsSent = 0; type = xmpp_stanza_get_type(stanza); if (strcmp(type, "error") == 0) { syslog(LOG_WARNING, "ERROR: query failed\n"); } else { query = xmpp_stanza_get_child_by_name(stanza, "query"); syslog(LOG_INFO, "Roster (Only the first group is shown!):\n----------\n"); for (item = xmpp_stanza_get_children(query); item; item = xmpp_stanza_get_next(item)) { name = xmpp_stanza_get_attribute(item, "name"); jid = xmpp_stanza_get_attribute(item, "jid"); sub = xmpp_stanza_get_attribute(item, "subscription"); // Get groups // strcpy(groups, "-"); for (group = xmpp_stanza_get_children(item); group; group = xmpp_stanza_get_next(group)) { groupName = xmpp_stanza_get_name(group); if (strcmp(groupName, "group") == 0) { g = xmpp_stanza_get_text(group); strcpy(groups, g); free(g); } } syslog(LOG_INFO, "#%d\tName=%s\n\tJID=%s\n\tsubscription=%s\n\tGroups=%s\n\n", r_count, name, jid, sub, groups); r_count++; } syslog(LOG_INFO, "----------\n"); } return 1; }
static int _ibb_pres_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *type; type = xmpp_stanza_get_type(stanza); if (strncmp(type, "unavailable", 11) == 0) { char *from; xmpp_ibb_session_t * sess; xmpp_ibb_userdata_t * udata = (xmpp_ibb_userdata_t *) userdata; from = xmpp_stanza_get_attribute(stanza, "from"); sess = ilist_finditem_func(g_list, _find_peer, from); if (sess != NULL) { //printf("target '%s' unavailable\n", from); if (udata != NULL && udata->close_cb != NULL) udata->close_cb(sess, "result"); _ibb_session_release(sess); } } time(&glast_ping_time); return 1; }
static int mood_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { int status; char *type; mood_callback_t callback; status = 0; callback = (mood_callback_t)userdata; type = xmpp_stanza_get_type(stanza); if (strcmp(type, "error") == 0) { warnx("XEP-0092: Error"); status = 1; } else if (strcmp(type, "result") != 0) { warnx("XEP-0092: Unknown error"); status = 1; } if (callback != NULL) { callback(status); } return 0; }
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; }
int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *reply, *body, *text; char *intext, *replytext; xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata; if(!xmpp_stanza_get_child_by_name(stanza, "body")) return 1; if(!strcmp(xmpp_stanza_get_attribute(stanza, "type"), "error")) return 1; intext = xmpp_stanza_get_text(xmpp_stanza_get_child_by_name(stanza, "body")); printf("Incoming message from %s: %s\n", xmpp_stanza_get_attribute(stanza, "from"), intext); reply = xmpp_stanza_new(ctx); xmpp_stanza_set_name(reply, "message"); xmpp_stanza_set_type(reply, xmpp_stanza_get_type(stanza)?xmpp_stanza_get_type(stanza):"chat"); xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from")); body = xmpp_stanza_new(ctx); xmpp_stanza_set_name(body, "body"); //printf("intext char: %c\n", *intext); /* reply section */ if(*intext == '!') { intext++; char command[32]; int idx=0; while(idx<31 && *intext != '\0' && *intext != ' ') { command[idx] = *intext; idx++; intext++; } command[idx] = '\0'; while(*intext == ' ' && *intext != '\0') intext++; char *args = intext; if(command[0]=='\0') { replytext = strdup("you're barking mad!"); } else { // good command and args // if(!strcmp("google", command)) { char *res = google(args); replytext = malloc(snprintf(NULL, 0 , "result: %s", res)+1); sprintf(replytext, "result: %s", res); free(res); } else if(!strcmp("d20", command)) { srand(time(NULL)); int rand_int = (rand() % 20) + 1; if(rand_int == 20) { replytext = malloc(snprintf(NULL, 0, "d20: %d CRITICAL!!!", rand_int)+1); sprintf(replytext, "d20: %d CRITICAL!!!", rand_int); } else { replytext = malloc(snprintf(NULL, 0, "d20: %d", rand_int)+1); sprintf(replytext, "d20: %d", rand_int); } } else { replytext = malloc(snprintf(NULL, 0 , "command: %s args: %s", command, args)+1); sprintf(replytext, "command: %s args: %s", command, args); } } } else { if (strcmp(intext, "boob")==0) { replytext = malloc(strlen("Boobies!")+1); replytext = strcpy(replytext, "Boobies!"); } else { replytext = malloc(strlen(" to you too!") + strlen(intext) + 1); strcpy(replytext, intext); strcat(replytext, " to you too!"); } } /* end reply logic */ text = xmpp_stanza_new(ctx); xmpp_stanza_set_text(text, replytext); xmpp_stanza_add_child(body, text); xmpp_stanza_add_child(reply, body); xmpp_send(conn, reply); xmpp_stanza_release(reply); free(replytext); return 1; }
static int _handle_bind(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *type; xmpp_stanza_t *iq, *session; /* delete missing bind handler */ xmpp_timed_handler_delete(conn, _handle_missing_bind); /* server has replied to bind request */ type = xmpp_stanza_get_type(stanza); if (type && strcmp(type, "error") == 0) { xmpp_error(conn->ctx, "xmpp", "Binding failed."); xmpp_disconnect(conn); } else if (type && strcmp(type, "result") == 0) { xmpp_stanza_t *binding = xmpp_stanza_get_child_by_name(stanza, "bind"); xmpp_debug(conn->ctx, "xmpp", "Bind successful."); if (binding) { xmpp_stanza_t *jid_stanza = xmpp_stanza_get_child_by_name(binding, "jid"); if (jid_stanza) { conn->bound_jid = xmpp_stanza_get_text(jid_stanza); } } /* establish a session if required */ if (conn->session_required) { /* setup response handlers */ handler_add_id(conn, _handle_session, "_xmpp_session1", NULL); handler_add_timed(conn, _handle_missing_session, SESSION_TIMEOUT, NULL); /* send session request */ iq = xmpp_stanza_new(conn->ctx); if (!iq) { disconnect_mem_error(conn); return 0; } xmpp_stanza_set_name(iq, "iq"); xmpp_stanza_set_type(iq, "set"); xmpp_stanza_set_id(iq, "_xmpp_session1"); session = xmpp_stanza_new(conn->ctx); if (!session) { xmpp_stanza_release(iq); disconnect_mem_error(conn); } xmpp_stanza_set_name(session, "session"); xmpp_stanza_set_ns(session, XMPP_NS_SESSION); xmpp_stanza_add_child(iq, session); xmpp_stanza_release(session); /* send session establishment request */ xmpp_send(conn, iq); xmpp_stanza_release(iq); } else { conn->authenticated = 1; /* call connection handler */ conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata); } } else { xmpp_error(conn->ctx, "xmpp", "Server sent malformed bind reply."); xmpp_disconnect(conn); } return 0; }
static int _chat_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) { // ignore if type not chat or absent char *type = xmpp_stanza_get_type(stanza); if (!(g_strcmp0(type, "chat") == 0 || type == NULL)) { return 1; } // check if carbon message gboolean res = _handle_carbons(stanza); if (res) { return 1; } // ignore handled namespaces xmpp_stanza_t *conf = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE); xmpp_stanza_t *captcha = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CAPTCHA); if (conf || captcha) { return 1; } // some clients send the mucuser namespace with private messages // if the namespace exists, and the stanza contains a body element, assume its a private message // otherwise exit the handler xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY); if (mucuser && body == NULL) { return 1; } gchar *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); Jid *jid = jid_create(from); // private message from chat room use full jid (room/nick) if (muc_active(jid->barejid)) { _private_chat_handler(stanza, jid->fulljid); jid_destroy(jid); return 1; } // standard chat message, use jid without resource xmpp_ctx_t *ctx = connection_get_ctx(); GDateTime *timestamp = stanza_get_delay(stanza); if (body) { char *message = xmpp_stanza_get_text(body); if (message) { char *enc_message = NULL; xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_ENCRYPTED); if (x) { enc_message = xmpp_stanza_get_text(x); } sv_ev_incoming_message(jid->barejid, jid->resourcepart, message, enc_message, timestamp); xmpp_free(ctx, enc_message); _receipt_request_handler(stanza); xmpp_free(ctx, message); } } // handle chat sessions and states if (!timestamp && jid->resourcepart) { gboolean gone = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_GONE) != NULL; gboolean typing = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_COMPOSING) != NULL; gboolean paused = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PAUSED) != NULL; gboolean inactive = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_INACTIVE) != NULL; if (gone) { sv_ev_gone(jid->barejid, jid->resourcepart); } else if (typing) { sv_ev_typing(jid->barejid, jid->resourcepart); } else if (paused) { sv_ev_paused(jid->barejid, jid->resourcepart); } else if (inactive) { sv_ev_inactive(jid->barejid, jid->resourcepart); } else if (stanza_contains_chat_state(stanza)) { sv_ev_activity(jid->barejid, jid->resourcepart, TRUE); } else { sv_ev_activity(jid->barejid, jid->resourcepart, FALSE); } } if (timestamp) g_date_time_unref(timestamp); jid_destroy(jid); return 1; }
static int _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { // handler still fires if error if (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_ERROR) == 0) { return 1; } char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); Jid *from_jid = jid_create(from); if (from_jid == NULL || from_jid->resourcepart == NULL) { return 1; } char *from_room = from_jid->barejid; char *from_nick = from_jid->resourcepart; // handle self presence if (stanza_is_muc_self_presence(stanza, jabber_get_fulljid())) { char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE); char *new_nick = stanza_get_new_nick(stanza); if ((type != NULL) && (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0)) { // leave room if not self nick change if (new_nick != NULL) { muc_set_room_pending_nick_change(from_room, new_nick); } else { handle_leave_room(from_room); } // handle self nick change } else if (muc_is_room_pending_nick_change(from_room)) { muc_complete_room_nick_change(from_room, from_nick); handle_room_nick_change(from_room, from_nick); // handle roster complete } else if (!muc_get_roster_received(from_room)) { handle_room_roster_complete(from_room); // room configuration required if (stanza_muc_requires_config(stanza)) { handle_room_requires_config(from_room); } } // handle presence from room members } else { char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE); char *status_str; log_debug("Room presence received from %s", from_jid->fulljid); status_str = stanza_get_status(stanza, NULL); if ((type != NULL) && (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0)) { // handle nickname change if (stanza_is_room_nick_change(stanza)) { char *new_nick = stanza_get_new_nick(stanza); if (new_nick != NULL) { muc_set_roster_pending_nick_change(from_room, new_nick, from_nick); free(new_nick); } } else { handle_room_member_offline(from_room, from_nick, "offline", status_str); } } else { // send disco info for capabilities, if not cached if (stanza_contains_caps(stanza)) { log_info("Presence contains capabilities."); _handle_caps(stanza); } char *show_str = stanza_get_show(stanza, "online"); if (!muc_get_roster_received(from_room)) { muc_add_to_roster(from_room, from_nick, show_str, status_str); } else { char *old_nick = muc_complete_roster_nick_change(from_room, from_nick); if (old_nick != NULL) { muc_add_to_roster(from_room, from_nick, show_str, status_str); handle_room_member_nick_change(from_room, old_nick, from_nick); free(old_nick); } else { if (!muc_nick_in_roster(from_room, from_nick)) { handle_room_member_online(from_room, from_nick, show_str, status_str); } else { handle_room_member_presence(from_room, from_nick, show_str, status_str); } } } free(show_str); } free(status_str); } jid_destroy(from_jid); return 1; }
static int _available_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { // handler still fires if error if (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_ERROR) == 0) { return 1; } // handler still fires if other types if ((g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_UNAVAILABLE) == 0) || (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBE) == 0) || (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBED) == 0) || (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_UNSUBSCRIBED) == 0)) { return 1; } // handler still fires for muc presence if (stanza_is_muc_presence(stanza)) { return 1; } char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (from) { log_info("Available presence handler fired for: %s", from); } else { log_info("Available presence handler fired"); } // exit when no from attribute if (!from) { log_warning("No from attribute found."); return 1; } // own jid is invalid const char *my_jid_str = xmpp_conn_get_jid(conn); Jid *my_jid = jid_create(my_jid_str); if (!my_jid) { if (my_jid_str) { log_error("Could not parse account JID: %s", my_jid_str); } else { log_error("Could not parse account JID: NULL"); } return 1; } // contact jid invalud Jid *from_jid = jid_create(from); if (!from_jid) { log_warning("Could not parse contact JID: %s", from); jid_destroy(my_jid); return 1; } // presence properties char *show_str = stanza_get_show(stanza, "online"); char *status_str = stanza_get_status(stanza, NULL); // presence last activity int idle_seconds = stanza_get_idle_time(stanza); GDateTime *last_activity = NULL; if (idle_seconds > 0) { GDateTime *now = g_date_time_new_now_local(); last_activity = g_date_time_add_seconds(now, 0 - idle_seconds); g_date_time_unref(now); } // priority int priority = 0; xmpp_stanza_t *priority_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PRIORITY); if (priority_stanza != NULL) { char *priority_str = xmpp_stanza_get_text(priority_stanza); if (priority_str != NULL) { priority = atoi(priority_str); } free(priority_str); } // send disco info for capabilities, if not cached if ((g_strcmp0(my_jid->fulljid, from_jid->fulljid) != 0) && (stanza_contains_caps(stanza))) { log_info("Presence contains capabilities."); _handle_caps(stanza); } // create Resource Resource *resource = NULL; resource_presence_t presence = resource_presence_from_string(show_str); if (from_jid->resourcepart == NULL) { // hack for servers that do not send full jid resource = resource_new("__prof_default", presence, status_str, priority); } else { resource = resource_new(from_jid->resourcepart, presence, status_str, priority); } free(status_str); free(show_str); // check for self presence if (g_strcmp0(my_jid->barejid, from_jid->barejid) == 0) { connection_add_available_resource(resource); // contact presence } else { handle_contact_online(from_jid->barejid, resource, last_activity); } if (last_activity != NULL) { g_date_time_unref(last_activity); } jid_destroy(my_jid); jid_destroy(from_jid); return 1; }