sj definitely rocks. Now I can use the following shell script to see which of my buddies are online, and to keep it constantly updated call it from watch:
#!/bin/sh cd "$SJ_DIR" if pgrep presenced > /dev/null; then egrep '.+' `find . -name status` | sed 's|\./||g' | sed 's|:|: |g' else echo 'Presence daemon not running' fi On Tue, Dec 08, 2015 at 07:46:02PM -0500, Greg Reagle wrote: > 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 >