summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordefanor <defanor@uberspace.net>2020-03-27 21:07:10 +0300
committerdefanor <defanor@uberspace.net>2020-03-27 21:07:10 +0300
commit8c621b46145e07e3eb3515a58f44ae6cd62caf0d (patch)
tree212fc6c884fc395df03580ff7e52c2b4cde23d4d
parent0b7ee1e683b55610379d7d4ee8da8ddfd0b49ffe (diff)
Move roster functions into a separate file
-rw-r--r--src/Makefile.am7
-rw-r--r--src/rexmpp.c135
-rw-r--r--src/rexmpp.h4
-rw-r--r--src/rexmpp_roster.c146
-rw-r--r--src/rexmpp_roster.h20
5 files changed, 176 insertions, 136 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c3a62bf..741add0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,10 @@ AM_CFLAGS = -Werror -Wall -Wextra -Wno-pointer-sign -Wno-unused-parameter
lib_LTLIBRARIES = librexmpp.la
-librexmpp_la_SOURCES = rexmpp_tcp.h rexmpp_tcp.c rexmpp_socks.h rexmpp_socks.c rexmpp.h rexmpp.c
-include_HEADERS = rexmpp_tcp.h rexmpp_socks.h rexmpp.h
+librexmpp_la_SOURCES = rexmpp_roster.h rexmpp_roster.c \
+ rexmpp_tcp.h rexmpp_tcp.c \
+ rexmpp_socks.h rexmpp_socks.c \
+ rexmpp.h rexmpp.c
+include_HEADERS = rexmpp_roster.h rexmpp_tcp.h rexmpp_socks.h rexmpp.h
librexmpp_la_CFLAGS = $(AM_CFLAGS) $(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(GSASL_CFLAGS) $(CARES_CFLAGS)
librexmpp_la_LIBADD = $(LIBXML_LIBS) $(GNUTLS_LIBS) $(GSASL_LIBS) $(CARES_LIBS)
diff --git a/src/rexmpp.c b/src/rexmpp.c
index 51229b7..fe04481 100644
--- a/src/rexmpp.c
+++ b/src/rexmpp.c
@@ -23,7 +23,7 @@
#include "rexmpp.h"
#include "rexmpp_tcp.h"
#include "rexmpp_socks.h"
-
+#include "rexmpp_roster.h"
void rexmpp_sax_start_elem_ns (rexmpp_t *s,
const char *localname,
@@ -1082,139 +1082,6 @@ void rexmpp_iq_discovery_info (rexmpp_t *s,
}
}
-xmlNodePtr rexmpp_roster_find_item (rexmpp_t *s,
- const char *jid,
- xmlNodePtr *prev_item)
-{
- xmlNodePtr prev = NULL, cur = s->roster_items;
- while (cur != NULL) {
- char *cur_jid = xmlGetProp(cur, "jid");
- if (cur_jid == NULL) {
- rexmpp_log(s, LOG_ALERT, "No jid found in a roster item.");
- return NULL;
- }
- int match = (strcmp(cur_jid, jid) == 0);
- free(cur_jid);
- if (match) {
- if (prev_item != NULL) {
- *prev_item = prev;
- }
- return cur;
- }
- prev = cur;
- cur = cur->next;
- }
- return NULL;
-}
-
-rexmpp_err_t rexmpp_modify_roster (rexmpp_t *s, xmlNodePtr item) {
- rexmpp_err_t ret = REXMPP_SUCCESS;
- if (! rexmpp_xml_match(item, "jabber:iq:roster", "item")) {
- rexmpp_log(s, LOG_ERR, "No roster item.");
- return REXMPP_E_PARAM;
- }
- char *subscription = xmlGetProp(item, "subscription");
- char *jid = xmlGetProp(item, "jid");
- if (subscription != NULL && strcmp(subscription, "remove") == 0) {
- /* Delete the item. */
- xmlNodePtr prev, cur;
- cur = rexmpp_roster_find_item(s, jid, &prev);
- if (cur != NULL) {
- if (prev != NULL) {
- prev->next = cur->next;
- } else {
- s->roster_items = cur->next;
- }
- xmlFreeNode(cur);
- } else {
- ret = REXMPP_E_ROSTER_ITEM_NOT_FOUND;
- }
- } else {
- /* Add or modify the item. */
- xmlNodePtr cur, prev;
- cur = rexmpp_roster_find_item(s, jid, &prev);
- /* Remove the item if it was in the roster before. */
- if (cur != NULL) {
- if (prev != NULL) {
- prev->next = cur->next;
- } else {
- s->roster_items = cur->next;
- }
- xmlFreeNode(cur);
- }
- /* Add the new item. */
- xmlNodePtr new_item = xmlCopyNode(item, 1);
- new_item->next = s->roster_items;
- s->roster_items = new_item;
- }
- free(jid);
- if (subscription != NULL) {
- free(subscription);
- }
- return ret;
-}
-
-void rexmpp_roster_set (rexmpp_t *s, xmlNodePtr query) {
- if (s->roster_items != NULL) {
- xmlFreeNodeList(s->roster_items);
- }
- if (s->roster_ver != NULL) {
- free(s->roster_ver);
- }
- s->roster_ver = xmlGetProp(query, "ver");
- s->roster_items = xmlCopyNodeList(xmlFirstElementChild(query));
-}
-
-void rexmpp_roster_cache_read (rexmpp_t *s) {
- if (s->roster_cache_file == NULL) {
- rexmpp_log(s, LOG_WARNING, "No roster cache file path is set.");
- return;
- }
- xmlDocPtr doc = xmlReadFile(s->roster_cache_file, "utf-8", XML_PARSE_NONET);
- xmlNodePtr query = xmlDocGetRootElement(doc);
- rexmpp_roster_set(s, query);
- xmlFreeDoc(doc);
-}
-
-void rexmpp_roster_cache_write (rexmpp_t *s) {
- if (s->roster_cache_file == NULL) {
- rexmpp_log(s, LOG_WARNING, "No roster cache file path is set.");
- return;
- }
- xmlDocPtr doc = xmlNewDoc("1.0");
- xmlNodePtr query = xmlNewDocNode(doc, NULL, "query", NULL);
- xmlDocSetRootElement(doc, query);
- xmlNewNs(query, "jabber:iq:roster", NULL);
- if (s->roster_ver != NULL) {
- xmlNewProp(query, "ver", s->roster_ver);
- }
- if (s->roster_items != NULL) {
- xmlAddChild(query, xmlDocCopyNodeList(doc, s->roster_items));
- }
- xmlSaveFileEnc(s->roster_cache_file, doc, "utf-8");
- xmlFreeDoc(doc);
-}
-
-void rexmpp_iq_roster_get (rexmpp_t *s,
- xmlNodePtr req,
- xmlNodePtr response,
- int success)
-{
- if (! success) {
- rexmpp_log(s, LOG_ERR, "Roster loading failed.");
- return;
- }
- xmlNodePtr query = xmlFirstElementChild(response);
- if (! rexmpp_xml_match(query, "jabber:iq:roster", "query")) {
- rexmpp_log(s, LOG_DEBUG, "No roster query in reply.");
- return;
- }
- rexmpp_roster_set(s, query);
- if (s->roster_cache_file != NULL) {
- rexmpp_roster_cache_write(s);
- }
-}
-
void rexmpp_stream_is_ready(rexmpp_t *s) {
s->stream_state = REXMPP_STREAM_READY;
rexmpp_resend_stanzas(s);
diff --git a/src/rexmpp.h b/src/rexmpp.h
index c7b07b0..7679546 100644
--- a/src/rexmpp.h
+++ b/src/rexmpp.h
@@ -390,4 +390,8 @@ int rexmpp_fds (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds);
char *rexmpp_xml_serialize (xmlNodePtr node);
xmlNodePtr rexmpp_xml_add_id (rexmpp_t *s, xmlNodePtr node);
+void rexmpp_log (rexmpp_t *s, int priority, const char *format, ...);
+int rexmpp_xml_match (xmlNodePtr node,
+ const char *namespace,
+ const char *name);
#endif
diff --git a/src/rexmpp_roster.c b/src/rexmpp_roster.c
new file mode 100644
index 0000000..8479c14
--- /dev/null
+++ b/src/rexmpp_roster.c
@@ -0,0 +1,146 @@
+/**
+ @file rexmpp_roster.c
+ @brief Roster-related functions.
+ @author defanor <defanor@uberspace.net>
+ @date 2020
+ @copyright MIT license.
+*/
+
+#include "rexmpp.h"
+#include <syslog.h>
+#include <string.h>
+#include <libxml/tree.h>
+#include <libxml/xmlsave.h>
+
+xmlNodePtr rexmpp_roster_find_item (rexmpp_t *s,
+ const char *jid,
+ xmlNodePtr *prev_item)
+{
+ xmlNodePtr prev = NULL, cur = s->roster_items;
+ while (cur != NULL) {
+ char *cur_jid = xmlGetProp(cur, "jid");
+ if (cur_jid == NULL) {
+ rexmpp_log(s, LOG_ALERT, "No jid found in a roster item.");
+ return NULL;
+ }
+ int match = (strcmp(cur_jid, jid) == 0);
+ free(cur_jid);
+ if (match) {
+ if (prev_item != NULL) {
+ *prev_item = prev;
+ }
+ return cur;
+ }
+ prev = cur;
+ cur = cur->next;
+ }
+ return NULL;
+}
+
+rexmpp_err_t rexmpp_modify_roster (rexmpp_t *s, xmlNodePtr item) {
+ rexmpp_err_t ret = REXMPP_SUCCESS;
+ if (! rexmpp_xml_match(item, "jabber:iq:roster", "item")) {
+ rexmpp_log(s, LOG_ERR, "No roster item.");
+ return REXMPP_E_PARAM;
+ }
+ char *subscription = xmlGetProp(item, "subscription");
+ char *jid = xmlGetProp(item, "jid");
+ if (subscription != NULL && strcmp(subscription, "remove") == 0) {
+ /* Delete the item. */
+ xmlNodePtr prev, cur;
+ cur = rexmpp_roster_find_item(s, jid, &prev);
+ if (cur != NULL) {
+ if (prev != NULL) {
+ prev->next = cur->next;
+ } else {
+ s->roster_items = cur->next;
+ }
+ xmlFreeNode(cur);
+ } else {
+ ret = REXMPP_E_ROSTER_ITEM_NOT_FOUND;
+ }
+ } else {
+ /* Add or modify the item. */
+ xmlNodePtr cur, prev;
+ cur = rexmpp_roster_find_item(s, jid, &prev);
+ /* Remove the item if it was in the roster before. */
+ if (cur != NULL) {
+ if (prev != NULL) {
+ prev->next = cur->next;
+ } else {
+ s->roster_items = cur->next;
+ }
+ xmlFreeNode(cur);
+ }
+ /* Add the new item. */
+ xmlNodePtr new_item = xmlCopyNode(item, 1);
+ new_item->next = s->roster_items;
+ s->roster_items = new_item;
+ }
+ free(jid);
+ if (subscription != NULL) {
+ free(subscription);
+ }
+ return ret;
+}
+
+void rexmpp_roster_set (rexmpp_t *s, xmlNodePtr query) {
+ if (s->roster_items != NULL) {
+ xmlFreeNodeList(s->roster_items);
+ }
+ if (s->roster_ver != NULL) {
+ free(s->roster_ver);
+ }
+ s->roster_ver = xmlGetProp(query, "ver");
+ s->roster_items = xmlCopyNodeList(xmlFirstElementChild(query));
+}
+
+void rexmpp_roster_cache_read (rexmpp_t *s) {
+ if (s->roster_cache_file == NULL) {
+ rexmpp_log(s, LOG_WARNING, "No roster cache file path is set.");
+ return;
+ }
+ xmlDocPtr doc = xmlReadFile(s->roster_cache_file, "utf-8", XML_PARSE_NONET);
+ xmlNodePtr query = xmlDocGetRootElement(doc);
+ rexmpp_roster_set(s, query);
+ xmlFreeDoc(doc);
+}
+
+void rexmpp_roster_cache_write (rexmpp_t *s) {
+ if (s->roster_cache_file == NULL) {
+ rexmpp_log(s, LOG_WARNING, "No roster cache file path is set.");
+ return;
+ }
+ xmlDocPtr doc = xmlNewDoc("1.0");
+ xmlNodePtr query = xmlNewDocNode(doc, NULL, "query", NULL);
+ xmlDocSetRootElement(doc, query);
+ xmlNewNs(query, "jabber:iq:roster", NULL);
+ if (s->roster_ver != NULL) {
+ xmlNewProp(query, "ver", s->roster_ver);
+ }
+ if (s->roster_items != NULL) {
+ xmlAddChild(query, xmlDocCopyNodeList(doc, s->roster_items));
+ }
+ xmlSaveFileEnc(s->roster_cache_file, doc, "utf-8");
+ xmlFreeDoc(doc);
+}
+
+void rexmpp_iq_roster_get (rexmpp_t *s,
+ xmlNodePtr req,
+ xmlNodePtr response,
+ int success)
+{
+ if (! success) {
+ rexmpp_log(s, LOG_ERR, "Roster loading failed.");
+ return;
+ }
+ xmlNodePtr query = xmlFirstElementChild(response);
+ if (! rexmpp_xml_match(query, "jabber:iq:roster", "query")) {
+ rexmpp_log(s, LOG_DEBUG, "No roster query in reply.");
+ return;
+ }
+ rexmpp_roster_set(s, query);
+ if (s->roster_cache_file != NULL) {
+ rexmpp_roster_cache_write(s);
+ }
+}
diff --git a/src/rexmpp_roster.h b/src/rexmpp_roster.h
new file mode 100644
index 0000000..d9e41fd
--- /dev/null
+++ b/src/rexmpp_roster.h
@@ -0,0 +1,20 @@
+/**
+ @file rexmpp_roster.h
+ @brief Roster-related functions.
+ @author defanor <defanor@uberspace.net>
+ @date 2020
+ @copyright MIT license.
+*/
+
+
+xmlNodePtr rexmpp_roster_find_item (rexmpp_t *s,
+ const char *jid,
+ xmlNodePtr *prev_item);
+rexmpp_err_t rexmpp_modify_roster (rexmpp_t *s, xmlNodePtr item);
+void rexmpp_roster_set (rexmpp_t *s, xmlNodePtr query);
+void rexmpp_roster_cache_read (rexmpp_t *s);
+void rexmpp_roster_cache_write (rexmpp_t *s);
+void rexmpp_iq_roster_get (rexmpp_t *s,
+ xmlNodePtr req,
+ xmlNodePtr response,
+ int success);