Patch attached.

--
"No data yet," he answered. "It is a capital mistake to theorize before you have all the evidence. It biases the judgement."
by Arthur Conan Doyle via his character Sherlock Holmes
>From feed0b1c94c49b6850b6504a9d9bc9ae2780dec8 Mon Sep 17 00:00:00 2001
From: Greg Reagle <greg.rea...@umbc.edu>
Date: Tue, 8 Dec 2015 19:38:33 -0500
Subject: [PATCH] Properly receive and respond to presence notices.

An empty (zero bytes) status file indicates offline.  A non-empty (one or more bytes) status file indicates online.  Default online status text is "online", unless overridden by a show element.
---
 presenced.c | 40 ++++++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/presenced.c b/presenced.c
index fed559b..bf42811 100644
--- a/presenced.c
+++ b/presenced.c
@@ -213,13 +213,13 @@ recv_presence(char *tag, void *data)
 	/* HACK: we need this, cause mxml can't parse tags by itself */
 	static mxml_node_t *tree = NULL;
 	static mxml_node_t *node = NULL;
-	static mxml_node_t *status = NULL;
 	const char *base = "<?xml ?><stream:stream></stream:stream>";
 	const char *tag_name = NULL;
 	const char *from = NULL;
 	char *slash = NULL;
 	char path[PATH_MAX];
 	int fd;
+	int is_online = 0;
 
 	if (tree == NULL) tree = mxmlLoadString(NULL, base, MXML_NO_CALLBACK);
 	if (tree == NULL) err(EXIT_FAILURE, "%s: no xml tree found", __func__);
@@ -234,6 +234,11 @@ recv_presence(char *tag, void *data)
 	if ((from = mxmlElementGetAttr(tree->child->next, "from")) == NULL)
 		goto err;
 
+	if (mxmlElementGetAttr(tree->child->next, "type"))
+		is_online = 0; /* presense of 'type' attribute indicates offline */
+	else
+		is_online = 1;  /* lack of 'type' attribute indicates online */
+
 	/* cut off resourcepart from jabber ID */
 	if ((slash = strchr(from, '/')) != NULL)
 		*slash = '\0';
@@ -251,25 +256,24 @@ recv_presence(char *tag, void *data)
 
 	snprintf(path, sizeof path, "%s/%s/status", ctx->dir, from);
 
-	status = mxmlFindElement(node, tree, "status", NULL, NULL,
-	    MXML_DESCEND_FIRST);
+	if ((fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR))
+		== -1)
+		goto err;
 
-	if (status != NULL) {
-		if ((fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR))
-		    == -1)
-			goto err;
-		/* write text of status-tag into this file */
-		/* concatinate all text peaces */
-		for (mxml_node_t *txt = status->child; txt != NULL;
-				txt = mxmlGetNextSibling(txt)) {
-			int space = 0;
-			const char *t = mxmlGetText(txt, &space);
-			if (space == 1)
-				write(fd, " ", 1);
-			if (write(fd, t, strlen(t)) == -1) goto err;
-		}
-		if (close(fd) == -1) goto err;
+	if (is_online) { 
+		mxml_node_t *show = NULL;
+		const char *status;
+		if (show = mxmlFindElement(node, tree, "show", NULL, NULL,
+		                           MXML_DESCEND_FIRST))
+			status = mxmlGetText(show, NULL);
+		else
+			status = "online";
+		if (write(fd, status, strlen(status)) == -1) goto err;
+	} else { 
+		; /* write nothing; make fd an empty file */
 	}
+	if (close(fd) == -1) goto err; 
+
  err:
 	if (errno != 0)
 		perror(__func__);
-- 
2.1.4

Reply via email to