mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-07-26 18:26:22 +00:00
Merge pull request #991 from paulfariello/feature/xep-0050
Add support for xep 0050 ad-hoc commands, without multi-step
This commit is contained in:
256
src/xmpp/iq.c
256
src/xmpp/iq.c
@@ -88,6 +88,11 @@ typedef struct privilege_set_t {
|
||||
char *privilege;
|
||||
} ProfPrivilegeSet;
|
||||
|
||||
typedef struct command_config_data_t {
|
||||
char *sessionid;
|
||||
char *command;
|
||||
} CommandConfigData;
|
||||
|
||||
static int _iq_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
|
||||
|
||||
static void _error_handler(xmpp_stanza_t *const stanza);
|
||||
@@ -120,6 +125,8 @@ static int _caps_response_for_jid_id_handler(xmpp_stanza_t *const stanza, void *
|
||||
static int _caps_response_legacy_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
|
||||
static int _auto_pong_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
|
||||
static int _room_list_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
|
||||
static int _command_list_result_handler(xmpp_stanza_t *const stanza, void *const userdata);
|
||||
static int _command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata);
|
||||
|
||||
static void _iq_free_room_data(ProfRoomInfoData *roominfo);
|
||||
static void _iq_free_affiliation_set(ProfPrivilegeSet *affiliation_set);
|
||||
@@ -319,7 +326,7 @@ iq_room_list_request(gchar *conferencejid, gchar *filter)
|
||||
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
char *id = connection_create_stanza_id("confreq");
|
||||
xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, id, conferencejid);
|
||||
xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, id, conferencejid, NULL);
|
||||
|
||||
iq_id_handler_add(id, _room_list_id_handler, NULL, filter);
|
||||
|
||||
@@ -521,7 +528,7 @@ void
|
||||
iq_disco_items_request(gchar *jid)
|
||||
{
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, "discoitemsreq", jid);
|
||||
xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, "discoitemsreq", jid, NULL);
|
||||
iq_send_stanza(iq);
|
||||
xmpp_stanza_release(iq);
|
||||
}
|
||||
@@ -530,7 +537,7 @@ void
|
||||
iq_disco_items_request_onconnect(gchar *jid)
|
||||
{
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, "discoitemsreq_onconnect", jid);
|
||||
xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, "discoitemsreq_onconnect", jid, NULL);
|
||||
iq_send_stanza(iq);
|
||||
xmpp_stanza_release(iq);
|
||||
}
|
||||
@@ -584,10 +591,10 @@ iq_request_room_config_form(const char *const room_jid)
|
||||
}
|
||||
|
||||
void
|
||||
iq_submit_room_config(const char *const room, DataForm *form)
|
||||
iq_submit_room_config(ProfConfWin *confwin)
|
||||
{
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *iq = stanza_create_room_config_submit_iq(ctx, room, form);
|
||||
xmpp_stanza_t *iq = stanza_create_room_config_submit_iq(ctx, confwin->roomjid, confwin->form);
|
||||
|
||||
const char *id = xmpp_stanza_get_id(iq);
|
||||
iq_id_handler_add(id, _room_config_submit_id_handler, NULL, NULL);
|
||||
@@ -597,10 +604,10 @@ iq_submit_room_config(const char *const room, DataForm *form)
|
||||
}
|
||||
|
||||
void
|
||||
iq_room_config_cancel(const char *const room_jid)
|
||||
iq_room_config_cancel(ProfConfWin *confwin)
|
||||
{
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *iq = stanza_create_room_config_cancel_iq(ctx, room_jid);
|
||||
xmpp_stanza_t *iq = stanza_create_room_config_cancel_iq(ctx, confwin->roomjid);
|
||||
iq_send_stanza(iq);
|
||||
xmpp_stanza_release(iq);
|
||||
}
|
||||
@@ -696,6 +703,62 @@ iq_send_ping(const char *const target)
|
||||
xmpp_stanza_release(iq);
|
||||
}
|
||||
|
||||
void
|
||||
iq_command_list(const char *const target)
|
||||
{
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
const char *id = connection_create_stanza_id("cmdlist");
|
||||
xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, id, target, STANZA_NS_COMMAND);
|
||||
|
||||
iq_id_handler_add(id, _command_list_result_handler, NULL, NULL);
|
||||
|
||||
iq_send_stanza(iq);
|
||||
xmpp_stanza_release(iq);
|
||||
}
|
||||
|
||||
void
|
||||
iq_command_exec(const char *const target, const char *const command)
|
||||
{
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
xmpp_stanza_t *iq = stanza_create_command_exec_iq(ctx, target, command);
|
||||
const char *id = xmpp_stanza_get_id(iq);
|
||||
|
||||
iq_id_handler_add(id, _command_exec_response_handler, free, strdup(command));
|
||||
|
||||
iq_send_stanza(iq);
|
||||
xmpp_stanza_release(iq);
|
||||
}
|
||||
|
||||
void
|
||||
iq_submit_command_config(ProfConfWin *confwin)
|
||||
{
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
CommandConfigData *data = (CommandConfigData *)confwin->userdata;
|
||||
xmpp_stanza_t *iq = stanza_create_command_config_submit_iq(ctx, confwin->roomjid, data->command, data->sessionid, confwin->form);
|
||||
|
||||
const char *id = xmpp_stanza_get_id(iq);
|
||||
iq_id_handler_add(id, _command_exec_response_handler, free, strdup(data->command));
|
||||
|
||||
iq_send_stanza(iq);
|
||||
xmpp_stanza_release(iq);
|
||||
free(data->sessionid);
|
||||
free(data->command);
|
||||
free(data);
|
||||
}
|
||||
|
||||
void
|
||||
iq_cancel_command_config(ProfConfWin *confwin)
|
||||
{
|
||||
xmpp_ctx_t * const ctx = connection_get_ctx();
|
||||
CommandConfigData *data = (CommandConfigData *)confwin->userdata;
|
||||
xmpp_stanza_t *iq = stanza_create_room_config_cancel_iq(ctx, confwin->roomjid);
|
||||
iq_send_stanza(iq);
|
||||
xmpp_stanza_release(iq);
|
||||
free(data->sessionid);
|
||||
free(data->command);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void
|
||||
_error_handler(xmpp_stanza_t *const stanza)
|
||||
{
|
||||
@@ -1011,6 +1074,181 @@ _room_list_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_command_list_result_handler(xmpp_stanza_t *const stanza, void *const userdata)
|
||||
{
|
||||
const char *id = xmpp_stanza_get_id(stanza);
|
||||
const char *type = xmpp_stanza_get_type(stanza);
|
||||
char *from = strdup(xmpp_stanza_get_from(stanza));
|
||||
|
||||
if (id) {
|
||||
log_debug("IQ command list result handler fired, id: %s.", id);
|
||||
} else {
|
||||
log_debug("IQ command list result handler fired.");
|
||||
}
|
||||
|
||||
// handle error responses
|
||||
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||
char *error_message = stanza_get_error_message(stanza);
|
||||
log_debug("Error retrieving command list for %s: %s", from, error_message);
|
||||
ProfWin *win = wins_get_by_string(from);
|
||||
if (win) {
|
||||
win_command_list_error(win, error_message);
|
||||
}
|
||||
free(error_message);
|
||||
free(from);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GSList *cmds = NULL;
|
||||
|
||||
xmpp_stanza_t *query = xmpp_stanza_get_child_by_ns(stanza, XMPP_NS_DISCO_ITEMS);
|
||||
if (query) {
|
||||
xmpp_stanza_t *child = xmpp_stanza_get_children(query);
|
||||
while (child) {
|
||||
const char *name = xmpp_stanza_get_name(child);
|
||||
if (g_strcmp0(name, "item") == 0) {
|
||||
const char *node = xmpp_stanza_get_attribute(child, STANZA_ATTR_NODE);
|
||||
if (node) {
|
||||
cmds = g_slist_insert_sorted(cmds, (gpointer)node, (GCompareFunc)g_strcmp0);
|
||||
}
|
||||
}
|
||||
child = xmpp_stanza_get_next(child);
|
||||
}
|
||||
}
|
||||
|
||||
ProfWin *win = wins_get_by_string(from);
|
||||
if (win == NULL) {
|
||||
win = wins_get_console();
|
||||
}
|
||||
|
||||
win_handle_command_list(win, cmds);
|
||||
g_slist_free(cmds);
|
||||
free(from);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_command_exec_response_handler(xmpp_stanza_t *const stanza, void *const userdata)
|
||||
{
|
||||
const char *id = xmpp_stanza_get_id(stanza);
|
||||
const char *type = xmpp_stanza_get_type(stanza);
|
||||
const char *from = xmpp_stanza_get_from(stanza);
|
||||
char *command = userdata;
|
||||
|
||||
if (id) {
|
||||
log_debug("IQ command exec response handler fired, id: %s.", id);
|
||||
} else {
|
||||
log_debug("IQ command exec response handler fired.");
|
||||
}
|
||||
|
||||
ProfWin *win = wins_get_by_string(from);
|
||||
if (win == NULL) {
|
||||
/* No more window associated with this command.
|
||||
* Fallback to console. */
|
||||
win = wins_get_console();
|
||||
}
|
||||
|
||||
// handle error responses
|
||||
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
|
||||
char *error_message = stanza_get_error_message(stanza);
|
||||
log_debug("Error executing command %s for %s: %s", command, from, error_message);
|
||||
win_command_exec_error(win, command, error_message);
|
||||
free(error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmpp_stanza_t *cmd = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_COMMAND);
|
||||
if (!cmd) {
|
||||
log_error("No command element for command response");
|
||||
win_command_exec_error(win, command, "Malformed command response");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char *status = xmpp_stanza_get_attribute(cmd, STANZA_ATTR_STATUS);
|
||||
if (g_strcmp0(status, "completed") == 0) {
|
||||
win_handle_command_exec_status(win, command, "completed");
|
||||
xmpp_stanza_t *note = xmpp_stanza_get_child_by_name(cmd, "note");
|
||||
if (note) {
|
||||
const char *type = xmpp_stanza_get_attribute(note, "type");
|
||||
const char *value = xmpp_stanza_get_text(note);
|
||||
win_handle_command_exec_result_note(win, type, value);
|
||||
}
|
||||
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(cmd, STANZA_NS_DATA);
|
||||
if (x) {
|
||||
xmpp_stanza_t *roster = xmpp_stanza_get_child_by_ns(x, XMPP_NS_ROSTER);
|
||||
if (roster) {
|
||||
/* Special handling of xep-0133 roster in response */
|
||||
GSList *list = NULL;
|
||||
xmpp_stanza_t *child = xmpp_stanza_get_children(roster);
|
||||
while (child) {
|
||||
const char *barejid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID);
|
||||
gchar *barejid_lower = g_utf8_strdown(barejid, -1);
|
||||
const char *name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME);
|
||||
const char *sub = xmpp_stanza_get_attribute(child, STANZA_ATTR_SUBSCRIPTION);
|
||||
const char *ask = xmpp_stanza_get_attribute(child, STANZA_ATTR_ASK);
|
||||
|
||||
GSList *groups = NULL;
|
||||
groups = roster_get_groups_from_item(child);
|
||||
|
||||
gboolean pending_out = FALSE;
|
||||
if (ask && (strcmp(ask, "subscribe") == 0)) {
|
||||
pending_out = TRUE;
|
||||
}
|
||||
|
||||
PContact contact = p_contact_new(barejid_lower, name, groups, sub, NULL, pending_out);
|
||||
list = g_slist_insert_sorted(list, contact, (GCompareFunc)roster_compare_name);
|
||||
child = xmpp_stanza_get_next(child);
|
||||
}
|
||||
|
||||
cons_show_roster(list);
|
||||
g_slist_free(list);
|
||||
} else {
|
||||
DataForm *form = form_create(x);
|
||||
ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, NULL, NULL, NULL);
|
||||
confwin_handle_configuration(confwin, form);
|
||||
}
|
||||
}
|
||||
} else if (g_strcmp0(status, "executing") == 0) {
|
||||
win_handle_command_exec_status(win, command, "executing");
|
||||
|
||||
/* Looking for a jabber:x:data type form */
|
||||
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(cmd, STANZA_NS_DATA);
|
||||
if (x == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *form_type = xmpp_stanza_get_type(x);
|
||||
if (g_strcmp0(form_type, "form") != 0) {
|
||||
log_error("Unsupported payload in command response");
|
||||
win_command_exec_error(win, command, "Unsupported command response");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DataForm *form = form_create(x);
|
||||
CommandConfigData *data = malloc(sizeof(CommandConfigData));
|
||||
data->sessionid = strdup(xmpp_stanza_get_attribute(cmd, "sessionid"));
|
||||
data->command = command;
|
||||
ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, iq_submit_command_config, iq_cancel_command_config, data);
|
||||
confwin_handle_configuration(confwin, form);
|
||||
} else if (g_strcmp0(status, "canceled") == 0) {
|
||||
win_handle_command_exec_status(win, command, "canceled");
|
||||
xmpp_stanza_t *note = xmpp_stanza_get_child_by_name(cmd, "note");
|
||||
if (note) {
|
||||
const char *type = xmpp_stanza_get_attribute(note, "type");
|
||||
const char *value = xmpp_stanza_get_text(note);
|
||||
win_handle_command_exec_result_note(win, type, value);
|
||||
}
|
||||
} else {
|
||||
log_error("Unsupported command status %s", status);
|
||||
win_command_exec_error(win, command, "Malformed command response");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_enable_carbons_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
|
||||
{
|
||||
@@ -1540,8 +1778,8 @@ _room_config_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
|
||||
}
|
||||
|
||||
DataForm *form = form_create(x);
|
||||
ProfMucConfWin *confwin = (ProfMucConfWin*)wins_new_muc_config(from, form);
|
||||
mucconfwin_handle_configuration(confwin, form);
|
||||
ProfConfWin *confwin = (ProfConfWin*)wins_new_config(from, form, iq_submit_room_config, iq_room_config_cancel, NULL);
|
||||
confwin_handle_configuration(confwin, form);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -75,9 +75,6 @@ static int _group_add_id_handler(xmpp_stanza_t *const stanza, void *const userda
|
||||
static int _group_remove_id_handler(xmpp_stanza_t *const stanza, void *const userdata);
|
||||
static void _free_group_data(GroupData *data);
|
||||
|
||||
// helper functions
|
||||
GSList* _get_groups_from_item(xmpp_stanza_t *item);
|
||||
|
||||
void
|
||||
roster_request(void)
|
||||
{
|
||||
@@ -254,7 +251,7 @@ roster_set_handler(xmpp_stanza_t *const stanza)
|
||||
pending_out = TRUE;
|
||||
}
|
||||
|
||||
GSList *groups = _get_groups_from_item(item);
|
||||
GSList *groups = roster_get_groups_from_item(item);
|
||||
|
||||
// update the local roster
|
||||
PContact contact = roster_get_contact(barejid_lower);
|
||||
@@ -301,7 +298,7 @@ roster_result_handler(xmpp_stanza_t *const stanza)
|
||||
pending_out = TRUE;
|
||||
}
|
||||
|
||||
GSList *groups = _get_groups_from_item(item);
|
||||
GSList *groups = roster_get_groups_from_item(item);
|
||||
|
||||
gboolean added = roster_add(barejid_lower, name, groups, sub, pending_out);
|
||||
if (!added) {
|
||||
@@ -318,7 +315,7 @@ roster_result_handler(xmpp_stanza_t *const stanza)
|
||||
}
|
||||
|
||||
GSList*
|
||||
_get_groups_from_item(xmpp_stanza_t *item)
|
||||
roster_get_groups_from_item(xmpp_stanza_t *item)
|
||||
{
|
||||
GSList *groups = NULL;
|
||||
xmpp_stanza_t *group_element = xmpp_stanza_get_children(item);
|
||||
|
||||
@@ -38,5 +38,6 @@
|
||||
void roster_request(void);
|
||||
void roster_set_handler(xmpp_stanza_t *const stanza);
|
||||
void roster_result_handler(xmpp_stanza_t *const stanza);
|
||||
GSList* roster_get_groups_from_item(xmpp_stanza_t *const item);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -73,8 +73,6 @@ static gboolean _key_equals(void *key1, void *key2);
|
||||
static gboolean _datetimes_equal(GDateTime *dt1, GDateTime *dt2);
|
||||
static void _replace_name(const char *const current_name, const char *const new_name, const char *const barejid);
|
||||
static void _add_name_and_barejid(const char *const name, const char *const barejid);
|
||||
static gint _compare_name(PContact a, PContact b);
|
||||
static gint _compare_presence(PContact a, PContact b);
|
||||
|
||||
void
|
||||
roster_create(void)
|
||||
@@ -397,7 +395,7 @@ roster_get_contacts_by_presence(const char *const presence)
|
||||
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
||||
PContact contact = (PContact)value;
|
||||
if (g_strcmp0(p_contact_presence(contact), presence) == 0) {
|
||||
result = g_slist_insert_sorted(result, value, (GCompareFunc)_compare_name);
|
||||
result = g_slist_insert_sorted(result, value, (GCompareFunc)roster_compare_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,9 +415,9 @@ roster_get_contacts(roster_ord_t order)
|
||||
|
||||
GCompareFunc cmp_func;
|
||||
if (order == ROSTER_ORD_PRESENCE) {
|
||||
cmp_func = (GCompareFunc) _compare_presence;
|
||||
cmp_func = (GCompareFunc) roster_compare_presence;
|
||||
} else {
|
||||
cmp_func = (GCompareFunc) _compare_name;
|
||||
cmp_func = (GCompareFunc) roster_compare_name;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init(&iter, roster->contacts);
|
||||
@@ -444,7 +442,7 @@ roster_get_contacts_online(void)
|
||||
g_hash_table_iter_init(&iter, roster->contacts);
|
||||
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
||||
if(strcmp(p_contact_presence(value), "offline"))
|
||||
result = g_slist_insert_sorted(result, value, (GCompareFunc)_compare_name);
|
||||
result = g_slist_insert_sorted(result, value, (GCompareFunc)roster_compare_name);
|
||||
}
|
||||
|
||||
// return all contact structs
|
||||
@@ -499,9 +497,9 @@ roster_get_group(const char *const group, roster_ord_t order)
|
||||
|
||||
GCompareFunc cmp_func;
|
||||
if (order == ROSTER_ORD_PRESENCE) {
|
||||
cmp_func = (GCompareFunc) _compare_presence;
|
||||
cmp_func = (GCompareFunc) roster_compare_presence;
|
||||
} else {
|
||||
cmp_func = (GCompareFunc) _compare_name;
|
||||
cmp_func = (GCompareFunc) roster_compare_name;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init(&iter, roster->contacts);
|
||||
@@ -605,8 +603,8 @@ _add_name_and_barejid(const char *const name, const char *const barejid)
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
_compare_name(PContact a, PContact b)
|
||||
gint
|
||||
roster_compare_name(PContact a, PContact b)
|
||||
{
|
||||
const char * utf8_str_a = NULL;
|
||||
const char * utf8_str_b = NULL;
|
||||
@@ -645,8 +643,8 @@ _get_presence_weight(const char *presence)
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
_compare_presence(PContact a, PContact b)
|
||||
gint
|
||||
roster_compare_presence(PContact a, PContact b)
|
||||
{
|
||||
const char *presence_a = p_contact_presence(a);
|
||||
const char *presence_b = p_contact_presence(b);
|
||||
@@ -663,6 +661,6 @@ _compare_presence(PContact a, PContact b)
|
||||
|
||||
// otherwise order by name
|
||||
} else {
|
||||
return _compare_name(a, b);
|
||||
return roster_compare_name(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,5 +70,7 @@ char* roster_group_autocomplete(const char *const search_str, gboolean previous)
|
||||
char* roster_barejid_autocomplete(const char *const search_str, gboolean previous);
|
||||
GSList* roster_get_contacts_by_presence(const char *const presence);
|
||||
char* roster_get_msg_display_name(const char *const barejid, const char *const resource);
|
||||
gint roster_compare_name(PContact a, PContact b);
|
||||
gint roster_compare_presence(PContact a, PContact b);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -926,7 +926,7 @@ stanza_create_disco_info_iq(xmpp_ctx_t *ctx, const char *const id, const char *c
|
||||
|
||||
xmpp_stanza_t*
|
||||
stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char *const id,
|
||||
const char *const jid)
|
||||
const char *const jid, const char *const node)
|
||||
{
|
||||
xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id);
|
||||
xmpp_stanza_set_to(iq, jid);
|
||||
@@ -934,6 +934,9 @@ stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char *const id,
|
||||
xmpp_stanza_t *query = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
|
||||
xmpp_stanza_set_ns(query, XMPP_NS_DISCO_ITEMS);
|
||||
if (node) {
|
||||
xmpp_stanza_set_attribute(query, STANZA_ATTR_NODE, node);
|
||||
}
|
||||
|
||||
xmpp_stanza_add_child(iq, query);
|
||||
xmpp_stanza_release(query);
|
||||
@@ -2040,6 +2043,53 @@ stanza_parse_presence(xmpp_stanza_t *stanza, int *err)
|
||||
return result;
|
||||
}
|
||||
|
||||
xmpp_stanza_t*
|
||||
stanza_create_command_exec_iq(xmpp_ctx_t *ctx, const char *const target,
|
||||
const char *const node)
|
||||
{
|
||||
char *id = connection_create_stanza_id("cmdexec");
|
||||
xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
|
||||
free(id);
|
||||
xmpp_stanza_set_to(iq, target);
|
||||
|
||||
xmpp_stanza_t *command = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_name(command, STANZA_NAME_COMMAND);
|
||||
|
||||
xmpp_stanza_set_ns(command, STANZA_NS_COMMAND);
|
||||
xmpp_stanza_set_attribute(command, "node", node);
|
||||
xmpp_stanza_set_attribute(command, "action", "execute");
|
||||
|
||||
xmpp_stanza_add_child(iq, command);
|
||||
xmpp_stanza_release(command);
|
||||
|
||||
return iq;
|
||||
}
|
||||
|
||||
xmpp_stanza_t*
|
||||
stanza_create_command_config_submit_iq(xmpp_ctx_t *ctx, const char *const room,
|
||||
const char *const node, const char *const sessionid, DataForm *form)
|
||||
{
|
||||
char *id = connection_create_stanza_id("commandconf_submit");
|
||||
xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
|
||||
free(id);
|
||||
xmpp_stanza_set_to(iq, room);
|
||||
|
||||
xmpp_stanza_t *command = xmpp_stanza_new(ctx);
|
||||
xmpp_stanza_set_name(command, STANZA_NAME_COMMAND);
|
||||
xmpp_stanza_set_ns(command, STANZA_NS_COMMAND);
|
||||
xmpp_stanza_set_attribute(command, "node", node);
|
||||
xmpp_stanza_set_attribute(command, "sessionid", sessionid);
|
||||
|
||||
xmpp_stanza_t *x = form_create_submission(form);
|
||||
xmpp_stanza_add_child(command, x);
|
||||
xmpp_stanza_release(x);
|
||||
|
||||
xmpp_stanza_add_child(iq, command);
|
||||
xmpp_stanza_release(command);
|
||||
|
||||
return iq;
|
||||
}
|
||||
|
||||
static void
|
||||
_stanza_add_unique_id(xmpp_stanza_t *stanza, char *prefix)
|
||||
{
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
#define STANZA_NAME_PUT "put"
|
||||
#define STANZA_NAME_GET "get"
|
||||
#define STANZA_NAME_URL "url"
|
||||
#define STANZA_NAME_COMMAND "command"
|
||||
|
||||
// error conditions
|
||||
#define STANZA_NAME_BAD_REQUEST "bad-request"
|
||||
@@ -156,6 +157,7 @@
|
||||
#define STANZA_ATTR_REASON "reason"
|
||||
#define STANZA_ATTR_AUTOJOIN "autojoin"
|
||||
#define STANZA_ATTR_PASSWORD "password"
|
||||
#define STANZA_ATTR_STATUS "status"
|
||||
|
||||
#define STANZA_TEXT_AWAY "away"
|
||||
#define STANZA_TEXT_DND "dnd"
|
||||
@@ -186,6 +188,7 @@
|
||||
#define STANZA_NS_HTTP_UPLOAD "urn:xmpp:http:upload"
|
||||
#define STANZA_NS_X_OOB "jabber:x:oob"
|
||||
#define STANZA_NS_BLOCKING "urn:xmpp:blocking"
|
||||
#define STANZA_NS_COMMAND "http://jabber.org/protocol/commands"
|
||||
|
||||
#define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
|
||||
|
||||
@@ -278,6 +281,9 @@ xmpp_stanza_t* stanza_create_room_subject_message(xmpp_ctx_t *ctx, const char *c
|
||||
xmpp_stanza_t* stanza_create_room_kick_iq(xmpp_ctx_t *const ctx, const char *const room, const char *const nick,
|
||||
const char *const reason);
|
||||
|
||||
xmpp_stanza_t* stanza_create_command_exec_iq(xmpp_ctx_t *ctx, const char *const target, const char *const node);
|
||||
xmpp_stanza_t* stanza_create_command_config_submit_iq(xmpp_ctx_t *ctx, const char *const room, const char *const node, const char *const sessionid, DataForm *form);
|
||||
|
||||
int stanza_get_idle_time(xmpp_stanza_t *const stanza);
|
||||
|
||||
void stanza_attach_priority(xmpp_ctx_t *const ctx, xmpp_stanza_t *const presence, const int pri);
|
||||
@@ -292,7 +298,7 @@ EntityCapabilities* stanza_create_caps_from_query_element(xmpp_stanza_t *query);
|
||||
|
||||
const char* stanza_get_presence_string_from_type(resource_presence_t presence_type);
|
||||
xmpp_stanza_t* stanza_create_software_version_iq(xmpp_ctx_t *ctx, const char *const fulljid);
|
||||
xmpp_stanza_t* stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char *const id, const char *const jid);
|
||||
xmpp_stanza_t* stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char *const id, const char *const jid, const char *const node);
|
||||
|
||||
char* stanza_get_status(xmpp_stanza_t *stanza, char *def);
|
||||
char* stanza_get_show(xmpp_stanza_t *stanza, char *def);
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#define XMPP_FEATURE_RECEIPTS "urn:xmpp:receipts"
|
||||
#define XMPP_FEATURE_LASTACTIVITY "jabber:iq:last"
|
||||
#define XMPP_FEATURE_MUC "http://jabber.org/protocol/muc"
|
||||
#define XMPP_FEATURE_COMMANDS "http://jabber.org/protocol/commands"
|
||||
|
||||
typedef enum {
|
||||
JABBER_CONNECTING,
|
||||
@@ -170,8 +171,8 @@ void iq_set_autoping(int seconds);
|
||||
void iq_confirm_instant_room(const char *const room_jid);
|
||||
void iq_destroy_room(const char *const room_jid);
|
||||
void iq_request_room_config_form(const char *const room_jid);
|
||||
void iq_submit_room_config(const char *const room, DataForm *form);
|
||||
void iq_room_config_cancel(const char *const room_jid);
|
||||
void iq_submit_room_config(ProfConfWin *confwin);
|
||||
void iq_room_config_cancel(ProfConfWin *confwin);
|
||||
void iq_send_ping(const char *const target);
|
||||
void iq_room_info_request(const char *const room, gboolean display_result);
|
||||
void iq_room_affiliation_list(const char *const room, char *affiliation);
|
||||
@@ -182,6 +183,8 @@ void iq_room_role_set(const char *const room, const char *const nick, char *role
|
||||
void iq_room_role_list(const char * const room, char *role);
|
||||
void iq_autoping_check(void);
|
||||
void iq_http_upload_request(HTTPUpload *upload);
|
||||
void iq_command_list(const char *const target);
|
||||
void iq_command_exec(const char *const target, const char *const command);
|
||||
|
||||
EntityCapabilities* caps_lookup(const char *const jid);
|
||||
void caps_close(void);
|
||||
|
||||
Reference in New Issue
Block a user