gboolean stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, const char * const self_jid) { if (stanza == NULL) { return FALSE; } if (strcmp(xmpp_stanza_get_name(stanza), STANZA_NAME_PRESENCE) != 0) { return FALSE; } xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); if (x == NULL) { return FALSE; } char *ns = xmpp_stanza_get_ns(x); if (ns == NULL) { return FALSE; } if (strcmp(ns, STANZA_NS_MUC_USER) != 0) { return FALSE; } xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); if (x_children == NULL) { return FALSE; } while (x_children != NULL) { if (strcmp(xmpp_stanza_get_name(x_children), STANZA_NAME_STATUS) == 0) { char *code = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_CODE); if (strcmp(code, "110") == 0) { return TRUE; } } x_children = xmpp_stanza_get_next(x_children); } // for older server that don't send status 110 x_children = xmpp_stanza_get_children(x); while (x_children != NULL) { if (strcmp(xmpp_stanza_get_name(x_children), STANZA_NAME_ITEM) == 0) { char *jid = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_JID); if (jid != NULL) { if (g_str_has_prefix(jid, self_jid)) { return TRUE; } } } x_children = xmpp_stanza_get_next(x_children); } return FALSE; }
int blocked_set_handler(xmpp_stanza_t *stanza) { xmpp_stanza_t *block = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BLOCK); if (block) { xmpp_stanza_t *child = xmpp_stanza_get_children(block); while (child) { if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_ITEM) == 0) { const char *jid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID); if (jid) { blocked = g_list_append(blocked, strdup(jid)); autocomplete_add(blocked_ac, jid); } } child = xmpp_stanza_get_next(child); } } xmpp_stanza_t *unblock = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_UNBLOCK); if (unblock) { xmpp_stanza_t *child = xmpp_stanza_get_children(unblock); if (!child) { g_list_free_full(blocked, free); blocked = NULL; autocomplete_clear(blocked_ac); } else { while (child) { if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_ITEM) == 0) { const char *jid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID); if (jid) { GList *found = g_list_find_custom(blocked, jid, (GCompareFunc)g_strcmp0); if (found) { blocked = g_list_remove_link(blocked, found); g_list_free_full(found, free); autocomplete_remove(blocked_ac, jid); } } } child = xmpp_stanza_get_next(child); } } } return 1; }
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 int _zkmuc_on_source_query(xmpp_ua_t *ua, xmpp_stanza_t *stanza, void *userdata) { query_source_data *data = (query_source_data *)userdata; char *from = xmpp_stanza_get_attribute(stanza, "from"); xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, "x"); xmpp_stanza_t *item = xmpp_stanza_get_children(x); zkmuc_source_t *head = NULL; zkmuc_source_t **current = &head; while (item) { if (!strcmp("item", xmpp_stanza_get_name(item))) { *current = (zkmuc_source_t *)malloc(sizeof(zkmuc_source_t)); (*current)->cid = atoi(xmpp_stanza_get_attribute(item, "cid")); (*current)->sid = atoi(xmpp_stanza_get_attribute(item, "sid")); (*current)->description = strdup(xmpp_stanza_get_attribute(item, "desc")); (*current)->mcu = strdup(xmpp_stanza_get_attribute(item, "mcu")); current = &(*current)->next; } item = xmpp_stanza_get_next(item); } *current = NULL; data->cb(data->ctx, from, data->userdata, head); _zkmuc_free_all_remote_source(head); free(data); return 1; }
static void files_list(xmpp_stanza_t *stanza) { int rc; /* Return code */ rc = pthread_mutex_lock(&mutex); wsyserr(rc != 0, "pthread_mutex_lock"); char *error_attr = xmpp_stanza_get_attribute(stanza, "error"); /* error attribute */ wfatal(error_attr == NULL, "no error attribute in files stanza"); if (strcmp(error_attr, "0") != 0) { wlog("Error in attributes: %s", error_attr); } else { char *path_attr = xmpp_stanza_get_attribute(stanza, "path"); /* path attribute */ wfatal(path_attr == NULL, "xmpp_stanza_get_attribute [attribute = path]"); xmpp_stanza_t *child = xmpp_stanza_get_children(stanza); while (child != NULL) { elem_t *elem = (elem_t *)malloc(sizeof(elem_t)); wsyserr(elem == NULL, "malloc"); elem->next = NULL; char *name = xmpp_stanza_get_name(child); wfatal(name == NULL, "xmpp_stanza_get_name"); if (strcmp(name, "directory") == 0) { elem->type = DIR; } else if (strcmp(name, "file") == 0) { elem->type = REG; } else { werr("Unknown name: %s", name); } char *filename_attr = xmpp_stanza_get_attribute(child, "filename"); wfatal(filename_attr == NULL, "xmpp_stanza_get_attribute [attribute = filename]"); elem->filename = strdup(filename_attr); wsyserr(elem->filename == NULL, "strdup"); /* Add elem in list */ if (root == NULL) { root = elem; } else { last->next = elem; } last = elem; child = xmpp_stanza_get_next(child); } } /* Data set */ signal_list = true; rc = pthread_cond_signal(&cond); wsyserr(rc != 0, "pthread_cond_signal"); rc = pthread_mutex_unlock(&mutex); wsyserr(rc != 0, "pthread_mutex_unlock"); }
/** * Creates the parameter structure for the Read callback * @param[in] params This stanza is the params element in the XML-RPC format * @return The structure or null if an error were found. */ static sdvp_ReadParam_t* _CreateReadParam (xmpp_stanza_t * params) { const int expectedParams = 1; sdvp_ReadParam_t* rv = NULL; int i = 0; bool elementNotFund = false; xmpp_stanza_t *structure = NULL, *member = NULL, *value = NULL, *type = NULL, *name = NULL; char *text, *textname; structure = _GetRpcStructureElementFromParams(params); if (structure == NULL ) { return NULL ; } rv = _InitiateReadParameters(); for (member = xmpp_stanza_get_children(structure); member && !elementNotFund && (i < expectedParams); member = xmpp_stanza_get_next(member)) { if (xmpp_stanza_get_name(member) && strcmp(xmpp_stanza_get_name(member), "member") == 0) { if (!(name = xmpp_stanza_get_child_by_name(member, "name"))) { _FreeReadParameters(rv); // TODO: Signal error back return NULL ; } name = xmpp_stanza_get_children(name); textname = xmpp_stanza_get_text(name); if (strcmp(textname, "VariableAccessSpecification") == 0) { if (!(value = xmpp_stanza_get_child_by_name(member, "value"))) { _FreeReadParameters(rv); // TODO: Signal error back free(textname); return NULL ; } if ((type = xmpp_stanza_get_child_by_name(value, "string"))) { if (xmpp_stanza_get_children(type)) { text = xmpp_stanza_get_text(type); rv->reference = text; } else { rv->reference = NULL; } } else { elementNotFund = true; } } else { // if (!type) { // _FreeReadParameters(rv); // return NULL ; // } } free(textname); } } return rv; }
//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; }
int handle_disco_items(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *query, *item; xmppipe_state_t *state = userdata; xmpp_ctx_t *ctx = state->ctx; query = xmpp_stanza_get_child_by_name(stanza, "query"); if (query == NULL) return 1; for (item = xmpp_stanza_get_children(query); item != NULL; item = xmpp_stanza_get_next(item)) { xmpp_stanza_t *iq, *reply; const char *jid = NULL; const char *name = NULL; char *id = NULL; name = xmpp_stanza_get_name(item); if (name == NULL) continue; if (XMPPIPE_STRNEQ(name, "item")) continue; jid = xmpp_stanza_get_attribute(item, "jid"); if (jid == NULL) continue; iq = xmppipe_stanza_new(ctx); xmppipe_stanza_set_name(iq, "iq"); xmppipe_stanza_set_type(iq, "get"); xmppipe_stanza_set_attribute(iq, "to", jid); id = xmpp_uuid_gen(state->ctx); if (id == NULL) { errx(EXIT_FAILURE, "unable to allocate message id"); } xmppipe_stanza_set_id(iq, id); reply = xmppipe_stanza_new(ctx); xmppipe_stanza_set_name(reply, "query"); xmppipe_stanza_set_ns(reply, "http://jabber.org/protocol/disco#info"); xmppipe_stanza_add_child(iq, reply); xmppipe_send(state, iq); (void)xmpp_stanza_release(iq); xmpp_free(state->ctx, id); } return 0; }
static int _iq_handle_discoitems_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { log_debug("Recieved diso#items response"); const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); const char *stanza_name = NULL; const char *item_jid = NULL; const char *item_name = NULL; GSList *items = NULL; if ((g_strcmp0(id, "confreq") == 0) || (g_strcmp0(id, "discoitemsreq") == 0)) { log_debug("Response to query: %s", id); xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); if (query != NULL) { xmpp_stanza_t *child = xmpp_stanza_get_children(query); while (child != NULL) { stanza_name = xmpp_stanza_get_name(child); if ((stanza_name != NULL) && (g_strcmp0(stanza_name, STANZA_NAME_ITEM) == 0)) { item_jid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID); if (item_jid != NULL) { DiscoItem *item = malloc(sizeof(struct disco_item_t)); item->jid = strdup(item_jid); item_name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME); if (item_name != NULL) { item->name = strdup(item_name); } else { item->name = NULL; } items = g_slist_append(items, item); } } child = xmpp_stanza_get_next(child); } } } if (g_strcmp0(id, "confreq") == 0) { handle_room_list(items, from); } else if (g_strcmp0(id, "discoitemsreq") == 0) { handle_disco_items(items, from); } g_slist_free_full(items, (GDestroyNotify)_item_destroy); return 1; }
int handle_disco_info(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *query, *child; const char *from = NULL; xmppipe_state_t *state = userdata; from = xmpp_stanza_get_attribute(stanza, "from"); if (from == NULL) return 1; query = xmpp_stanza_get_child_by_name(stanza, "query"); if (query == NULL) return 1; for (child = xmpp_stanza_get_children(query); child != NULL; child = xmpp_stanza_get_next(child)) { const char *feature = NULL; const char *var = NULL; feature = xmpp_stanza_get_name(child); if (feature == NULL) continue; if (XMPPIPE_STRNEQ(feature, "feature")) continue; var = xmpp_stanza_get_attribute(child, "var"); if (var == NULL) continue; if (XMPPIPE_STRNEQ(var, "http://jabber.org/protocol/muc")) continue; state->mucservice = xmppipe_strdup(from); state->out = xmppipe_conference(state->room, state->mucservice); state->mucjid = xmppipe_mucjid(state->out, state->resource); if (state->opt & XMPPIPE_OPT_GROUPCHAT) { xmppipe_muc_join(state); xmppipe_muc_unlock(state); } return 0; } return 1; }
static int _handle_features(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *child, *mech; char *text; /* remove the handler that detects missing stream:features */ xmpp_timed_handler_delete(conn, _handle_missing_features); /* check for TLS */ if (!conn->secured) { if (!conn->tls_disabled) { child = xmpp_stanza_get_child_by_name(stanza, "starttls"); if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_TLS) == 0)) conn->tls_support = 1; } else { conn->tls_support = 0; } } /* check for SASL */ child = xmpp_stanza_get_child_by_name(stanza, "mechanisms"); if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_SASL) == 0)) { for (mech = xmpp_stanza_get_children(child); mech; mech = xmpp_stanza_get_next(mech)) { if (xmpp_stanza_get_name(mech) && strcmp(xmpp_stanza_get_name(mech), "mechanism") == 0) { text = xmpp_stanza_get_text(mech); if (strcasecmp(text, "PLAIN") == 0) conn->sasl_support |= SASL_MASK_PLAIN; else if (strcasecmp(text, "DIGEST-MD5") == 0) conn->sasl_support |= SASL_MASK_DIGESTMD5; else if (strcasecmp(text, "SCRAM-SHA-1") == 0) conn->sasl_support |= SASL_MASK_SCRAMSHA1; else if (strcasecmp(text, "ANONYMOUS") == 0) conn->sasl_support |= SASL_MASK_ANONYMOUS; xmpp_free(conn->ctx, text); } } } _auth(conn); return 0; }
static int _roster_result_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); if (g_strcmp0(id, "roster") != 0) { return 1; } // handle initial roster response xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); xmpp_stanza_t *item = xmpp_stanza_get_children(query); while (item) { const char *barejid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); gchar *barejid_lower = g_utf8_strdown(barejid, -1); const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME); const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION); // do not set nickname to empty string, set to NULL instead if (name && (strlen(name) == 0)) name = NULL; gboolean pending_out = FALSE; const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK); if (g_strcmp0(ask, "subscribe") == 0) { pending_out = TRUE; } GSList *groups = _get_groups_from_item(item); gboolean added = roster_add(barejid_lower, name, groups, sub, pending_out); if (!added) { log_warning("Attempt to add contact twice: %s", barejid_lower); } g_free(barejid_lower); item = xmpp_stanza_get_next(item); } sv_ev_roster_received(); resource_presence_t conn_presence = accounts_get_login_presence(jabber_get_account_name()); cl_ev_presence_send(conn_presence, NULL, 0); return 1; }
GSList * _get_groups_from_item(xmpp_stanza_t *item) { GSList *groups = NULL; xmpp_stanza_t *group_element = xmpp_stanza_get_children(item); while (group_element) { if (strcmp(xmpp_stanza_get_name(group_element), STANZA_NAME_GROUP) == 0) { char *groupname = xmpp_stanza_get_text(group_element); if (groupname) { groups = g_slist_append(groups, groupname); } } group_element = xmpp_stanza_get_next(group_element); } return groups; }
static int _roster_result_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); // handle initial roster response if (g_strcmp0(id, "roster") == 0) { xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); xmpp_stanza_t *item = xmpp_stanza_get_children(query); while (item != NULL) { const char *barejid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME); const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION); gboolean pending_out = FALSE; const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK); if (g_strcmp0(ask, "subscribe") == 0) { pending_out = TRUE; } GSList *groups = _get_groups_from_item(item); gboolean added = roster_add(barejid, name, groups, sub, pending_out); if (!added) { log_warning("Attempt to add contact twice: %s", barejid); } item = xmpp_stanza_get_next(item); } resource_presence_t conn_presence = accounts_get_login_presence(jabber_get_account_name()); presence_update(conn_presence, NULL, 0); } return 1; }
static kvpair_t *grok_form(xmpp_stanza_t *fields) { kvpair_t *rv = NULL; /* walk the field peers and grab their values and stuff */ while (fields) { if (xmpp_stanza_is_tag(fields)) { char* k = xmpp_stanza_get_attribute(fields, "var"); char **vals = get_specific_form_values(fields, k); kvpair_t* thispair = mk_kvpair(k, vals); free_string_list(vals); thispair->next = rv; rv = thispair; } fields = xmpp_stanza_get_next(fields); } return rv; }
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; }
gboolean stanza_is_room_nick_change(xmpp_stanza_t * const stanza) { if (stanza == NULL) { return FALSE; } if (strcmp(xmpp_stanza_get_name(stanza), STANZA_NAME_PRESENCE) != 0) { return FALSE; } xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); if (x == NULL) { return FALSE; } char *ns = xmpp_stanza_get_ns(x); if (ns == NULL) { return FALSE; } if (strcmp(ns, STANZA_NS_MUC_USER) != 0) { return FALSE; } xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); if (x_children == NULL) { return FALSE; } while (x_children != NULL) { if (strcmp(xmpp_stanza_get_name(x_children), STANZA_NAME_STATUS) == 0) { char *code = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_CODE); if (strcmp(code, "303") == 0) { return TRUE; } } x_children = xmpp_stanza_get_next(x_children); } return FALSE; }
char * stanza_get_new_nick(xmpp_stanza_t * const stanza) { if (!stanza_is_room_nick_change(stanza)) { return NULL; } else { xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); while (x_children != NULL) { if (strcmp(xmpp_stanza_get_name(x_children), STANZA_NAME_ITEM) == 0) { char *nick = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_NICK); if (nick != NULL) { return strdup(nick); } } x_children = xmpp_stanza_get_next(x_children); } return NULL; } }
static int _bookmark_handle_result(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) { xmpp_ctx_t *ctx = connection_get_ctx(); char *id = (char *)userdata; xmpp_stanza_t *ptr; xmpp_stanza_t *nick; xmpp_stanza_t *password_st; char *name; char *jid; char *autojoin; char *password; gboolean autojoin_val; Jid *my_jid; Bookmark *item; xmpp_timed_handler_delete(conn, _bookmark_handle_delete); g_free(id); name = xmpp_stanza_get_name(stanza); if (!name || strcmp(name, STANZA_NAME_IQ) != 0) { return 0; } ptr = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); if (!ptr) { return 0; } ptr = xmpp_stanza_get_child_by_name(ptr, STANZA_NAME_STORAGE); if (!ptr) { return 0; } if (bookmark_ac == NULL) { bookmark_ac = autocomplete_new(); } my_jid = jid_create(jabber_get_fulljid()); ptr = xmpp_stanza_get_children(ptr); while (ptr) { name = xmpp_stanza_get_name(ptr); if (!name || strcmp(name, STANZA_NAME_CONFERENCE) != 0) { ptr = xmpp_stanza_get_next(ptr); continue; } jid = xmpp_stanza_get_attribute(ptr, STANZA_ATTR_JID); if (!jid) { ptr = xmpp_stanza_get_next(ptr); continue; } log_debug("Handle bookmark for %s", jid); name = NULL; nick = xmpp_stanza_get_child_by_name(ptr, "nick"); if (nick) { char *tmp; tmp = xmpp_stanza_get_text(nick); if (tmp) { name = strdup(tmp); xmpp_free(ctx, tmp); } } password = NULL; password_st = xmpp_stanza_get_child_by_name(ptr, "password"); if (password_st) { char *tmp; tmp = xmpp_stanza_get_text(password_st); if (tmp) { password = strdup(tmp); xmpp_free(ctx, tmp); } } autojoin = xmpp_stanza_get_attribute(ptr, "autojoin"); if (autojoin && (strcmp(autojoin, "1") == 0 || strcmp(autojoin, "true") == 0)) { autojoin_val = TRUE; } else { autojoin_val = FALSE; } autocomplete_add(bookmark_ac, jid); item = malloc(sizeof(*item)); item->jid = strdup(jid); item->nick = name; item->password = password; item->autojoin = autojoin_val; bookmark_list = g_list_append(bookmark_list, item); if (autojoin_val) { Jid *room_jid; char *account_name = jabber_get_account_name(); ProfAccount *account = accounts_get_account(account_name); if (name == NULL) { name = account->muc_nick; } log_debug("Autojoin %s with nick=%s", jid, name); room_jid = jid_create_from_bare_and_resource(jid, name); if (!muc_active(room_jid->barejid)) { presence_join_room(jid, name, password); muc_join(jid, name, password, TRUE); } jid_destroy(room_jid); account_free(account); } ptr = xmpp_stanza_get_next(ptr); } jid_destroy(my_jid); return 0; }
static int _iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { log_debug("Recieved diso#info response"); const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (g_strcmp0(id, "discoinforeq") == 0) { GSList *identities = NULL; GSList *features = NULL; xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); if (query != NULL) { xmpp_stanza_t *child = xmpp_stanza_get_children(query); while (child != NULL) { const char *stanza_name = xmpp_stanza_get_name(child); if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) { const char *var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR); if (var != NULL) { features = g_slist_append(features, strdup(var)); } } else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) { const char *name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME); const char *type = xmpp_stanza_get_attribute(child, STANZA_ATTR_TYPE); const char *category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY); if ((name != NULL) || (category != NULL) || (type != NULL)) { DiscoIdentity *identity = malloc(sizeof(struct disco_identity_t)); if (name != NULL) { identity->name = strdup(name); } else { identity->name = NULL; } if (category != NULL) { identity->category = strdup(category); } else { identity->category = NULL; } if (type != NULL) { identity->type = strdup(type); } else { identity->type = NULL; } identities = g_slist_append(identities, identity); } } child = xmpp_stanza_get_next(child); } handle_disco_info(from, identities, features); g_slist_free_full(features, free); g_slist_free_full(identities, (GDestroyNotify)_identity_destroy); } } else if ((id != NULL) && (g_str_has_prefix(id, "capsreq"))) { log_debug("Response to query: %s", id); xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE); if (node == NULL) { return 1; } char *caps_key = NULL; // xep-0115 if (g_strcmp0(id, "capsreq") == 0) { log_debug("xep-0115 supported capabilities"); caps_key = strdup(node); // validate sha1 gchar **split = g_strsplit(node, "#", -1); char *given_sha1 = split[1]; char *generated_sha1 = caps_create_sha1_str(query); if (g_strcmp0(given_sha1, generated_sha1) != 0) { log_info("Generated sha-1 does not match given:"); log_info("Generated : %s", generated_sha1); log_info("Given : %s", given_sha1); g_free(generated_sha1); g_strfreev(split); free(caps_key); return 1; } g_free(generated_sha1); g_strfreev(split); // non supported hash, or legacy caps } else { log_debug("Unsupported hash, or legacy capabilities"); caps_key = strdup(id + 8); log_debug("Caps key: %s", caps_key); } // already cached if (caps_contains(caps_key)) { log_info("Client info already cached."); free(caps_key); return 1; } log_debug("Client info not cached"); const char *category = NULL; const char *type = NULL; const char *name = NULL; const char *software = NULL; const char *software_version = NULL; const char *os = NULL; const char *os_version = NULL; GSList *features = NULL; xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity"); if (identity != NULL) { category = xmpp_stanza_get_attribute(identity, "category"); type = xmpp_stanza_get_attribute(identity, "type"); name = xmpp_stanza_get_attribute(identity, "name"); } xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA); if (softwareinfo != NULL) { DataForm *form = stanza_create_form(softwareinfo); FormField *formField = NULL; if (g_strcmp0(form->form_type, STANZA_DATAFORM_SOFTWARE) == 0) { GSList *field = form->fields; while (field != NULL) { formField = field->data; if (formField->values != NULL) { if (strcmp(formField->var, "software") == 0) { software = formField->values->data; } else if (strcmp(formField->var, "software_version") == 0) { software_version = formField->values->data; } else if (strcmp(formField->var, "os") == 0) { os = formField->values->data; } else if (strcmp(formField->var, "os_version") == 0) { os_version = formField->values->data; } } field = g_slist_next(field); } } stanza_destroy_form(form); } xmpp_stanza_t *child = xmpp_stanza_get_children(query); while (child != NULL) { if (g_strcmp0(xmpp_stanza_get_name(child), "feature") == 0) { features = g_slist_append(features, strdup(xmpp_stanza_get_attribute(child, "var"))); } child = xmpp_stanza_get_next(child); } caps_add(caps_key, category, type, name, software, software_version, os, os_version, features); free(caps_key); } return 1; }
char * caps_create_sha1_str(xmpp_stanza_t * const query) { char *category = NULL; char *type = NULL; char *lang = NULL; char *name = NULL; char *feature_str = NULL; GSList *identities = NULL; GSList *features = NULL; GSList *form_names = NULL; DataForm *form = NULL; FormField *field = NULL; GHashTable *forms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)form_destroy); xmpp_stanza_t *child = xmpp_stanza_get_children(query); while (child) { if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_IDENTITY) == 0) { category = xmpp_stanza_get_attribute(child, "category"); type = xmpp_stanza_get_attribute(child, "type"); lang = xmpp_stanza_get_attribute(child, "xml:lang"); name = xmpp_stanza_get_attribute(child, "name"); GString *identity_str = g_string_new(category); g_string_append(identity_str, "/"); if (type) { g_string_append(identity_str, type); } g_string_append(identity_str, "/"); if (lang) { g_string_append(identity_str, lang); } g_string_append(identity_str, "/"); if (name) { g_string_append(identity_str, name); } g_string_append(identity_str, "<"); identities = g_slist_insert_sorted(identities, g_strdup(identity_str->str), (GCompareFunc)strcmp); g_string_free(identity_str, TRUE); } else if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_FEATURE) == 0) { feature_str = xmpp_stanza_get_attribute(child, "var"); features = g_slist_insert_sorted(features, g_strdup(feature_str), (GCompareFunc)strcmp); } else if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_X) == 0) { if (g_strcmp0(xmpp_stanza_get_ns(child), STANZA_NS_DATA) == 0) { form = form_create(child); char *form_type = form_get_form_type_field(form); form_names = g_slist_insert_sorted(form_names, g_strdup(form_type), (GCompareFunc)strcmp); g_hash_table_insert(forms, g_strdup(form_type), form); } } child = xmpp_stanza_get_next(child); } GString *s = g_string_new(""); GSList *curr = identities; while (curr) { g_string_append(s, curr->data); curr = g_slist_next(curr); } curr = features; while (curr) { g_string_append(s, curr->data); g_string_append(s, "<"); curr = g_slist_next(curr); } curr = form_names; while (curr) { form = g_hash_table_lookup(forms, curr->data); char *form_type = form_get_form_type_field(form); g_string_append(s, form_type); g_string_append(s, "<"); GSList *sorted_fields = form_get_non_form_type_fields_sorted(form); GSList *curr_field = sorted_fields; while (curr_field) { field = curr_field->data; g_string_append(s, field->var); g_string_append(s, "<"); GSList *sorted_values = form_get_field_values_sorted(field); GSList *curr_value = sorted_values; while (curr_value) { g_string_append(s, curr_value->data); g_string_append(s, "<"); curr_value = g_slist_next(curr_value); } g_slist_free(sorted_values); curr_field = g_slist_next(curr_field); } g_slist_free(sorted_fields); curr = g_slist_next(curr); } char *result = p_sha1_hash(s->str); g_string_free(s, TRUE); g_slist_free_full(identities, g_free); g_slist_free_full(features, g_free); g_slist_free_full(form_names, g_free); g_hash_table_destroy(forms); return result; }
static int _bookmark_handle_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ctx_t *ctx = connection_get_ctx(); char *id = (char *)userdata; xmpp_stanza_t *ptr; xmpp_stanza_t *nick; char *name; char *jid; char *autojoin; gboolean autojoin_val; Jid *my_jid; Bookmark *item; xmpp_timed_handler_delete(conn, _bookmark_handle_delete); g_free(id); name = xmpp_stanza_get_name(stanza); if (!name || strcmp(name, STANZA_NAME_IQ) != 0) { return 0; } ptr = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); if (!ptr) { return 0; } ptr = xmpp_stanza_get_child_by_name(ptr, STANZA_NAME_STORAGE); if (!ptr) { return 0; } if (bookmark_ac == NULL) { bookmark_ac = autocomplete_new(); } my_jid = jid_create(jabber_get_fulljid()); ptr = xmpp_stanza_get_children(ptr); while (ptr) { name = xmpp_stanza_get_name(ptr); if (!name || strcmp(name, STANZA_NAME_CONFERENCE) != 0) { ptr = xmpp_stanza_get_next(ptr); continue; } jid = xmpp_stanza_get_attribute(ptr, STANZA_ATTR_JID); if (!jid) { ptr = xmpp_stanza_get_next(ptr); continue; } log_debug("Handle bookmark for %s", jid); name = NULL; nick = xmpp_stanza_get_child_by_name(ptr, "nick"); if (nick) { char *tmp; tmp = xmpp_stanza_get_text(nick); if (tmp) { name = strdup(tmp); xmpp_free(ctx, tmp); } } autojoin = xmpp_stanza_get_attribute(ptr, "autojoin"); if (autojoin && (strcmp(autojoin, "1") == 0 || strcmp(autojoin, "true") == 0)) { autojoin_val = TRUE; } else { autojoin_val = FALSE; } autocomplete_add(bookmark_ac, jid); item = malloc(sizeof(*item)); item->jid = strdup(jid); item->nick = name; item->autojoin = autojoin_val; bookmark_list = g_list_append(bookmark_list, item); /* TODO: preference whether autojoin */ if (autojoin_val) { if (autojoin_count < BOOKMARK_AUTOJOIN_MAX) { Jid *room_jid; ++autojoin_count; if (name == NULL) { name = my_jid->localpart; } log_debug("Autojoin %s with nick=%s", jid, name); room_jid = jid_create_from_bare_and_resource(jid, name); if (!muc_room_is_active(room_jid)) { presence_join_room(room_jid); /* TODO: this should be removed after fixing #195 */ ui_room_join(room_jid); } jid_destroy(room_jid); } else { log_debug("Rejected autojoin %s (maximum has been reached)", jid); } } ptr = xmpp_stanza_get_next(ptr); } jid_destroy(my_jid); return 0; }
static sdvp_WriteParam_t* _CreateWriteParam (xmpp_stanza_t * params) { int expectedParams, nVarParams = 0; sdvp_WriteParam_t* rv = NULL; int i = 0, j = 0, expectedDataElementsInArray; bool elementNotFund = false; xmpp_stanza_t *structure = NULL, *member = NULL, *value = NULL, *type = NULL; xmpp_stanza_t *name = NULL, *array, *arrayEntry; char *text, *textname; structure = _GetRpcStructureElementFromParams(params); if (structure == NULL ) { return NULL ; } // Get the number of elements // expectedParams = _FindNumberOfParams(params); if (expectedParams > 1) { nVarParams = expectedParams - 1; } else { // TODO: This should result in a ServiceError as minimum two is expected } rv = _InitiateWriteParameters(nVarParams); for (member = xmpp_stanza_get_children(structure); member && !elementNotFund && (i < expectedParams); member = xmpp_stanza_get_next(member)) { if (xmpp_stanza_get_name(member) && strcmp(xmpp_stanza_get_name(member), "member") == 0) { if (!(name = xmpp_stanza_get_child_by_name(member, "name"))) { _FreeWriteParameters(rv); // TODO: Signal error back return NULL ; } name = xmpp_stanza_get_children(name); textname = xmpp_stanza_get_text(name); if (strcmp(textname, "VariableAccessSpecification") == 0) { if (!(value = xmpp_stanza_get_child_by_name(member, "value"))) { _FreeWriteParameters(rv); // TODO: Signal error back return NULL ; } if ((type = xmpp_stanza_get_child_by_name(value, "string"))) { if (xmpp_stanza_get_children(type)) { text = xmpp_stanza_get_text(type); rv->params->reference = text; } else { rv->params->reference = NULL; } } else { elementNotFund = true; } } else if (strcmp(textname, "ListOfData") == 0) { if (!(value = xmpp_stanza_get_child_by_name(member, "value"))) { _FreeWriteParameters(rv); // TODO: Signal error back return NULL ; } if (!(array = xmpp_stanza_get_child_by_name(value, "array"))) { _FreeWriteParameters(rv); // TODO: Signal error back return NULL ; } expectedDataElementsInArray = _countDataElementsInArray(array); _InitiateWriteDataParameters(rv, expectedDataElementsInArray); // array = xmpp_stanza_get_children(array); arrayEntry = xmpp_stanza_get_children(array); //HJP Why skip the first element?! // arrayEntry = xmpp_stanza_get_next(arrayEntry); for (j = 0; arrayEntry; arrayEntry = xmpp_stanza_get_next(arrayEntry)) { if (xmpp_stanza_is_tag(arrayEntry)) { if (!(value = xmpp_stanza_get_child_by_name(arrayEntry, "value"))) { _FreeWriteParameters(rv); // TODO: Signal error back return NULL ; } // MISSING: base64 if ((type = xmpp_stanza_get_child_by_name(value, "string"))) { rv->params->dataAttributeValues[j]->dataType = IEC_VISIBLE_STRING; rv->params->dataAttributeValues[j]->strValue = xmpp_stanza_get_text(type); } else if ((type = xmpp_stanza_get_child_by_name(value, "i4")) || (type = xmpp_stanza_get_child_by_name(value, "int"))) { rv->params->dataAttributeValues[j]->dataType = IEC_INT32; text = xmpp_stanza_get_text(type); rv->params->dataAttributeValues[j]->intValue = strtol(text, NULL, 10); free(text); } else if ((type = xmpp_stanza_get_child_by_name(value, "double"))) { rv->params->dataAttributeValues[j]->dataType = IEC_FLOAT32; text = xmpp_stanza_get_text(type); rv->params->dataAttributeValues[j]->f32Value = strtof(text, NULL ); free(text); } else if ((type = xmpp_stanza_get_child_by_name(value, "boolean"))) { rv->params->dataAttributeValues[j]->dataType = IEC_BOOLEAN; text = xmpp_stanza_get_text(type); if (strcmp(text, "1") == 0) { rv->params->dataAttributeValues[j]->boolValue = true; } else { rv->params->dataAttributeValues[j]->boolValue = false; } free(text); } else if ((type = xmpp_stanza_get_child_by_name(value, "dateTime.iso8601"))) { rv->params->dataAttributeValues[j]->dataType = IEC_TIME; text = xmpp_stanza_get_text(type); rv->params->dataAttributeValues[j]->time = ne_iso8601_parse(text); free(text); } j++; } } } else { // if (!type) { // _FreeWriteParameters(rv); // return NULL ; // } } free(textname); } } return rv; }
char * caps_create_sha1_str(xmpp_stanza_t * const query) { char *category = NULL; char *type = NULL; char *lang = NULL; char *name = NULL; char *feature_str = NULL; GSList *identities = NULL; GSList *features = NULL; GSList *form_names = NULL; DataForm *form = NULL; FormField *field = NULL; GHashTable *forms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)stanza_destroy_form); GString *s = g_string_new(""); xmpp_stanza_t *child = xmpp_stanza_get_children(query); while (child != NULL) { if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_IDENTITY) == 0) { category = xmpp_stanza_get_attribute(child, "category"); type = xmpp_stanza_get_attribute(child, "type"); lang = xmpp_stanza_get_attribute(child, "xml:lang"); name = xmpp_stanza_get_attribute(child, "name"); GString *identity_str = g_string_new(category); g_string_append(identity_str, "/"); if (type != NULL) { g_string_append(identity_str, type); } g_string_append(identity_str, "/"); if (lang != NULL) { g_string_append(identity_str, lang); } g_string_append(identity_str, "/"); if (name != NULL) { g_string_append(identity_str, name); } g_string_append(identity_str, "<"); identities = g_slist_insert_sorted(identities, g_strdup(identity_str->str), (GCompareFunc)strcmp); g_string_free(identity_str, TRUE); } else if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_FEATURE) == 0) { feature_str = xmpp_stanza_get_attribute(child, "var"); features = g_slist_insert_sorted(features, g_strdup(feature_str), (GCompareFunc)strcmp); } else if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_X) == 0) { if (strcmp(xmpp_stanza_get_ns(child), STANZA_NS_DATA) == 0) { form = stanza_create_form(child); form_names = g_slist_insert_sorted(form_names, g_strdup(form->form_type), (GCompareFunc)strcmp); g_hash_table_insert(forms, g_strdup(form->form_type), form); } } child = xmpp_stanza_get_next(child); } GSList *curr = identities; while (curr != NULL) { g_string_append(s, curr->data); curr = g_slist_next(curr); } curr = features; while (curr != NULL) { g_string_append(s, curr->data); g_string_append(s, "<"); curr = g_slist_next(curr); } curr = form_names; while (curr != NULL) { form = g_hash_table_lookup(forms, curr->data); g_string_append(s, form->form_type); g_string_append(s, "<"); GSList *curr_field = form->fields; while (curr_field != NULL) { field = curr_field->data; g_string_append(s, field->var); g_string_append(s, "<"); GSList *curr_value = field->values; while (curr_value != NULL) { g_string_append(s, curr_value->data); g_string_append(s, "<"); curr_value = g_slist_next(curr_value); } curr_field = g_slist_next(curr_field); } curr = g_slist_next(curr); } EVP_MD_CTX mdctx; const EVP_MD *md; unsigned char md_value[EVP_MAX_MD_SIZE]; unsigned int md_len; OpenSSL_add_all_digests(); md = EVP_get_digestbyname("SHA1"); EVP_MD_CTX_init(&mdctx); EVP_DigestInit_ex(&mdctx, md, NULL); EVP_DigestUpdate(&mdctx, s->str, strlen(s->str)); EVP_DigestFinal_ex(&mdctx, md_value, &md_len); EVP_MD_CTX_cleanup(&mdctx); char *result = g_base64_encode(md_value, md_len); g_string_free(s, TRUE); g_slist_free_full(identities, g_free); g_slist_free_full(features, g_free); g_slist_free_full(form_names, g_free); g_hash_table_destroy(forms); return result; }
DataForm* form_create(xmpp_stanza_t *const form_stanza) { xmpp_ctx_t *ctx = connection_get_ctx(); if (!_is_valid_form_element(form_stanza)) { return NULL; } DataForm *form = _form_new(); form->type = _get_attr(form_stanza, "type"); form->title = _get_property(form_stanza, "title"); form->instructions = _get_property(form_stanza, "instructions"); form->var_to_tag = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); form->tag_to_var = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); form->tag_ac = autocomplete_new(); form->modified = FALSE; int tag_num = 1; // get fields xmpp_stanza_t *form_child = xmpp_stanza_get_children(form_stanza); while (form_child) { const char *child_name = xmpp_stanza_get_name(form_child); if (g_strcmp0(child_name, "field") == 0) { xmpp_stanza_t *field_stanza = form_child; FormField *field = _field_new(); field->label = _get_attr(field_stanza, "label"); field->type = _get_attr(field_stanza, "type"); field->type_t = _get_field_type(field->type); field->value_ac = autocomplete_new(); field->var = _get_attr(field_stanza, "var"); if (field->type_t != FIELD_HIDDEN && field->var) { GString *tag = g_string_new(""); g_string_printf(tag, "field%d", tag_num++); g_hash_table_insert(form->var_to_tag, strdup(field->var), strdup(tag->str)); g_hash_table_insert(form->tag_to_var, strdup(tag->str), strdup(field->var)); autocomplete_add(form->tag_ac, tag->str); g_string_free(tag, TRUE); } field->description = _get_property(field_stanza, "desc"); field->required = _is_required(field_stanza); // handle repeated field children xmpp_stanza_t *field_child = xmpp_stanza_get_children(field_stanza); int value_index = 1; while (field_child) { child_name = xmpp_stanza_get_name(field_child); // handle values if (g_strcmp0(child_name, "value") == 0) { char *value = xmpp_stanza_get_text(field_child); if (value) { field->values = g_slist_append(field->values, strdup(value)); if (field->type_t == FIELD_TEXT_MULTI) { GString *ac_val = g_string_new(""); g_string_printf(ac_val, "val%d", value_index++); autocomplete_add(field->value_ac, ac_val->str); g_string_free(ac_val, TRUE); } if (field->type_t == FIELD_JID_MULTI) { autocomplete_add(field->value_ac, value); } xmpp_free(ctx, value); } // handle options } else if (g_strcmp0(child_name, "option") == 0) { FormOption *option = malloc(sizeof(FormOption)); option->label = _get_attr(field_child, "label"); option->value = _get_property(field_child, "value"); if ((field->type_t == FIELD_LIST_SINGLE) || (field->type_t == FIELD_LIST_MULTI)) { autocomplete_add(field->value_ac, option->value); } field->options = g_slist_append(field->options, option); } field_child = xmpp_stanza_get_next(field_child); } form->fields = g_slist_append(form->fields, field); } form_child = xmpp_stanza_get_next(form_child); } return form; }
Capabilities * caps_create(xmpp_stanza_t *query) { char *category = NULL; char *type = NULL; char *name = NULL; char *software = NULL; char *software_version = NULL; char *os = NULL; char *os_version = NULL; GSList *features = NULL; xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA); if (softwareinfo != NULL) { DataForm *form = form_create(softwareinfo); FormField *formField = NULL; char *form_type = form_get_form_type_field(form); if (g_strcmp0(form_type, STANZA_DATAFORM_SOFTWARE) == 0) { GSList *field = form->fields; while (field != NULL) { formField = field->data; if (formField->values != NULL) { if (strcmp(formField->var, "software") == 0) { software = strdup(formField->values->data); } else if (strcmp(formField->var, "software_version") == 0) { software_version = strdup(formField->values->data); } else if (strcmp(formField->var, "os") == 0) { os = strdup(formField->values->data); } else if (strcmp(formField->var, "os_version") == 0) { os_version = strdup(formField->values->data); } } field = g_slist_next(field); } } form_destroy(form); } xmpp_stanza_t *child = xmpp_stanza_get_children(query); GSList *identity_stanzas = NULL; while (child != NULL) { if (g_strcmp0(xmpp_stanza_get_name(child), "feature") == 0) { features = g_slist_append(features, strdup(xmpp_stanza_get_attribute(child, "var"))); } if (g_strcmp0(xmpp_stanza_get_name(child), "identity") == 0) { identity_stanzas = g_slist_append(identity_stanzas, child); } child = xmpp_stanza_get_next(child); } // find identity by locale const gchar* const *langs = g_get_language_names(); int num_langs = g_strv_length((gchar**)langs); xmpp_stanza_t *found = NULL; GSList *curr_identity = identity_stanzas; while (curr_identity) { xmpp_stanza_t *id_stanza = curr_identity->data; char *stanza_lang = xmpp_stanza_get_attribute(id_stanza, "xml:lang"); if (stanza_lang) { int i = 0; for (i = 0; i < num_langs; i++) { if (g_strcmp0(langs[i], stanza_lang) == 0) { found = id_stanza; break; } } } if (found) { break; } curr_identity = g_slist_next(curr_identity); } // not lang match, use default with no lang if (!found) { curr_identity = identity_stanzas; while (curr_identity) { xmpp_stanza_t *id_stanza = curr_identity->data; char *stanza_lang = xmpp_stanza_get_attribute(id_stanza, "xml:lang"); if (!stanza_lang) { found = id_stanza; break; } curr_identity = g_slist_next(curr_identity); } } // no matching lang, no identity without lang, use first if (!found) { if (identity_stanzas) { found = identity_stanzas->data; } } g_slist_free(identity_stanzas); if (found) { category = xmpp_stanza_get_attribute(found, "category"); type = xmpp_stanza_get_attribute(found, "type"); name = xmpp_stanza_get_attribute(found, "name"); } Capabilities *new_caps = malloc(sizeof(struct capabilities_t)); if (category != NULL) { new_caps->category = strdup(category); } else { new_caps->category = NULL; } if (type != NULL) { new_caps->type = strdup(type); } else { new_caps->type = NULL; } if (name != NULL) { new_caps->name = strdup(name); } else { new_caps->name = NULL; } if (software != NULL) { new_caps->software = software; } else { new_caps->software = NULL; } if (software_version != NULL) { new_caps->software_version = software_version; } else { new_caps->software_version = NULL; } if (os != NULL) { new_caps->os = os; } else { new_caps->os = NULL; } if (os_version != NULL) { new_caps->os_version = os_version; } else { new_caps->os_version = NULL; } if (features != NULL) { new_caps->features = features; } else { new_caps->features = NULL; } return new_caps; }
/* stream:error handler */ static int _handle_error(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *child; char *name; /* free old stream error if it's still there */ if (conn->stream_error) { xmpp_stanza_release(conn->stream_error->stanza); if (conn->stream_error->text) xmpp_free(conn->ctx, conn->stream_error->text); xmpp_free(conn->ctx, conn->stream_error); } /* create stream error structure */ conn->stream_error = (xmpp_stream_error_t *)xmpp_alloc(conn->ctx, sizeof(xmpp_stream_error_t)); conn->stream_error->text = NULL; conn->stream_error->type = XMPP_SE_UNDEFINED_CONDITION; if (conn->stream_error) { child = xmpp_stanza_get_children(stanza); do { char *ns = NULL; if (child) { ns = xmpp_stanza_get_ns(child); } if (ns && strcmp(ns, XMPP_NS_STREAMS_IETF) == 0) { name = xmpp_stanza_get_name(child); if (strcmp(name, "text") == 0) { if (conn->stream_error->text) xmpp_free(conn->ctx, conn->stream_error->text); conn->stream_error->text = xmpp_stanza_get_text(child); } else if (strcmp(name, "bad-format") == 0) conn->stream_error->type = XMPP_SE_BAD_FORMAT; else if (strcmp(name, "bad-namespace-prefix") == 0) conn->stream_error->type = XMPP_SE_BAD_NS_PREFIX; else if (strcmp(name, "conflict") == 0) conn->stream_error->type = XMPP_SE_CONFLICT; else if (strcmp(name, "connection-timeout") == 0) conn->stream_error->type = XMPP_SE_CONN_TIMEOUT; else if (strcmp(name, "host-gone") == 0) conn->stream_error->type = XMPP_SE_HOST_GONE; else if (strcmp(name, "host-unknown") == 0) conn->stream_error->type = XMPP_SE_HOST_UNKNOWN; else if (strcmp(name, "improper-addressing") == 0) conn->stream_error->type = XMPP_SE_IMPROPER_ADDR; else if (strcmp(name, "internal-server-error") == 0) conn->stream_error->type = XMPP_SE_INTERNAL_SERVER_ERROR; else if (strcmp(name, "invalid-from") == 0) conn->stream_error->type = XMPP_SE_INVALID_FROM; else if (strcmp(name, "invalid-id") == 0) conn->stream_error->type = XMPP_SE_INVALID_ID; else if (strcmp(name, "invalid-namespace") == 0) conn->stream_error->type = XMPP_SE_INVALID_NS; else if (strcmp(name, "invalid-xml") == 0) conn->stream_error->type = XMPP_SE_INVALID_XML; else if (strcmp(name, "not-authorized") == 0) conn->stream_error->type = XMPP_SE_NOT_AUTHORIZED; else if (strcmp(name, "policy-violation") == 0) conn->stream_error->type = XMPP_SE_POLICY_VIOLATION; else if (strcmp(name, "remote-connection-failed") == 0) conn->stream_error->type = XMPP_SE_REMOTE_CONN_FAILED; else if (strcmp(name, "resource-constraint") == 0) conn->stream_error->type = XMPP_SE_RESOURCE_CONSTRAINT; else if (strcmp(name, "restricted-xml") == 0) conn->stream_error->type = XMPP_SE_RESTRICTED_XML; else if (strcmp(name, "see-other-host") == 0) conn->stream_error->type = XMPP_SE_SEE_OTHER_HOST; else if (strcmp(name, "system-shutdown") == 0) conn->stream_error->type = XMPP_SE_SYSTEM_SHUTDOWN; else if (strcmp(name, "undefined-condition") == 0) conn->stream_error->type = XMPP_SE_UNDEFINED_CONDITION; else if (strcmp(name, "unsupported-encoding") == 0) conn->stream_error->type = XMPP_SE_UNSUPPORTED_ENCODING; else if (strcmp(name, "unsupported-stanza-type") == 0) conn->stream_error->type = XMPP_SE_UNSUPPORTED_STANZA_TYPE; else if (strcmp(name, "unsupported-version") == 0) conn->stream_error->type = XMPP_SE_UNSUPPORTED_VERSION; else if (strcmp(name, "xml-not-well-formed") == 0) conn->stream_error->type = XMPP_SE_XML_NOT_WELL_FORMED; } } while ((child = xmpp_stanza_get_next(child))); conn->stream_error->stanza = xmpp_stanza_clone(stanza); } return 1; }
static int _roster_result_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); if (g_strcmp0(id, "roster") != 0) { return 1; } // handle initial roster response xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); xmpp_stanza_t *item = xmpp_stanza_get_children(query); while (item) { const char *barejid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); gchar *barejid_lower = g_utf8_strdown(barejid, -1); const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME); const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION); // do not set nickname to empty string, set to NULL instead if (name && (strlen(name) == 0)) name = NULL; gboolean pending_out = FALSE; const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK); if (g_strcmp0(ask, "subscribe") == 0) { pending_out = TRUE; } GSList *groups = _get_groups_from_item(item); gboolean added = roster_add(barejid_lower, name, groups, sub, pending_out); if (!added) { log_warning("Attempt to add contact twice: %s", barejid_lower); } g_free(barejid_lower); item = xmpp_stanza_get_next(item); } sv_ev_roster_received(); char *account = jabber_get_account_name(); resource_presence_t conn_presence = accounts_get_login_presence(account); char *last_activity_str = accounts_get_last_activity(account); if (last_activity_str) { GDateTime *nowdt = g_date_time_new_now_utc(); GTimeVal lasttv; gboolean res = g_time_val_from_iso8601(last_activity_str, &lasttv); if (res) { GDateTime *lastdt = g_date_time_new_from_timeval_utc(&lasttv); GTimeSpan diff_micros = g_date_time_difference(nowdt, lastdt); int diff_secs = (diff_micros / 1000) / 1000; cl_ev_presence_send(conn_presence, NULL, diff_secs); g_date_time_unref(lastdt); } else { cl_ev_presence_send(conn_presence, NULL, 0); } free(last_activity_str); g_date_time_unref(nowdt); } else { cl_ev_presence_send(conn_presence, NULL, 0); } return 1; }
/** * Creates the parameter structure for the GetNameList callback * @param[in] params This stanza is the params element in the XML-RPC format * @return The structure or null if an error were found. */ static sdvp_GetNameListParam_t* _CreateGetNameListParam (xmpp_stanza_t * params) { const int expectedParams = 4; sdvp_GetNameListParam_t* rv = NULL; int i = 0; bool elementNotFund = false; xmpp_stanza_t *structure = NULL, *member = NULL, *value = NULL, *type = NULL, *name = NULL; char *text, *textname; structure = _GetRpcStructureElementFromParams(params); if (structure == NULL ) { return NULL ; } rv = _InitiateGetNameListParameters(); for (member = xmpp_stanza_get_children(structure); member && !elementNotFund && (i < expectedParams); member = xmpp_stanza_get_next(member)) { if (xmpp_stanza_get_name(member) && strcmp(xmpp_stanza_get_name(member), "member") == 0) { if (!(name = xmpp_stanza_get_child_by_name(member, "name"))) { _FreeGetNameListParameters(rv); // TODO: Signal error back return NULL ; } name = xmpp_stanza_get_children(name); textname = xmpp_stanza_get_text(name); if (strcmp(textname, "ObjectClass") == 0) { if (!(value = xmpp_stanza_get_child_by_name(member, "value"))) { _FreeGetNameListParameters(rv); // TODO: Signal error back return NULL ; } if ((type = xmpp_stanza_get_child_by_name(value, "string"))) { if (xmpp_stanza_get_children(type)) { text = xmpp_stanza_get_text(type); rv->params.objectClass = text; } else { rv->params.objectClass = NULL; } } else { elementNotFund = true; } } else if (strcmp(textname, "ObjectScope") == 0) { if ((type = xmpp_stanza_get_child_by_name(value, "string"))) { if (xmpp_stanza_get_children(type)) { text = xmpp_stanza_get_text(type); rv->params.objectScope = text; } else { rv->params.objectScope = NULL; } } else { elementNotFund = true; } } else if (strcmp(textname, "DomainName") == 0) { if ((type = xmpp_stanza_get_child_by_name(value, "string"))) { if (xmpp_stanza_get_children(type)) { text = xmpp_stanza_get_text(type); rv->params.domainName = text; } else { rv->params.domainName = NULL; } } else { elementNotFund = true; } } else if (strcmp(textname, "ContinueAfter") == 0) { if ((type = xmpp_stanza_get_child_by_name(value, "string"))) { if (xmpp_stanza_get_children(type)) { text = xmpp_stanza_get_text(type); rv->params.continueAfter = text; } else { rv->params.continueAfter = NULL; } } else { elementNotFund = true; } } else { // if (!type) { // _FreeGetNameListParameters(rv); // return NULL ; // } } free(textname); } } return rv; }
static int _bookmark_result_id_handler(xmpp_stanza_t *const stanza, void *const userdata) { const char *name = xmpp_stanza_get_name(stanza); if (!name || strcmp(name, STANZA_NAME_IQ) != 0) { return 0; } xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY); if (!query) { return 0; } xmpp_stanza_t *storage = xmpp_stanza_get_child_by_name(query, STANZA_NAME_STORAGE); if (!storage) { return 0; } if (bookmark_ac == NULL) { bookmark_ac = autocomplete_new(); } xmpp_stanza_t *child = xmpp_stanza_get_children(storage); while (child) { name = xmpp_stanza_get_name(child); if (!name || strcmp(name, STANZA_NAME_CONFERENCE) != 0) { child = xmpp_stanza_get_next(child); continue; } const char *barejid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID); if (!barejid) { child = xmpp_stanza_get_next(child); continue; } log_debug("Handle bookmark for %s", barejid); char *nick = NULL; xmpp_stanza_t *nick_st = xmpp_stanza_get_child_by_name(child, "nick"); if (nick_st) { nick = stanza_text_strdup(nick_st); } char *password = NULL; xmpp_stanza_t *password_st = xmpp_stanza_get_child_by_name(child, "password"); if (password_st) { password = stanza_text_strdup(password_st); } const char *autojoin = xmpp_stanza_get_attribute(child, "autojoin"); gboolean autojoin_val = FALSE;; if (autojoin && (strcmp(autojoin, "1") == 0 || strcmp(autojoin, "true") == 0)) { autojoin_val = TRUE; } autocomplete_add(bookmark_ac, barejid); Bookmark *bookmark = malloc(sizeof(Bookmark)); bookmark->barejid = strdup(barejid); bookmark->nick = nick; bookmark->password = password; bookmark->autojoin = autojoin_val; g_hash_table_insert(bookmarks, strdup(barejid), bookmark); if (autojoin_val) { sv_ev_bookmark_autojoin(bookmark); } Jid *jidp = jid_create(barejid); if (jidp->domainpart) { muc_confserver_add(jidp->domainpart); } jid_destroy(jidp); child = xmpp_stanza_get_next(child); } return 0; }