<html lang='en'>
<head>
<meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
<title>
GitLab
</title>
</meta>
</head>
<style>
  img {
    max-width: 100%;
    height: auto;
  }
  p.details {
    font-style:italic;
    color:#777
  }
  .footer p {
    font-size:small;
    color:#777
  }
  pre.commit-message {
    white-space: pre-wrap;
  }
  .file-stats a {
    text-decoration: none;
  }
  .file-stats .new-file {
    color: #090;
  }
  .file-stats .deleted-file {
    color: #B00;
  }
</style>
<body>
<div class='content'>
<h3>Justin Mitchell pushed to branch master at <a href="https://projects.sucs.org/arthur/mw">Justin Mitchell / mw</a></h3>
<h4>
Commits:
</h4>
<ul>
<li>
<strong><a href="https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470">d725e0a5</a></strong>
<div>
<span>by Justin Mitchell</span>
<i>at 2015-10-08T16:00:18Z</i>
</div>
<pre class='commit-message'>Goodbye who.bb, gone forever, and good riddance</pre>
</li>
</ul>
<h4>19 changed files:</h4>
<ul>
<li class='file-stats'>
<a href='#diff-0'>
INSTALL
</a>
</li>
<li class='file-stats'>
<a href='#diff-1'>
src/client/js.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-2'>
src/client/main.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-3'>
src/client/script_inst.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-4'>
src/client/who.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-5'>
src/client/who.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-6'>
src/ipc.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-7'>
src/ipc.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-8'>
src/server/PROTOCOL
</a>
</li>
<li class='file-stats'>
<a href='#diff-9'>
src/server/mwserv.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-10'>
src/server/replay.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-11'>
src/server/servsock.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-12'>
src/server/servsock.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-13'>
src/socket.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-14'>
src/webclient/comms.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-15'>
src/webclient/comms.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-16'>
<span class='deleted-file'>

src/who.c
</span>
</a>
</li>
<li class='file-stats'>
<a href='#diff-17'>
<span class='deleted-file'>

src/who.h
</span>
</a>
</li>
<li class='file-stats'>
<a href='#diff-18'>
web/bb.h
</a>
</li>
</ul>
<h4>Changes:</h4>
<li id='diff-0'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-0'>
<strong>
INSTALL
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/INSTALL
</span><span style="color: #000000;background-color: #ddffdd">+++ b/INSTALL
</span><span style="color: #aaaaaa">@@ -14,8 +14,8 @@ Milliways III installation notes
</span>     the libdir and bindir variables in Makefile as appropriate. `make install'
     will create a subdirectory of libdir called `mw' under which it will place
     all the files needed by Milliways to run (apart from users.bb which is
<span style="color: #000000;background-color: #ffdddd">-    created when mw is first run, and who.bb which you must create yourself, as
-    below). It will also put a copy of the mw executable under bindir.
</span><span style="color: #000000;background-color: #ddffdd">+    created when mw is first run. It will also put a copy of the mw executable
+    under bindir.
</span> 
     To build, cd to the src subdirectory and type `make'.
 
</code></pre>

<br>
</li>
<li id='diff-1'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-1'>
<strong>
src/client/js.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/js.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/js.c
</span><span style="color: #aaaaaa">@@ -21,7 +21,6 @@
</span> #pragma GCC diagnostic warning "-Winvalid-offsetof"
 #pragma GCC diagnostic warning "-Wstrict-prototypes"
 
-#include <who.h>
 #include <sqlite.h>
 #include <iconv.h>
 #include "bb.h"
</code></pre>

<br>
</li>
<li id='diff-2'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-2'>
<strong>
src/client/main.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/main.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/main.c
</span><span style="color: #aaaaaa">@@ -470,8 +470,6 @@ int main(int argc, char **argv)
</span>           printf(_("  -new        Summary of new messages and quit\n"));
                printf(_("  -server <a> Connect to server <a>\n"));
                printf(_("  -since      Lists people logged on between now and when you last logged on\n"));
-               printf(_("  -who        Show a list of users logged on and quit\n"));
-               printf(_("  -what       Show a list of what users are doing\n"));
                /*
                printf("  -quiet              Don't announce your login to board or talker\n");
                printf("  -X <user>           Display messages for that user\n");
</code></pre>

<br>
</li>
<li id='diff-3'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-3'>
<strong>
src/client/script_inst.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/script_inst.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/script_inst.c
</span><span style="color: #aaaaaa">@@ -419,7 +419,7 @@ void scr_roomnum( struct code *pc, int fargc, char **fargv )
</span>                   const char *name = json_getstring(entry, "name");
                        const char *chatmode = NULL;
                        if (perms!=NULL) chatmode=json_getstring(perms, "chatmode");
-                       int room = json_getint(entry, "room");
<span style="color: #000000;background-color: #ddffdd">+                        int room = json_getint(entry, "channel");
</span> 
                        /* wrong person */
                        if (strcasecmp(name, uname)!=0) continue;
</code></pre>

<br>
</li>
<li id='diff-4'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-4'>
<strong>
src/client/who.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/who.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/who.c
</span><span style="color: #aaaaaa">@@ -134,8 +134,6 @@ void update_wholist(ipc_message_t *msg)
</span>   whoinfo = json_init(msg);
        whowhen = time(NULL);
 
-       printf("Received whodata = %s\n", msg->body);
-
        /* we were waiting for one, show it */
        if (whotype >= 0) {
                display_wholist(whotype);
<span style="color: #aaaaaa">@@ -252,3 +250,22 @@ json_t * grab_wholist(void)
</span>   if (whoinfo != NULL) json_incref(whoinfo);
        return whoinfo;
 }
<span style="color: #000000;background-color: #ddffdd">+
+int32_t who_find(const char *username)
+{
+       json_t *wlist = grab_wholist();
+       if (wlist == NULL) return -1;
+
+       size_t wi;
+       json_t *entry;
+       json_array_foreach(wlist, wi, entry) {
+               const char *name = json_getstring(entry, "name");
+               int32_t uid = json_getint(entry, "id");
+               if (strcasecmp(username, name)==0) {
+                       json_decref(wlist);
+                       return uid;
+               }
+       }
+       json_decref(wlist);
+       return -1;
+}
</span></code></pre>

<br>
</li>
<li id='diff-5'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-5'>
<strong>
src/client/who.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/who.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/who.h
</span><span style="color: #aaaaaa">@@ -12,12 +12,7 @@ void what_list(void);
</span> char *part_who_talk(const char *text, int status);
 char *part_who(const char *text, int status);
 json_t * grab_wholist(void);
<span style="color: #000000;background-color: #ddffdd">+int32_t who_find(const char *username);
</span> 
-#ifndef json_array_foreach
-#define json_array_foreach(array, index, value) \
-       for(index = 0; \
-       index < json_array_size(array) && (value = json_array_get(array, index)); \
-       index++)
-#endif
 
 #endif /* CLIENT_WHO_H */
</code></pre>

<br>
</li>
<li id='diff-6'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-6'>
<strong>
src/ipc.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/ipc.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/ipc.c
</span><span style="color: #aaaaaa">@@ -105,9 +105,16 @@ int ipc_getfd()
</span>   return ipcsock->fd;
 }
 
<span style="color: #000000;background-color: #ddffdd">+extern uint32_t who_find(const char *username);
+
</span> /*
  * Send a message to a remote process addressed by username.
  * Returns the number of processes successfuly sent messages
<span style="color: #000000;background-color: #ddffdd">+ *
+ * DEPRECATED ! - move away from this function
+ *               server should decide who messages go to not you
+ *
+ *  Any program including this must provide its own who_find()
</span>  */
 unsigned int ipc_send_to_username(const char * dest, enum ipc_types msgtype, const char * data) {
        int     ret = 0;
</code></pre>

<br>
</li>
<li id='diff-7'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-7'>
<strong>
src/ipc.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/ipc.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/ipc.h
</span><span style="color: #aaaaaa">@@ -2,7 +2,6 @@
</span> #define IPC_H
 
 #include <unistd.h>
-#include "who.h"
 #include "user.h"
 #include "socket.h"
 
<span style="color: #aaaaaa">@@ -59,8 +58,6 @@ enum ipc_types {
</span> #endif
 
 
-typedef int (send_filter)(const struct person * usr, const struct who * who, const void * info);
-
 void ipc_connect(const char *target);
 int ipc_connected(void);
 void ipc_check(void);
</code></pre>

<br>
</li>
<li id='diff-8'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-8'>
<strong>
src/server/PROTOCOL
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/server/PROTOCOL
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/server/PROTOCOL
</span><span style="color: #aaaaaa">@@ -107,6 +107,9 @@ IPC_ACTION - user requests an action
</span>           gag   - Apply gagging filter to user
                        gag - name of gag to Apply
                ungag - remove gagging filters
<span style="color: #000000;background-color: #ddffdd">+                channel - enter/leave a channel
+                       channel - channel to move to
+                       target - (opt) if this is a summons/force
</span>   Response:
                type - command request
                target - victim
</code></pre>

<br>
</li>
<li id='diff-9'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-9'>
<strong>
src/server/mwserv.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/server/mwserv.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/server/mwserv.c
</span><span style="color: #aaaaaa">@@ -9,7 +9,6 @@
</span> #include <string.h>
 #include <time.h>
 #include <socket.h>
-#include <who.h>
 #include "servsock.h"
 
 /* unused, but necessary to link other util functions */
<span style="color: #aaaaaa">@@ -117,12 +116,6 @@ int main(int argc, char **argv)
</span>           }
        }
 
-       /* at server start nobody is logged in, wipe who list */
-       int fd = who_open(O_TRUNC|O_WRONLY);
-       if (fd < 0)
-               return 1;
-       close(fd);
-
        if (!opts.foreground) daemon(0,0);
 
        uptime = time(0);
</code></pre>

<br>
</li>
<li id='diff-10'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-10'>
<strong>
src/server/replay.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/server/replay.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/server/replay.c
</span><span style="color: #aaaaaa">@@ -134,13 +134,9 @@ void replay(ipc_connection_t *conn, ipc_message_t *msg)
</span>   json_decref(cmd);
 
        /* who are we doing this for */
-       struct who who;
-       who.posn = conn->user;
-       who.pid = conn->addr;
-
        struct person user;
        int users_fd = userdb_open(O_RDONLY);
-       lseek(users_fd, who.posn, SEEK_SET);
<span style="color: #000000;background-color: #ddffdd">+        lseek(users_fd, conn->user, SEEK_SET);
</span>   if (read(users_fd, &user, sizeof(user)) <= 0) {
                close(users_fd);
                send_error(conn, msg, "Error cannot find your user record");
</code></pre>

<br>
</li>
<li id='diff-11'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-11'>
<strong>
src/server/servsock.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/server/servsock.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/server/servsock.c
</span><span style="color: #aaaaaa">@@ -112,7 +112,6 @@ void accept_connection(int mainsock)
</span> void drop_connection(ipc_connection_t * conn)
 {
        struct epoll_event ev;
-       int wfd;
 
        printf("Drop connection fd=%d\n", conn->fd);
        bzero(&ev, sizeof(ev));
<span style="color: #aaaaaa">@@ -120,9 +119,6 @@ void drop_connection(ipc_connection_t * conn)
</span>   list_del_init(&conn->list);
        if (conn->fd != -1) close(conn->fd);
        conn->fd = -1;
-       wfd = who_open(O_RDWR);
-       who_delete(wfd, conn->addr);
-       close(wfd);
        conn->state = IPCSTATE_DELETED;
        if (!list_empty(&conn->outq)) {
                struct list_head *pos, *q;
<span style="color: #aaaaaa">@@ -270,7 +266,6 @@ void process_msg(ipc_connection_t *conn, ipc_message_t *msg)
</span> 
        /* client just told us who they are */
        if (msg->head.type == IPC_HELLO) {
-               int wfd;
                if (msg->bodylen < 4) {
                        printf("Invalid HELO from fd=%d. dropping.\n", conn->fd);
                        ipcmsg_destroy(msg);
<span style="color: #aaaaaa">@@ -290,9 +285,6 @@ void process_msg(ipc_connection_t *conn, ipc_message_t *msg)
</span>                   return;
                }
                printf("WHO Add: pid=%d posn=%d\n", conn->addr, conn->user);
-               wfd = who_open(O_RDWR);
-               who_add(wfd, conn->addr, conn->user);
-               close(wfd);
                conn->state = IPCSTATE_VALID;
                ipcmsg_destroy(msg);
 
<span style="color: #aaaaaa">@@ -435,20 +427,19 @@ void process_msg(ipc_connection_t *conn, ipc_message_t *msg)
</span>  * except username==exclude (notsayto command) */
 void msg_attach_to_channel(ipc_message_t *msg, int channel, const char * exclude)
 {
-       int who_fd = who_open(O_RDONLY);
        int users_fd = userdb_open(O_RDONLY);
-       struct who who;
        struct person user;
 
        struct room room;
        RoomInit(&room);
        LoadRoom(&room, channel);
 
-       while (read(who_fd, &who, sizeof(who)) > 0) {
-               if (who.posn < 0) continue;
-               if (who.pid <= 0) continue;
<span style="color: #000000;background-color: #ddffdd">+        struct list_head *pos;
+       list_for_each(pos, &connection_list) {
+               ipc_connection_t *c = list_entry(pos, ipc_connection_t, list);
+               if (c->state != IPCSTATE_VALID) continue;
</span> 
-               lseek(users_fd, who.posn, SEEK_SET);
<span style="color: #000000;background-color: #ddffdd">+                lseek(users_fd, c->user, SEEK_SET);
</span>           if (read(users_fd, &user, sizeof(user)) <= 0) continue;
 
                /* have we been told to exclude someone in this room */
<span style="color: #aaaaaa">@@ -459,41 +450,38 @@ void msg_attach_to_channel(ipc_message_t *msg, int channel, const char * exclude
</span> 
                /* room matches, send them a copy */
                if (user.room == msg->head.dst) {
-                       msg_attach_to_pid(msg, who.pid);
<span style="color: #000000;background-color: #ddffdd">+                        msg_attach(msg, c);
</span>           } else
                /* room not soundproof, and user has global on */
                if (room.sproof < 1 && (user.chatmode & CM_GLOBAL)) {
-                       msg_attach_to_pid(msg, who.pid);
<span style="color: #000000;background-color: #ddffdd">+                        msg_attach(msg, c);
</span>           }
        }
        RoomDestroy(&room);
-       close(who_fd);
        close(users_fd);
 }
 
 /* send copy to all sessions belonging to username */
 int msg_attach_to_username(ipc_message_t *msg, const char * username)
 {
-       int who_fd = who_open(O_RDONLY);
        int users_fd = userdb_open(O_RDONLY);
-       struct who who;
        struct person user;
        int found = 0;
 
-       while (read(who_fd, &who, sizeof(who)) > 0) {
-               if (who.posn < 0) continue;
-               if (who.pid <= 0) continue;
<span style="color: #000000;background-color: #ddffdd">+        struct list_head *pos;
+       list_for_each(pos, &connection_list) {
+               ipc_connection_t *c = list_entry(pos, ipc_connection_t, list);
+               if (c->state != IPCSTATE_VALID) continue;
</span> 
-               lseek(users_fd, who.posn, SEEK_SET);
<span style="color: #000000;background-color: #ddffdd">+                lseek(users_fd, c->user, SEEK_SET);
</span>           if (read(users_fd, &user, sizeof(user)) <= 0) continue;
                /* is this the username we are looking for */
                if (strcasecmp(username, user.name)==0) {
-                       msg_attach_to_pid(msg, who.pid);
<span style="color: #000000;background-color: #ddffdd">+                        msg_attach(msg, c);
</span>                   found++;
                }
        }
 
-       close(who_fd);
        close(users_fd);
        return found;
 }
<span style="color: #aaaaaa">@@ -501,25 +489,23 @@ int msg_attach_to_username(ipc_message_t *msg, const char * username)
</span> /* send copy of message to every session */
 void msg_attach_to_all(ipc_message_t *msg)
 {
-       int who_fd = who_open(O_RDONLY);
        int users_fd = userdb_open(O_RDONLY);
-       struct who who;
        struct person user;
 
-       while (read(who_fd, &who, sizeof(who)) > 0) {
-               if (who.posn < 0) continue;
-               if (who.pid <= 0) continue;
<span style="color: #000000;background-color: #ddffdd">+        struct list_head *pos;
+       list_for_each(pos, &connection_list) {
+               ipc_connection_t *c = list_entry(pos, ipc_connection_t, list);
+               if (c->state != IPCSTATE_VALID) continue;
</span> 
-               lseek(users_fd, who.posn, SEEK_SET);
<span style="color: #000000;background-color: #ddffdd">+                lseek(users_fd, c->user, SEEK_SET);
</span>           if (read(users_fd, &user, sizeof(user)) <= 0) continue;
 
                /* person not on talker, just skip them */
                if (!cm_flags(user.chatmode, CM_ONCHAT, CM_MODE_ALL)) continue;
 
-               msg_attach_to_pid(msg, who.pid);
<span style="color: #000000;background-color: #ddffdd">+                msg_attach(msg, c);
</span>           printf("Broadcast to %s in %d\n", user.name, user.room);
        }
-       close(who_fd);
        close(users_fd);
 }
 
<span style="color: #aaaaaa">@@ -616,23 +602,22 @@ ipc_message_t * msg_wholist(void)
</span> {
        ipc_message_t * msg = ipcmsg_create(IPC_WHOLIST, SYSTEM_USER);
 
-       int who_fd = who_open(O_RDONLY);
        int users_fd = userdb_open(O_RDONLY);
-       struct who who;
        struct person user;
 
        json_t * list = json_array();
 
-       while (read(who_fd, &who, sizeof(who)) > 0) {
-               if (who.posn < 0) continue;
-               if (who.pid <= 0) continue;
<span style="color: #000000;background-color: #ddffdd">+        struct list_head *pos;
+       list_for_each(pos, &connection_list) {
+               ipc_connection_t *c = list_entry(pos, ipc_connection_t, list);
+               if (c->state != IPCSTATE_VALID) continue;
</span> 
-               lseek(users_fd, who.posn, SEEK_SET);
<span style="color: #000000;background-color: #ddffdd">+                lseek(users_fd, c->user, SEEK_SET);
</span>           if (read(users_fd, &user, sizeof(user)) <= 0) continue;
 
                json_t * j = json_init(NULL);
-               json_addint(j, "pid", who.pid);
-               json_addint(j, "id", who.posn);
<span style="color: #000000;background-color: #ddffdd">+                json_addint(j, "pid", c->addr);
+               json_addint(j, "id", c->user);
</span>           json_addstring(j, "name", user.name);
                json_addstring(j, "realname", user.realname);
                json_addstring(j, "doing", user.doing);
<span style="color: #aaaaaa">@@ -659,3 +644,29 @@ ipc_message_t * msg_wholist(void)
</span>   json_decref(list);
        return msg;
 }
<span style="color: #000000;background-color: #ddffdd">+
+/* whats the uid/userposn for this username
+ * searchs only online users
+ */
+int32_t who_find(const char * username)
+{
+       int users_fd = userdb_open(O_RDONLY);
+       struct person user;
+
+       struct list_head *pos;
+       list_for_each(pos, &connection_list) {
+               ipc_connection_t *c = list_entry(pos, ipc_connection_t, list);
+               if (c->state != IPCSTATE_VALID) continue;
+
+               lseek(users_fd, c->user, SEEK_SET);
+               if (read(users_fd, &user, sizeof(user)) <= 0) continue;
+               /* is this the username we are looking for */
+               if (strcasecmp(username, user.name)==0) {
+                       close(users_fd);
+                       return c->user;
+               }
+       }
+
+       close(users_fd);
+       return -1;
+}
</span></code></pre>

<br>
</li>
<li id='diff-12'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-12'>
<strong>
src/server/servsock.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/server/servsock.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/server/servsock.h
</span><span style="color: #aaaaaa">@@ -20,5 +20,6 @@ void init_server(void);
</span> void send_error(ipc_connection_t *conn, ipc_message_t *orig, const char *format, ...);
 void msg_apply_gag(struct person * from, ipc_message_t * msg, const char * field);
 ipc_message_t * msg_wholist(void);
<span style="color: #000000;background-color: #ddffdd">+int32_t who_find(const char * username);
</span> 
 #endif /* SERVSOCK_H */
</code></pre>

<br>
</li>
<li id='diff-13'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-13'>
<strong>
src/socket.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/socket.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/socket.h
</span><span style="color: #aaaaaa">@@ -85,5 +85,11 @@ const char *json_getstring(json_t *js, const char *key);
</span> int json_getint(json_t *js, const char *key);
 void ipcmsg_summary(const char *intro, ipc_message_t *msg);
 
<span style="color: #000000;background-color: #ddffdd">+#ifndef json_array_foreach
+#define json_array_foreach(array, index, value) \
+       for(index = 0; \
+       index < json_array_size(array) && (value = json_array_get(array, index)); \
+       index++)
+#endif
</span> 
 #endif
</code></pre>

<br>
</li>
<li id='diff-14'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-14'>
<strong>
src/webclient/comms.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/webclient/comms.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/webclient/comms.c
</span><span style="color: #aaaaaa">@@ -632,3 +632,24 @@ void mwlog(const char *fmt, ...)
</span>   va_end(ap);
 }
 
<span style="color: #000000;background-color: #ddffdd">+int32_t who_find(const char *username)
+{
+          if (whoinfo == NULL) return -1;
+         json_error_t err;
+          json_t *wlist = json_loads(whoinfo, 0, &err);
+          if (wlist == NULL) return -1;
+  
+          size_t wi;
+          json_t *entry;
+          json_array_foreach(wlist, wi, entry) {
+                  const char *name = json_getstring(entry, "name");
+                  int32_t uid = json_getint(entry, "id");
+                  if (strcasecmp(username, name)==0) {
+                          json_decref(wlist);
+                          return uid;
+                  }
+          }
+          json_decref(wlist);
+          return -1;
+}
+
</span></code></pre>

<br>
</li>
<li id='diff-15'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-15'>
<strong>
src/webclient/comms.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/webclient/comms.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/webclient/comms.h
</span><span style="color: #aaaaaa">@@ -8,4 +8,4 @@ void close_cmd(void);
</span> void talk_rawbcast(const char *fmt, ...) __attribute__((format(printf,1,2)));
 void create_user(struct person *me, int *userposn, const char *username, const char *password);
 const char * fetch_who(int immediate);
-
<span style="color: #000000;background-color: #ddffdd">+int32_t who_find(const char *username);
</span></code></pre>

<br>
</li>
<li id='diff-16'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-16'>
<strong>
src/who.c
</strong>
deleted
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/who.c
</span><span style="color: #000000;background-color: #ddffdd">+++ /dev/null
</span><span style="color: #aaaaaa">@@ -1,86 +0,0 @@
</span>-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <strings.h>
-
-#include "who.h"
-#include "files.h"
-#include "user.h"
-
-int who_open(int flags)
-{
-       int wfd = open(WHOFILE, flags|O_CREAT, 0644);
-       if (wfd < 0)
-               perror(WHOFILE);
-       return wfd;
-}
-
-void who_add(int wfd, int pid, int32_t posn)
-{
-       struct who rec;
-       Lock_File(wfd);
-       while(read(wfd,&rec,sizeof(rec))==sizeof(rec))
-       {
-               if(rec.pid<0)
-               {
-                       lseek(wfd,-sizeof(rec), SEEK_CUR);
-                       break;
-               }
-       }
-       rec.pid=pid;
-       rec.posn=posn;
-       write(wfd,&rec,sizeof(rec));
-       Unlock_File(wfd);
-}
-
-void who_delete(int wfd, int pid)
-{
-       struct who temp;
-       Lock_File(wfd);
-       while(read(wfd,&temp,sizeof(temp))==sizeof(temp))
-       {
-               if (temp.pid==pid) {
-                       lseek(wfd,(long)-sizeof(temp),1);
-                       temp.pid=-1;
-                       temp.posn=-1L;
-                       write(wfd,&temp,sizeof(temp));
-               }
-       }
-       Unlock_File(wfd);
-}
-
-/* find userid of logged in users */
-long who_find(const char * username)
-{
-       int             who_fd;
-       int             users_fd = -1;
-       struct who      who;
-       struct person   user;
-       long            where = -1;
-
-       who_fd = who_open(O_RDONLY);
-       if (who_fd < 0) return -1;
-
-       users_fd = userdb_open(O_RDONLY);
-       if (users_fd < 0) {
-               close(who_fd);
-               return -1;
-       }
-
-       while (read(who_fd, &who, sizeof(who)) > 0) {
-               if (who.posn < 0) continue;
-               if (who.pid  <= 0) continue;
-
-               lseek(users_fd, who.posn, SEEK_SET);
-               if (read(users_fd, &user, sizeof(user)) <= 0) continue;
-               if (strcasecmp(user.name, username)==0) {
-                       where = who.posn;
-                       break;
-               }
-       }
-       close(who_fd);
-       close(users_fd);
-
-       return where;
-}
-
</code></pre>

<br>
</li>
<li id='diff-17'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-17'>
<strong>
src/who.h
</strong>
deleted
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/who.h
</span><span style="color: #000000;background-color: #ddffdd">+++ /dev/null
</span><span style="color: #aaaaaa">@@ -1,20 +0,0 @@
</span>-#ifndef WHO_H
-#define WHO_H
-
-#include <stdint.h>
-
-#define WHOFILE MSGDIR"/who.bb"
-
-struct who 
-{
-       int32_t pid;
-       int32_t posn;
-};
-
-extern int who_open(int mode);
-extern void who_add(int wfd, int pid, int32_t posn);
-extern void who_delete(int wfd, int pid);
-extern long who_find(const char * username);
-
-
-#endif /* WHO_H */
</code></pre>

<br>
</li>
<li id='diff-18'>
<a href='https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470#diff-18'>
<strong>
web/bb.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/web/bb.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/web/bb.h
</span><span style="color: #aaaaaa">@@ -2,7 +2,6 @@
</span> #define USERFILE  "users.bb"
 #define LOGFILE                "log.bb"
 #define LOGIN_BANNER   "login.banner"
-#define WHOFILE                "who.bb"
 #define LOCKFILE       "/tmp/bb.locked"
 #define EDITOR         "/usr/bin/vi"
 #define HOMEPATH       "/usr/local/lib/mw"
</code></pre>

<br>
</li>

</div>
<div class='footer' style='margin-top: 10px;'>
<p>

<br>
<a href="https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470">View it on GitLab</a>
<script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","action":{"@type":"ViewAction","name":"View Commit","url":"https://projects.sucs.org/arthur/mw/commit/d725e0a5003b9f59ab3481a1bdde17cfcd787470"}}</script>
</p>
</div>
</body>
</html>