diff options
Diffstat (limited to 'src/rexmpp_console.c')
-rw-r--r-- | src/rexmpp_console.c | 645 |
1 files changed, 471 insertions, 174 deletions
diff --git a/src/rexmpp_console.c b/src/rexmpp_console.c index f2d748f..a6f859a 100644 --- a/src/rexmpp_console.c +++ b/src/rexmpp_console.c @@ -11,11 +11,15 @@ */ #include <string.h> +#include <stdlib.h> +#include <stdarg.h> #include "rexmpp.h" +#include "rexmpp_xml.h" #include "rexmpp_openpgp.h" #include "rexmpp_http_upload.h" #include "rexmpp_jingle.h" +#include "rexmpp_pubsub.h" #include "rexmpp_console.h" @@ -29,61 +33,60 @@ void rexmpp_console_printf (rexmpp_t *s, const char *format, ...) } } -char *rexmpp_console_message_string (rexmpp_t *s, xmlNodePtr node) { - char *ret = NULL; - xmlNodePtr openpgp = +const char *rexmpp_console_message_string (rexmpp_t *s, rexmpp_xml_t *node) { + const char *ret = NULL; + rexmpp_xml_t *openpgp = rexmpp_xml_find_child(node, "urn:xmpp:openpgp:0", "openpgp"); if (openpgp != NULL) { int valid; - xmlNodePtr elem = rexmpp_openpgp_decrypt_verify_message(s, node, &valid); + rexmpp_xml_t *elem = rexmpp_openpgp_decrypt_verify_message(s, node, &valid); if (! valid) { rexmpp_console_printf(s, "An invalid OpenPGP message!\n"); } if (elem != NULL) { - xmlNodePtr payload = + rexmpp_xml_t *payload = rexmpp_xml_find_child(elem, "urn:xmpp:openpgp:0", "payload"); if (payload != NULL) { - xmlNodePtr pl_body = + rexmpp_xml_t *pl_body = rexmpp_xml_find_child(payload, "jabber:client", "body"); if (pl_body != NULL) { - ret = xmlNodeGetContent(pl_body); + ret = rexmpp_xml_text_child(pl_body); } } - xmlFreeNode(elem); + rexmpp_xml_free(elem); } } if (ret == NULL) { - xmlNodePtr body = rexmpp_xml_find_child(node, "jabber:client", "body"); - ret = xmlNodeGetContent(body); + rexmpp_xml_t *body = + rexmpp_xml_find_child(node, "jabber:client", "body"); + ret = rexmpp_xml_text_child(body); } return ret; } -void rexmpp_console_on_send (rexmpp_t *s, xmlNodePtr node) { +void rexmpp_console_on_send (rexmpp_t *s, rexmpp_xml_t *node) { if (rexmpp_xml_match(node, "jabber:client", "message")) { - char *to = xmlGetProp(node, "to"); + const char *to = rexmpp_xml_find_attr_val(node, "to"); if (to != NULL) { /* "from" should be set for verification. */ - char *from = xmlGetProp(node, "from"); - xmlAttrPtr fromProp = NULL; - if (from == NULL) { - fromProp = xmlNewProp(node, "from", to); + int added_from = 0; + if (rexmpp_xml_find_attr_val(node, "from") == NULL) { + rexmpp_xml_add_attr(node, "from", to); + added_from = 1; } - char *str = rexmpp_console_message_string(s, node); - if (fromProp != NULL) { - xmlRemoveProp(fromProp); + const char *str = rexmpp_console_message_string(s, node); + if (added_from) { + rexmpp_xml_remove_attr(node, "from"); } if (str != NULL) { rexmpp_console_printf(s, "You tell %s: %s\n", to, str); - free(str); } - free(to); } } if (rexmpp_xml_match(node, "jabber:client", "presence")) { - char *presence_type = xmlGetProp(node, "type"); - char *presence_to = xmlGetProp(node, "to"); + const char *presence_type = rexmpp_xml_find_attr_val(node, "type"); + const char *presence_to = rexmpp_xml_find_attr_val(node, "to"); if (presence_to == NULL) { rexmpp_console_printf(s, "Becoming %s\n", (presence_type == NULL) ? @@ -105,72 +108,58 @@ void rexmpp_console_on_send (rexmpp_t *s, xmlNodePtr node) { "Denying %s's presence subscription request.\n", presence_to); } - free(presence_to); - } - if (presence_type != NULL) { - free(presence_type); } } } -void rexmpp_console_on_recv (rexmpp_t *s, xmlNodePtr node) { +void rexmpp_console_on_recv (rexmpp_t *s, rexmpp_xml_t *node) { if (rexmpp_xml_match(node, "jabber:client", "message")) { - xmlNodePtr sent = rexmpp_xml_find_child(node, "urn:xmpp:carbons:2", "sent"); + rexmpp_xml_t *sent = rexmpp_xml_find_child(node, "urn:xmpp:carbons:2", "sent"); if (sent != NULL) { - xmlNodePtr fwd = + rexmpp_xml_t *fwd = rexmpp_xml_find_child(sent, "urn:xmpp:forward:0", "forwarded"); if (fwd != NULL) { - xmlNodePtr msg = + rexmpp_xml_t *msg = rexmpp_xml_find_child(fwd, "jabber:client", "message"); if (msg != NULL) { - char *to = xmlGetProp(msg, "to"); - char *str = rexmpp_console_message_string(s, msg); + const char *to = rexmpp_xml_find_attr_val(msg, "to"); + const char *str = rexmpp_console_message_string(s, msg); if (str != NULL) { rexmpp_console_printf(s, "You tell %s: %s\n", to, str); - free(str); - } - if (to != NULL) { - free(to); } } } } - xmlNodePtr received = + rexmpp_xml_t *received = rexmpp_xml_find_child(node, "urn:xmpp:carbons:2", "received"); if (received != NULL) { - xmlNodePtr fwd = + rexmpp_xml_t *fwd = rexmpp_xml_find_child(received, "urn:xmpp:forward:0", "forwarded"); if (fwd != NULL) { - xmlNodePtr msg = + rexmpp_xml_t *msg = rexmpp_xml_find_child(fwd, "jabber:client", "message"); if (msg != NULL) { - char *from = xmlGetProp(msg, "from"); - char *str = rexmpp_console_message_string(s, msg); + const char *from = rexmpp_xml_find_attr_val(msg, "from"); + const char *str = rexmpp_console_message_string(s, msg); if (str != NULL) { rexmpp_console_printf(s, "%s tells you: %s\n", from, str); - free(str); - } - if (from != NULL) { - free(from); } } } } - char *from = xmlGetProp(node, "from"); + const char *from = rexmpp_xml_find_attr_val(node, "from"); if (from != NULL) { - char *str = rexmpp_console_message_string(s, node); + const char *str = rexmpp_console_message_string(s, node); if (str != NULL) { rexmpp_console_printf(s, "%s tells you: %s\n", from, str); - free(str); } - free(from); } } if (rexmpp_xml_match(node, "jabber:client", "presence")) { - char *presence_type = xmlGetProp(node, "type"); - char *from = xmlGetProp(node, "from"); + const char *presence_type = rexmpp_xml_find_attr_val(node, "type"); + const char *from = rexmpp_xml_find_attr_val(node, "from"); if (presence_type != NULL && ! strcmp(presence_type, "subscribe")) { rexmpp_console_printf(s, "%s requests a presence subscription\n", from); } else if (presence_type != NULL && ! strcmp(presence_type, "subscribed")) { @@ -182,74 +171,64 @@ void rexmpp_console_on_recv (rexmpp_t *s, xmlNodePtr node) { (presence_type == NULL) ? "available" : presence_type); - xmlNodePtr show = rexmpp_xml_find_child(node, "jabber:client", "show"); + rexmpp_xml_t *show = + rexmpp_xml_find_child(node, "jabber:client", "show"); if (show != NULL) { - char *show_str = xmlNodeGetContent(show); - rexmpp_console_printf(s, " (%s)", show_str); - free(show_str); - show_str = NULL; + rexmpp_console_printf(s, " (%s)", + rexmpp_xml_text_child(show)); } - xmlNodePtr status = rexmpp_xml_find_child(node, "jabber:client", "status"); + rexmpp_xml_t *status = + rexmpp_xml_find_child(node, "jabber:client", "status"); if (status != NULL) { - char *status_str = xmlNodeGetContent(status); - rexmpp_console_printf(s, ": %s", status_str); - free(status_str); - status_str = NULL; + rexmpp_console_printf(s, ": %s", + rexmpp_xml_text_child(status)); } rexmpp_console_printf(s, "\n"); } - if (presence_type != NULL) { - free(presence_type); - } - if (from != NULL) { - free(from); - } } } void rexmpp_console_roster_deleted (rexmpp_t *s, void *ptr, - xmlNodePtr req, - xmlNodePtr response, + rexmpp_xml_t *req, + rexmpp_xml_t *response, int success) { (void)ptr; (void)response; - xmlNodePtr item = + rexmpp_xml_t *item = rexmpp_xml_find_child(rexmpp_xml_find_child(req, "jabber:iq:roster", "query"), "jabber:iq:roster", "item"); - char *jid = xmlGetProp(item, "jid"); + const char *jid = rexmpp_xml_find_attr_val(item, "jid"); if (success) { rexmpp_console_printf(s, "Deleted %s from the roster.\n", jid); } else { rexmpp_console_printf(s, "Failed to delete %s from the roster.\n", jid); } - free(jid); } void rexmpp_console_roster_added (rexmpp_t *s, void *ptr, - xmlNodePtr req, - xmlNodePtr response, + rexmpp_xml_t *req, + rexmpp_xml_t *response, int success) { (void)ptr; (void)response; - xmlNodePtr item = + rexmpp_xml_t *item = rexmpp_xml_find_child(rexmpp_xml_find_child(req, "jabber:iq:roster", "query"), "jabber:iq:roster", "item"); - char *jid = xmlGetProp(item, "jid"); + const char *jid = rexmpp_xml_find_attr_val(item, "jid"); if (success) { rexmpp_console_printf(s, "Added %s into the roster.\n", jid); } else { rexmpp_console_printf(s, "Failed to add %s into the roster.\n", jid); } - free(jid); } void rexmpp_console_on_run (rexmpp_t *s, rexmpp_err_t result) { @@ -269,11 +248,210 @@ void rexmpp_console_on_upload (rexmpp_t *s, void *cb_data, const char *url) { free(fpath); } +void rexmpp_console_disco_info (rexmpp_t *s, + void *ptr, + rexmpp_xml_t *req, + rexmpp_xml_t *response, + int success) +{ + (void)ptr; + (void)req; + if (! success) { + rexmpp_console_printf(s, "Failed to discover info.\n"); + return; + } + rexmpp_xml_t *query = + rexmpp_xml_find_child(response, "http://jabber.org/protocol/disco#info", + "query"); + if (query == NULL) { + rexmpp_console_printf(s, "No disco#info query in response.\n"); + return; + } + const char *from = rexmpp_xml_find_attr_val(response, "from"); + if (from == NULL) { + rexmpp_console_printf(s, "No 'from' property in response.\n"); + return; + } + rexmpp_console_printf(s, "Discovered info for %s:\n", from); + rexmpp_xml_t *child = rexmpp_xml_first_elem_child(query); + while (child != NULL) { + if (rexmpp_xml_match(child, "http://jabber.org/protocol/disco#info", + "feature")) { + const char *var = rexmpp_xml_find_attr_val(child, "var"); + rexmpp_console_printf(s, "- feature var %s\n", var); + } else if (rexmpp_xml_match(child, "http://jabber.org/protocol/disco#info", + "identity")) { + const char *category = rexmpp_xml_find_attr_val(child, "category"); + const char *type = rexmpp_xml_find_attr_val(child, "type"); + const char *name = rexmpp_xml_find_attr_val(child, "name"); + rexmpp_console_printf(s, "- identity name %s, type %s, category %s\n", + name, type, category); + } else { + rexmpp_console_printf(s, "Encountered an unknown disco#info element.\n"); + } + child = rexmpp_xml_next_elem_sibling(child); + } + rexmpp_console_printf(s, "(end of discovered info for %s)\n", from); +} + +void rexmpp_console_disco_items (rexmpp_t *s, + void *ptr, + rexmpp_xml_t *req, + rexmpp_xml_t *response, + int success) +{ + (void)ptr; + (void)req; + if (! success) { + rexmpp_console_printf(s, "Failed to discover items.\n"); + return; + } + rexmpp_xml_t *query = + rexmpp_xml_find_child(response, "http://jabber.org/protocol/disco#items", + "query"); + if (query == NULL) { + rexmpp_console_printf(s, "No disco#items query in response.\n"); + return; + } + const char *from = rexmpp_xml_find_attr_val(response, "from"); + if (from == NULL) { + rexmpp_console_printf(s, "No 'from' property in response.\n"); + return; + } + rexmpp_console_printf(s, "Discovered items for %s:\n", from); + rexmpp_xml_t *child = rexmpp_xml_first_elem_child(query); + while (child != NULL) { + if (rexmpp_xml_match(child, "http://jabber.org/protocol/disco#items", + "item")) { + const char *jid = rexmpp_xml_find_attr_val(child, "jid"); + const char *name = rexmpp_xml_find_attr_val(child, "name"); + const char *node = rexmpp_xml_find_attr_val(child, "node"); + rexmpp_console_printf(s, "- item jid %s, name %s, node %s\n", jid, name, node); + } else { + rexmpp_console_printf(s, "Encountered an unknown disco#items element.\n"); + } + child = rexmpp_xml_next_elem_sibling(child); + } + rexmpp_console_printf(s, "(end of discovered items for %s)\n", from); +} + +void rexmpp_console_pubsub_node_deleted (rexmpp_t *s, + void *ptr, + rexmpp_xml_t *req, + rexmpp_xml_t *response, + int success) +{ + (void)ptr; + (void)req; + (void)response; + if (success) { + rexmpp_console_printf(s, "Deleted the pubsub node.\n"); + } else { + rexmpp_console_printf(s, "Failed to delete the pubsub node.\n"); + } +} + +void rexmpp_bookmark_added (rexmpp_t *s, + void *ptr, + rexmpp_xml_t *req, + rexmpp_xml_t *response, + int success) +{ + (void)ptr; + (void)req; + (void)response; + if (success) { + rexmpp_console_printf(s, "Added a bookmark.\n"); + } else { + rexmpp_console_printf(s, "Failed to add a bookmark.\n"); + } +} + +void rexmpp_bookmark_removed (rexmpp_t *s, + void *ptr, + rexmpp_xml_t *req, + rexmpp_xml_t *response, + int success) +{ + (void)ptr; + (void)req; + (void)response; + if (success) { + rexmpp_console_printf(s, "Removed a bookmark.\n"); + } else { + rexmpp_console_printf(s, "Failed to remove a bookmark.\n"); + } +} + +void rexmpp_console_blocklist (rexmpp_t *s, + void *ptr, + rexmpp_xml_t *req, + rexmpp_xml_t *response, + int success) +{ + (void)ptr; + (void)req; + if (success) { + rexmpp_xml_t *bl = + rexmpp_xml_find_child(response, "urn:xmpp:blocking", "blocklist"); + if (bl == NULL) { + rexmpp_console_printf(s, "No blocklist element in the response.\n"); + return; + } + rexmpp_console_printf(s, "Block list:"); + rexmpp_xml_t *child = rexmpp_xml_first_elem_child(bl); + while (child != NULL) { + if (rexmpp_xml_match(child, "urn:xmpp:blocking", "item")) { + const char *jid = rexmpp_xml_find_attr_val(child, "jid"); + rexmpp_console_printf(s, " %s", jid); + } else { + rexmpp_console_printf(s, "Encountered an unknown blocklist child element.\n"); + } + child = rexmpp_xml_next_elem_sibling(child); + } + rexmpp_console_printf(s, "\n"); + } else { + rexmpp_console_printf(s, "Failed to retrieve block list.\n"); + } +} + +void rexmpp_console_blocklist_blocked (rexmpp_t *s, + void *ptr, + rexmpp_xml_t *req, + rexmpp_xml_t *response, + int success) +{ + (void)ptr; + (void)req; + (void)response; + if (success) { + rexmpp_console_printf(s, "Blocklisted successfully.\n"); + } else { + rexmpp_console_printf(s, "Failed to blocklist.\n"); + } +} + +void rexmpp_console_blocklist_unblocked (rexmpp_t *s, + void *ptr, + rexmpp_xml_t *req, + rexmpp_xml_t *response, + int success) +{ + (void)ptr; + (void)req; + (void)response; + if (success) { + rexmpp_console_printf(s, "Un-blocklisted successfully.\n"); + } else { + rexmpp_console_printf(s, "Failed to un-blocklist.\n"); + } +} + void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { /* todo: buffering */ (void)str_len; /* Unused for now (todo). */ char *words_save_ptr; - xmlNodePtr presence; + rexmpp_xml_t *presence; char *word, *jid_str, *msg_text; struct rexmpp_jid jid; word = strtok_r(str, " ", &words_save_ptr); @@ -294,6 +472,8 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { "muc join <conference> [as] <nick>\n" "muc leave <conference> [as] <nick>\n" "muc tell <conference> <message>\n" + "bookmark add <conference> [autojoin] [nick] [password]\n" + "bookmark remove <conference>\n" "roster list\n" "roster add <jid>\n" "roster delete <jid>\n" @@ -305,8 +485,14 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { "jingle decline <sid>\n" "jingle accept-file <sid> <file path>\n" "jingle send-file <jid> <file path>\n" - "jingle accept-call <sid> <in port> <out port>\n" - "jingle call <jid> <in port> <out port>\n" + "jingle accept-call <sid>\n" + "jingle call <jid>\n" + "disco info <jid>\n" + "disco items <jid>\n" + "pubsub node delete <service_jid> <node>\n" + "blocklist\n" + "blocklist block <jid>\n" + "blocklist unblock <jid>\n" ; if (! strcmp(word, "help")) { @@ -337,11 +523,14 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { return; } msg_text = jid_str + strlen(jid_str) + 1; - xmlNodePtr msg = rexmpp_xml_add_id(s, xmlNewNode(NULL, "message")); - xmlNewNs(msg, "jabber:client", NULL); - xmlNewProp(msg, "to", jid.full); - xmlNewProp(msg, "type", "chat"); - xmlNewTextChild(msg, NULL, "body", msg_text); + + rexmpp_xml_t *msg = rexmpp_xml_new_elem("message", "jabber:client"); + rexmpp_xml_add_id(msg); + rexmpp_xml_add_attr(msg, "to", jid.full); + rexmpp_xml_add_attr(msg, "type", "chat"); + rexmpp_xml_t *body = rexmpp_xml_new_elem("body", NULL); + rexmpp_xml_add_text(body, msg_text); + rexmpp_xml_add_child(msg, body); rexmpp_send(s, msg); } @@ -353,9 +542,9 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { return; } msg_text = jid_str + strlen(jid_str) + 1; - xmlNodePtr body = xmlNewNode(NULL, "body"); - xmlNewNs(body, "jabber:client", NULL); - xmlNodeAddContent(body, msg_text); + rexmpp_xml_t *body = + rexmpp_xml_new_elem("body", "jabber:client"); + rexmpp_xml_add_text(body, msg_text); const char *rcpt[2]; rcpt[0] = jid.full; rcpt[1] = NULL; @@ -367,21 +556,20 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { } else if (strcmp(word, "crypt") == 0) { b64 = rexmpp_openpgp_payload(s, body, rcpt, NULL, REXMPP_OX_CRYPT); } - xmlNodePtr openpgp = xmlNewNode(NULL, "openpgp"); - openpgp->ns = xmlNewNs(openpgp, "urn:xmpp:openpgp:0", NULL); - xmlNodeAddContent(openpgp, b64); + rexmpp_xml_t *openpgp = + rexmpp_xml_new_elem("openpgp", "urn:xmpp:openpgp:0"); + rexmpp_xml_add_text(openpgp, b64); free(b64); - xmlNodePtr msg = rexmpp_xml_add_id(s, xmlNewNode(NULL, "message")); - xmlNewNs(msg, "jabber:client", NULL); - xmlNewProp(msg, "to", jid.full); - xmlNewProp(msg, "type", "chat"); - xmlAddChild(msg, openpgp); + rexmpp_xml_t *msg = rexmpp_xml_new_elem("message", "jabber:client"); + rexmpp_xml_add_id(msg); + rexmpp_xml_add_attr(msg, "to", jid.full); + rexmpp_xml_add_attr(msg, "type", "chat"); + rexmpp_xml_add_child(msg, openpgp); - body = xmlNewNode(NULL, "body"); - xmlNewNs(body, "jabber:client", NULL); - xmlNodeAddContent(body, "This is a secret message."); - xmlAddChild(msg, body); + body = rexmpp_xml_new_elem("body", "jabber:client"); + rexmpp_xml_add_text(body, "This is a secret message."); + rexmpp_xml_add_child(msg, body); rexmpp_send(s, msg); } @@ -394,11 +582,14 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { return; } msg_text = jid_str + strlen(jid_str) + 1; - xmlNodePtr msg = rexmpp_xml_add_id(s, xmlNewNode(NULL, "message")); - xmlNewNs(msg, "jabber:client", NULL); - xmlNewProp(msg, "to", jid.full); - xmlNewProp(msg, "type", "groupchat"); - xmlNewTextChild(msg, NULL, "body", msg_text); + + rexmpp_xml_t *msg = rexmpp_xml_new_elem("message", "jabber:client"); + rexmpp_xml_add_id(msg); + rexmpp_xml_add_attr(msg, "to", jid.full); + rexmpp_xml_add_attr(msg, "type", "groupchat"); + rexmpp_xml_t *body = rexmpp_xml_new_elem("body", NULL); + rexmpp_xml_add_text(body, msg_text); + rexmpp_xml_add_child(msg, body); rexmpp_send(s, msg); } if (! strcmp(word, "join")) { @@ -407,23 +598,20 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { return; } word = strtok_r(NULL, " ", &words_save_ptr); + if (word == NULL) { + return; + } if (! strcmp(word, "as")) { word = strtok_r(NULL, " ", &words_save_ptr); } if (word == NULL) { return; } - char *full_jid = malloc(strlen(jid.bare) + strlen(word) + 2); - snprintf(full_jid, strlen(jid_str) + strlen(word) + 2, "%s/%s", + char *occupant_jid = malloc(strlen(jid.bare) + strlen(word) + 2); + snprintf(occupant_jid, strlen(jid_str) + strlen(word) + 2, "%s/%s", jid.bare, word); - presence = rexmpp_xml_add_id(s, xmlNewNode(NULL, "presence")); - xmlNewProp(presence, "from", s->assigned_jid.full); - xmlNewProp(presence, "to", full_jid); - xmlNodePtr x = xmlNewNode(NULL, "x"); - xmlNewNs(x, "http://jabber.org/protocol/muc", NULL); - xmlAddChild(presence, x); - rexmpp_send(s, presence); - free(full_jid); + rexmpp_muc_join(s, occupant_jid, NULL, s->muc_ping_default_delay); + free(occupant_jid); } if (! strcmp(word, "leave")) { jid_str = strtok_r(NULL, " ", &words_save_ptr); @@ -431,21 +619,58 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { return; } word = strtok_r(NULL, " ", &words_save_ptr); + if (word == NULL) { + return; + } if (! strcmp(word, "as")) { word = strtok_r(NULL, " ", &words_save_ptr); } if (word == NULL) { return; } - char *full_jid = malloc(strlen(jid.bare) + strlen(word) + 2); - snprintf(full_jid, strlen(jid_str) + strlen(word) + 2, "%s/%s", + char *occupant_jid = malloc(strlen(jid.bare) + strlen(word) + 2); + snprintf(occupant_jid, strlen(jid_str) + strlen(word) + 2, "%s/%s", jid.bare, word); - presence = rexmpp_xml_add_id(s, xmlNewNode(NULL, "presence")); - xmlNewProp(presence, "from", s->assigned_jid.full); - xmlNewProp(presence, "to", full_jid); - xmlNewProp(presence, "type", "unavailable"); - rexmpp_send(s, presence); - free(full_jid); + rexmpp_muc_leave(s, occupant_jid); + free(occupant_jid); + } + } + + if (! strcmp(word, "bookmark")) { + word = strtok_r(NULL, " ", &words_save_ptr); + if (! strcmp(word, "add")) { + char *muc_jid = strtok_r(NULL, " ", &words_save_ptr); + if (muc_jid == NULL) { + return; + } + char *autojoin = strtok_r(NULL, " ", &words_save_ptr); + char *nick_str = strtok_r(NULL, " ", &words_save_ptr); + char *password = strtok_r(NULL, " ", &words_save_ptr); + + rexmpp_xml_t *conference = + rexmpp_xml_new_elem("conference", "urn:xmpp:bookmarks:1"); + if (autojoin != NULL) { + rexmpp_xml_add_attr(conference, "autojoin", autojoin); + } + if (password != NULL) { + rexmpp_xml_add_attr(conference, "password", password); + } + if (nick_str != NULL) { + rexmpp_xml_t *nick = + rexmpp_xml_new_elem("nick", "urn:xmpp:bookmarks:1"); + rexmpp_xml_add_text(nick, nick_str); + rexmpp_xml_add_child(conference, nick); + } + rexmpp_pubsub_item_publish(s, NULL, "urn:xmpp:bookmarks:1", muc_jid, + conference, rexmpp_bookmark_added, NULL); + } + if (! strcmp(word, "remove")) { + char *muc_jid = strtok_r(NULL, " ", &words_save_ptr); + if (muc_jid == NULL) { + return; + } + rexmpp_pubsub_item_retract(s, NULL, "urn:xmpp:bookmarks:1", muc_jid, + rexmpp_bookmark_removed, NULL); } } @@ -455,25 +680,26 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { return; } if (! strcmp(word, "list")) { - xmlNodePtr item; + rexmpp_xml_t *item; for (item = s->roster_items; item != NULL; - item = xmlNextElementSibling(item)) { - char *item_jid = xmlGetProp(item, "jid"); - char *item_ask = xmlGetProp(item, "ask"); - char *item_subscription = xmlGetProp(item, "subscription"); + item = item->next) { + const char *item_jid = rexmpp_xml_find_attr_val(item, "jid"); + const char *item_ask = rexmpp_xml_find_attr_val(item, "ask"); + const char *item_subscription = + rexmpp_xml_find_attr_val(item, "subscription"); char *item_presence = "unavailable"; if (s->track_roster_presence) { for (presence = s->roster_presence; presence != NULL; - presence = xmlNextElementSibling(presence)) { - char *presence_from = xmlGetProp(presence, "from"); + presence = presence->next) { + const char *presence_from = + rexmpp_xml_find_attr_val(presence, "from"); if (presence_from != NULL) { rexmpp_jid_parse(presence_from, &jid); if (! strcmp(jid.bare, item_jid)) { item_presence = "available"; } - free(presence_from); } } } @@ -482,28 +708,19 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { "presence = %s\n", item_jid, item_subscription, item_ask, item_presence); - if (item_jid != NULL) { - free(item_jid); - } - if (item_ask != NULL) { - free(item_ask); - } - if (item_subscription != NULL) { - free(item_subscription); - } } } else if (! strcmp(word, "delete")) { word = strtok_r(NULL, " ", &words_save_ptr); if (word == NULL) { return; } - xmlNodePtr delete_item = xmlNewNode(NULL, "item"); - delete_item->ns = xmlNewNs(delete_item, "jabber:iq:roster", NULL); - xmlNewProp(delete_item, "jid", word); - xmlNewProp(delete_item, "subscription", "remove"); - xmlNodePtr delete_query = xmlNewNode(NULL, "query"); - delete_query->ns = xmlNewNs(delete_query, "jabber:iq:roster", NULL); - xmlAddChild(delete_query, delete_item); + rexmpp_xml_t *delete_item = + rexmpp_xml_new_elem("item", "jabber:iq:roster"); + rexmpp_xml_add_attr(delete_item, "jid", word); + rexmpp_xml_add_attr(delete_item, "subscription", "remove"); + rexmpp_xml_t *delete_query = + rexmpp_xml_new_elem("query", "jabber:iq:roster"); + rexmpp_xml_add_child(delete_query, delete_item); rexmpp_iq_new(s, "set", NULL, delete_query, rexmpp_console_roster_deleted, NULL); } else if (! strcmp(word, "add")) { @@ -511,13 +728,13 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { if (word == NULL) { return; } - xmlNodePtr delete_item = xmlNewNode(NULL, "item"); - delete_item->ns = xmlNewNs(delete_item, "jabber:iq:roster", NULL); - xmlNewProp(delete_item, "jid", word); - xmlNodePtr delete_query = xmlNewNode(NULL, "query"); - delete_query->ns = xmlNewNs(delete_query, "jabber:iq:roster", NULL); - xmlAddChild(delete_query, delete_item); - rexmpp_iq_new(s, "set", NULL, delete_query, + rexmpp_xml_t *add_item = + rexmpp_xml_new_elem("item", "jabber:iq:roster"); + rexmpp_xml_add_attr(add_item, "jid", word); + rexmpp_xml_t *add_query = + rexmpp_xml_new_elem("query", "jabber:iq:roster"); + rexmpp_xml_add_child(add_query, add_item); + rexmpp_iq_new(s, "set", NULL, add_query, rexmpp_console_roster_added, NULL); } } @@ -532,9 +749,10 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { if (word == NULL) { return; } - presence = rexmpp_xml_add_id(s, xmlNewNode(NULL, "presence")); - xmlNewProp(presence, "to", word); - xmlNewProp(presence, "type", "subscribe"); + presence = rexmpp_xml_new_elem("presence", "jabber:client"); + rexmpp_xml_add_id(presence); + rexmpp_xml_add_attr(presence, "to", word); + rexmpp_xml_add_attr(presence, "type", "subscribe"); rexmpp_send(s, presence); } if (! strcmp(word, "approve")) { @@ -542,9 +760,10 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { if (word == NULL) { return; } - presence = rexmpp_xml_add_id(s, xmlNewNode(NULL, "presence")); - xmlNewProp(presence, "to", word); - xmlNewProp(presence, "type", "subscribed"); + presence = rexmpp_xml_new_elem("presence", "jabber:client"); + rexmpp_xml_add_id(presence); + rexmpp_xml_add_attr(presence, "to", word); + rexmpp_xml_add_attr(presence, "type", "subscribed"); rexmpp_send(s, presence); } if (! strcmp(word, "deny")) { @@ -552,9 +771,10 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { if (word == NULL) { return; } - presence = rexmpp_xml_add_id(s, xmlNewNode(NULL, "presence")); - xmlNewProp(presence, "to", word); - xmlNewProp(presence, "type", "unsubscribed"); + presence = rexmpp_xml_new_elem("presence", "jabber:client"); + rexmpp_xml_add_id(presence); + rexmpp_xml_add_attr(presence, "to", word); + rexmpp_xml_add_attr(presence, "type", "unsubscribed"); rexmpp_send(s, presence); } } @@ -574,7 +794,7 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { char *sid = strtok_r(NULL, " ", &words_save_ptr); if (sid != NULL) { rexmpp_jingle_session_terminate(s, sid, - rexmpp_xml_new_node("success", + rexmpp_xml_new_elem("success", "urn:xmpp:jingle:1"), NULL); } @@ -582,7 +802,7 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { char *sid = strtok_r(NULL, " ", &words_save_ptr); if (sid != NULL) { rexmpp_jingle_session_terminate(s, sid, - rexmpp_xml_new_node("decline", + rexmpp_xml_new_elem("decline", "urn:xmpp:jingle:1"), NULL); } @@ -600,18 +820,95 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) { } } else if (! strcmp(word, "accept-call")) { char *sid = strtok_r(NULL, " ", &words_save_ptr); - char *port_in = strtok_r(NULL, " ", &words_save_ptr); - char *port_out = strtok_r(NULL, " ", &words_save_ptr); - if (sid != NULL && port_in != NULL && port_out != NULL) { - rexmpp_jingle_call_accept(s, sid, atoi(port_in), atoi(port_out)); + if (sid != NULL) { + rexmpp_jingle_call_accept(s, sid); } } else if (! strcmp(word, "call")) { char *jid = strtok_r(NULL, " ", &words_save_ptr); - char *port_in = strtok_r(NULL, " ", &words_save_ptr); - char *port_out = strtok_r(NULL, " ", &words_save_ptr); - if (jid != NULL && port_in != NULL && port_out != NULL) { - rexmpp_jingle_call(s, jid, atoi(port_in), atoi(port_out)); + if (jid != NULL) { + rexmpp_jingle_call(s, jid); + } + } + } + + if (! strcmp(word, "disco")) { + word = strtok_r(NULL, " ", &words_save_ptr); + if (word == NULL) { + return; + } + if (! strcmp(word, "info")) { + char *jid = strtok_r(NULL, " ", &words_save_ptr); + if (jid == NULL) { + return; + } + rexmpp_xml_t *query = + rexmpp_xml_new_elem("query", + "http://jabber.org/protocol/disco#info"); + rexmpp_iq_new(s, "get", jid, query, rexmpp_console_disco_info, NULL); + } + if (! strcmp(word, "items")) { + char *jid = strtok_r(NULL, " ", &words_save_ptr); + if (jid == NULL) { + return; + } + rexmpp_xml_t *query = + rexmpp_xml_new_elem("query", + "http://jabber.org/protocol/disco#items"); + rexmpp_iq_new(s, "get", jid, query, rexmpp_console_disco_items, NULL); + } + } + + if (! strcmp(word, "pubsub")) { + word = strtok_r(NULL, " ", &words_save_ptr); + if (word == NULL) { + return; + } + if (! strcmp(word, "node")) { + word = strtok_r(NULL, " ", &words_save_ptr); + if (word == NULL) { + return; + } + if (! strcmp(word, "delete")) { + char *service_jid = strtok_r(NULL, " ", &words_save_ptr); + char *node = strtok_r(NULL, " ", &words_save_ptr); + if (service_jid == NULL || node == NULL) { + return; + } + rexmpp_pubsub_node_delete(s, service_jid, node, rexmpp_console_pubsub_node_deleted, NULL); + } + } + } + + if (! strcmp(word, "blocklist")) { + word = strtok_r(NULL, " ", &words_save_ptr); + if (word == NULL) { + rexmpp_xml_t *bl = + rexmpp_xml_new_elem("blocklist", "urn:xmpp:blocking"); + rexmpp_iq_new(s, "get", NULL, bl, rexmpp_console_blocklist, NULL); + } else if (! strcmp(word, "block")) { + char *jid = strtok_r(NULL, " ", &words_save_ptr); + if (jid == NULL) { + return; + } + rexmpp_xml_t *bl = + rexmpp_xml_new_elem("block", "urn:xmpp:blocking"); + rexmpp_xml_t *item = + rexmpp_xml_new_elem("item", "urn:xmpp:blocking"); + rexmpp_xml_add_attr(item, "jid", jid); + rexmpp_xml_add_child(bl, item); + rexmpp_iq_new(s, "set", NULL, bl, rexmpp_console_blocklist_blocked, NULL); + } else if (! strcmp(word, "unblock")) { + char *jid = strtok_r(NULL, " ", &words_save_ptr); + if (jid == NULL) { + return; } + rexmpp_xml_t *bl = + rexmpp_xml_new_elem("unblock", "urn:xmpp:blocking"); + rexmpp_xml_t *item = + rexmpp_xml_new_elem("item", "urn:xmpp:blocking"); + rexmpp_xml_add_attr(item, "jid", jid); + rexmpp_xml_add_child(bl, item); + rexmpp_iq_new(s, "set", NULL, bl, rexmpp_console_blocklist_unblocked, NULL); } } } |