<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/c4d8ec597f6369636ce5a960f4cec91c8a929fe5">c4d8ec59</a></strong>
<div>
<span>by Justin Mitchell</span>
<i>at 2015-10-07T15:10:59Z</i>
</div>
<pre class='commit-message'>Try to rid the world of references to who_open(), almost done</pre>
</li>
</ul>
<h4>36 changed files:</h4>
<ul>
<li class='file-stats'>
<a href='#diff-0'>
.gitignore
</a>
</li>
<li class='file-stats'>
<a href='#diff-1'>
<span class='new-file'>
+
src/.gitignore
</span>
</a>
</li>
<li class='file-stats'>
<a href='#diff-2'>
src/bb.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-3'>
src/client/chattable.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-4'>
src/client/completion.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-5'>
src/client/edit.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-6'>
src/client/folders.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-7'>
src/client/incoming.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-8'>
src/client/incoming.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-9'>
src/client/main.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-10'>
src/client/main.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-11'>
src/client/mesg.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-12'>
src/client/mesg.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-13'>
src/client/new.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-14'>
src/client/new.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-15'>
src/client/newmain.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-16'>
src/client/script.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-17'>
src/client/script_inst.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-18'>
src/client/script_inst.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-19'>
src/client/talker.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-20'>
src/client/talker.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-21'>
src/client/user.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-22'>
src/client/who.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-23'>
src/client/who.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-24'>
src/ipc.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-25'>
src/ipc.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-26'>
src/perms.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-27'>
src/perms.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-28'>
src/server/PROTOCOL
</a>
</li>
<li class='file-stats'>
<a href='#diff-29'>
src/server/servsock.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-30'>
src/server/servsock.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-31'>
src/socket.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-32'>
src/socket.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-33'>
src/webclient/Makefile
</a>
</li>
<li class='file-stats'>
<a href='#diff-34'>
src/webclient/comms.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-35'>
src/who.c
</a>
</li>
</ul>
<h4>Changes:</h4>
<li id='diff-0'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-0'>
<strong>
.gitignore
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/.gitignore
</span><span style="color: #000000;background-color: #ddffdd">+++ b/.gitignore
</span><span style="color: #aaaaaa">@@ -5,6 +5,7 @@
</span> *.so
 *.pyc
 *.swp
<span style="color: #000000;background-color: #ddffdd">+*.deb
</span> .deps
 cscope.out
 src/client/mw
</code></pre>

<br>
</li>
<li id='diff-1'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-1'>
<strong>
src/.gitignore
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- /dev/null
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/.gitignore
</span><span style="color: #aaaaaa">@@ -0,0 +1 @@
</span><span style="color: #000000;background-color: #ddffdd">+tags
</span></code></pre>

<br>
</li>
<li id='diff-2'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-2'>
<strong>
src/bb.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/bb.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/bb.h
</span><span style="color: #aaaaaa">@@ -53,13 +53,6 @@
</span> #define RIGHTS_BBS        0
 #define RIGHTS_TALK    1
 
-
-struct IgnoreList
-{
-       char                    *name;
-       struct IgnoreList       *next;
-};
<span style="color: #000000;background-color: #ffdddd">-                
</span> #define PACKAGE   "mw"
 #define LOCALEDIR HOMEPATH"/locale"
 
</code></pre>

<br>
</li>
<li id='diff-3'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-3'>
<strong>
src/client/chattable.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/chattable.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/chattable.c
</span><span style="color: #aaaaaa">@@ -44,8 +44,6 @@ CommandList chattable[]={
</span> {"gag"          ,0x0002 ,1, "Usage: gag <user> [filter]", "Gag the user (with optional filter)", t_gag, 1},
 {"global"    ,0x0010 ,1, "Usage: global <on|off>", "Global receive mode, hear all rooms", t_global, 1},
 {"help"              ,0x0000 ,0, "Usage: help [command]", "List available commands, or help on [command]", t_help, 1},
-{"ignore"    ,0x0000 ,1, "Usage: ignore <user>", "Filter user out so you can't hear them", t_ignore, 1},
-{"ignorelist"        ,0x0000 ,0, "Usage: ignorelist", "Show who you are currently ignoring", t_ignorelist, 1}, 
 {"linewrap"  ,0x0000 ,1, "Usage: linewrap <on|off>", "Line wrapping when terminal width is reached", t_linewrap, 1},
 {"load"              ,0x0200 ,1, "Usage: load <file>", "Load script from file", t_load, 1},
 {"kick"              ,0x0804 ,1, "Usage: kick <user> [reason]", "Eject user from talker, ignoring protection", t_kick, 1},
<span style="color: #aaaaaa">@@ -77,7 +75,6 @@ CommandList chattable[]={
</span> {"unevent"      ,0x0200 ,1, "Usage: unevent <function | *>", "Unset [all] text event handler function(s)", t_unevent, 1},
 {"unfreeze"  ,0x0040 ,1, "Usage: unfreeze <user>", "Allow user to change rooms again", t_unfreeze, 1},
 {"ungag"     ,0x0002 ,1, "Usage: ungag <user>", "Remove the Gag on the user", t_ungag, 1},
-{"unignore"  ,0x0000 ,1, "Usage: unignore <user>", "Stop filtering user out so you can hear them", t_unignore, 1},
 {"unprotect" ,0x0020 ,1, "Usage: unprotect <user>", "Remove protection from user", t_unprotect, 1},
 {"uptime"    ,0x0000 ,0, "Usage: uptime", "Show server uptime", t_uptime, 1},
 {"uri"               ,0x0000 ,0, "Usage: uri [list [*|username] [n] | delete <id> | nsfw <id> | membersonly <id> | anonymous <id> | displaymode <full|short>]", "View/Edit the uris in the mwuri database", t_uri, 1},
</code></pre>

<br>
</li>
<li id='diff-4'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-4'>
<strong>
src/client/completion.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/completion.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/completion.c
</span><span style="color: #aaaaaa">@@ -3,6 +3,7 @@
</span> #include "main.h"
 #include "talker_privs.h"
 #include "alias.h"
<span style="color: #000000;background-color: #ddffdd">+#include "who.h"
</span> 
 /*
   modes:       0 - commands
<span style="color: #aaaaaa">@@ -49,7 +50,6 @@ CompletionList tctable[]={
</span> {"freeze"       ,1      ,1      ,1      ,part_who_talk},
 {"gag"               ,1      ,2      ,2      ,part_gag_filter},
 {"gag"               ,1      ,1      ,2      ,part_who_talk},
-{"ignore"    ,1      ,1      ,-1     ,part_who},
 {"kick"              ,1      ,1      ,1      ,part_who_talk},
 {"load"              ,1      ,1      ,1      ,list_mwsfile},
 {"mrod"              ,1      ,1      ,1      ,part_who},
<span style="color: #aaaaaa">@@ -64,7 +64,6 @@ CompletionList tctable[]={
</span> {"unbind"       ,1      ,1      ,1      ,list_bind},
 {"unfreeze"  ,1      ,1      ,1      ,part_who_talk},
 {"ungag"     ,1      ,1      ,1      ,part_who_talk},
-{"unignore"  ,1      ,1      ,-1     ,part_who},
 {"unprotect" ,1      ,1      ,1      ,part_who_talk},
 {"uri"               ,1      ,2      ,2      ,uri_arg_tc},
 {"uri"               ,1      ,1      ,1      ,uri_action_tc},
</code></pre>

<br>
</li>
<li id='diff-5'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-5'>
<strong>
src/client/edit.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/edit.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/edit.c
</span><span style="color: #aaaaaa">@@ -36,7 +36,7 @@
</span> const char *partlist_user[]={
 "edit", "status", "special", "groups", "passwd", "chatprivs", "chatmode",
 "realname", "username", "contact", "timeout", "lastread", "view", "room",
-"clearignore", "protection", "doing", NULL};
<span style="color: #000000;background-color: #ddffdd">+"protection", "doing", NULL};
</span> 
 extern int busy;
 extern int mesg_waiting;
<span style="color: #aaaaaa">@@ -571,22 +571,6 @@ void edit_user(const char *args, const char *name)
</span>           time_on(usr.timeused);
                if (usr.dowhen != 0 && usr.doing[0] != 0)
                printf(_("Status: %s (%s ago)\n"), usr.doing, itime(time(0)-usr.dowhen));
-       } else
-       if (stringcmp(args,"clearignore",2))
-       {
-               char answer[10];
-
-               printf(_("Are you sure you want to clear %s's ignore list? "),usr.name);
-               fflush(stdout);
-               get_str(answer,5);
-               if (answer[0]=='y' || answer[0]=='Y')
-               {       
-                       ipc_send_to_username(usr.name, IPC_CLEARIGN, "");
-                       printf(_("Ignorelist Cleared.\n"));
-                       broadcast(3, "%s has just cleared %s's ignore list", user->name, usr.name);
-                       mwlog("CHANGE(IGNORELIST) of %s to cleared", usr.name);
-               }else
-                       printf(_("Clear Cancelled.\n"));
        }else
        {
                printf(_("Unknown Command\n"));
</code></pre>

<br>
</li>
<li id='diff-6'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-6'>
<strong>
src/client/folders.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/folders.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/folders.c
</span><span style="color: #aaaaaa">@@ -15,6 +15,7 @@
</span> #include "user.h"
 #include "userio.h"
 #include "folders.h"
<span style="color: #000000;background-color: #ddffdd">+#include "mesg.h"
</span> 
 void add_folder(void)
 {
</code></pre>

<br>
</li>
<li id='diff-7'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-7'>
<strong>
src/client/incoming.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/incoming.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/incoming.c
</span><span style="color: #aaaaaa">@@ -27,6 +27,9 @@
</span> #include "who.h"
 #include "user.h"
 #include "util.h"
<span style="color: #000000;background-color: #ddffdd">+#include "incoming.h"
+#include <jansson.h>
+#include <str_util.h>
</span> 
 extern Alias rpc_list;
 extern Alias event_list;
<span style="color: #aaaaaa">@@ -40,7 +43,6 @@ extern ipc_connection_t *ipcsock;
</span> 
 int new_mail_waiting=0;
 int mesg_waiting = 0;
-struct IgnoreList *ignored;
 char *mrod_user=NULL;
 
 static int MesgStacked=0;
<span style="color: #aaaaaa">@@ -61,7 +63,6 @@ static void force_gag(char *text, unsigned long theirprivs, const char *from);
</span> static void zod(char *from, char *msg);
 static void mrod(char *from, char *msg);
 static void force_newmail(void);
-static void force_clearign(void);
 static void force_protlevel(char *text, unsigned long theirprivs, const char *from);
 static void force_protpower(char *text);
 
<span style="color: #aaaaaa">@@ -718,13 +719,13 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct person *mesg_user)
</span>                   reset_timeout(user->timeout);
                        break;
                case IPC_TEXT:
-                       if (!is_ignored(mesg_user->name, NULL)) force_text(msg, newbuff, mesg_user->name);
<span style="color: #000000;background-color: #ddffdd">+                        force_text(msg, newbuff, mesg_user->name);
</span>                   break;
                case IPC_SCRIPTIPC:
-                       if (!is_ignored(mesg_user->name, NULL)) force_ipc(newbuff, mesg_user->name);
<span style="color: #000000;background-color: #ddffdd">+                        force_ipc(newbuff, mesg_user->name);
</span>                   break;
                case IPC_SCRIPTRPC:
-                       if (!is_ignored(mesg_user->name, NULL)) force_rpc(newbuff, mesg_user->name);
<span style="color: #000000;background-color: #ddffdd">+                        force_rpc(newbuff, mesg_user->name);
</span>                   break;
                case IPC_CHECKONOFF:
                        force_checkonoff(newbuff, mesg_user->name);
<span style="color: #aaaaaa">@@ -738,9 +739,6 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct person *mesg_user)
</span>           case IPC_KICK:
                        force_kick(newbuff, mesg_user->name, mesg_user->chatprivs);
                        break;
-               case IPC_CLEARIGN:
-                       force_clearign();
-                       break;
                case IPC_UPTIME:
                        display_uptime(msg);
                        break;
<span style="color: #aaaaaa">@@ -753,6 +751,9 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct person *mesg_user)
</span>           case IPC_TALKERROR:
                        display_error(msg);
                        break;
<span style="color: #000000;background-color: #ddffdd">+                case IPC_WHOLIST:
+                       update_wholist(msg);
+                       break;
</span>           default:
                        devel_msg("incoming_mesg", "unknown message type %d.\007", state);
        }
<span style="color: #aaaaaa">@@ -854,21 +855,6 @@ static void force_rpc(char *text, char *from)
</span>   }
 }
 
-static void force_clearign(void)
-{
-       struct IgnoreList *temp;
-
-       /* unignore everyone in list */
-       while (ignored != NULL)
-       {
-               temp = ignored;
-               ignored = ignored->next;
-               free(temp->name);
-               free(temp);
-       }
-       display_message(_("*** Your ignore list has just been cleared ***"), 1, 1);
-}
-
 static void force_status(char *newbuff, char *from)
 {
        user->status = user_stats(newbuff, user->status);
<span style="color: #aaaaaa">@@ -1115,4 +1101,3 @@ static void mrod(char *from, char *msg)
</span>   strcpy(mrod_user, from);
        close_down(3, from, msg);
 }
-
</code></pre>

<br>
</li>
<li id='diff-8'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-8'>
<strong>
src/client/incoming.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/incoming.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/incoming.h
</span><span style="color: #aaaaaa">@@ -1,5 +1,6 @@
</span> #ifndef INCOMING_H
 #define INCOMING_H
<span style="color: #000000;background-color: #ddffdd">+#include <ipc.h>
</span> 
 /* Incoming message flags */
 #define MST_EVENT      0x01    /* Event script will be called */
<span style="color: #aaaaaa">@@ -26,9 +27,6 @@ struct mstack
</span> extern int new_mail_waiting;
 extern char *mrod_user;
 
-/* user ignore list */
-extern struct IgnoreList *ignored;
-
 void incoming_mesg(int ignore);
 void handle_mesg(void);
 void InsertMesg(struct mstack *mesg);
</code></pre>

<br>
</li>
<li id='diff-9'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-9'>
<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">@@ -243,9 +243,6 @@ static void accept_line(char *line)
</span>                   user->idletime=time(0);
                        update_user(user,userposn);
                        if (*comm == 0) return;
-       #ifdef RWHO
-                       rwho_update();
-       #endif 
                        disable_rl(0);
                        update_user(user,userposn);
                        stack_str(comm);
<span style="color: #aaaaaa">@@ -353,8 +350,6 @@ int main(int argc, char **argv)
</span>   int qflag = 0;
        int tty_timeout = 500; /* milliseconds */
        int view_new = 0;
-       int view_who = 0;
-       int view_what = 0;
        int view_help = 0;
        int inet_mode = 0;
        int view_since = 0;
<span style="color: #aaaaaa">@@ -381,8 +376,6 @@ int main(int argc, char **argv)
</span>   user=(struct person *)malloc(sizeof(*user));
        fold=(struct folder *)malloc(sizeof(*fold));
 
-       /* init ignore list */
-       ignored = NULL;
        output=stdout;
 
 #ifdef GNUTLS_VERSION_MAJOR
<span style="color: #aaaaaa">@@ -406,8 +399,6 @@ int main(int argc, char **argv)
</span>           if (match_arg_str(argv[al], "autowho")) autowho = 1;
                if (match_arg_str(argv[al], "quiet")) qflag = 1;
                if (match_arg_str(argv[al], "new")) view_new = 1;
-               if (match_arg_str(argv[al], "who")) view_who = 1;
-               if (match_arg_str(argv[al], "what")) view_what = 1;
                if (match_arg_str(argv[al], "i")) inet_mode = 1;
                if (match_arg_str(argv[al], "since")) view_since = 1;
 
<span style="color: #aaaaaa">@@ -506,30 +497,6 @@ int main(int argc, char **argv)
</span>           }else
                        printf(_("Username not permitted.\n"));
        }
-       if (view_who)
-       {
-               char *b;
-               b=(char *)getmylogin();
-               if (b!=NULL)
-               {
-                       /* try and load user - dont care if it fails */
-                       is_old(user,b,&userposn);
-                       who_list(0);
-               }else
-                       printf(_("Username not permitted.\n"));
-       }
-       if (view_what)
-       {
-               char *b;
-               b=(char *)getmylogin();
-               if (b!=NULL)
-               {
-                       /* try and load user - dont care if it fails */
-                       is_old(user,b,&userposn);
-                       what_list();
-               }else
-                       printf(_("Username not permitted.\n"));
-       }
        if (view_since)
        {
                char *b;
<span style="color: #aaaaaa">@@ -547,7 +514,7 @@ int main(int argc, char **argv)
</span>   }
 
        /* if any 'view and quit' options specified, then quit */
-       if (view_new || view_who || view_since || view_what)
<span style="color: #000000;background-color: #ddffdd">+        if (view_new || view_since)
</span>   {
                free(user);
                free(fold);
<span style="color: #aaaaaa">@@ -602,7 +569,7 @@ int main(int argc, char **argv)
</span>                   exit(-1);
                }
                remote=true;
-               new(user);  
<span style="color: #000000;background-color: #ddffdd">+                show_new(user);  
</span>           update_user(user,tmp);
                free(user);
                free(fold);
<span style="color: #aaaaaa">@@ -682,10 +649,6 @@ int main(int argc, char **argv)
</span>           quietmode=0;
        }
 
-#ifdef RWHO
-       rwho_update();
-#endif
-
        {
                struct sockaddr sa;
                socklen_t ss;
<span style="color: #aaaaaa">@@ -890,8 +853,6 @@ void close_down(int exitmode, char *sourceuser, char *reason)
</span> {
        extern char *event_user;
        extern char *event_body_text;
-       extern struct IgnoreList *ignored;
-       struct IgnoreList *temp;
 
        disable_rl(0);
 
<span style="color: #aaaaaa">@@ -932,15 +893,6 @@ void close_down(int exitmode, char *sourceuser, char *reason)
</span>   user->lastlogout = time(0);
        update_user(user, userposn);
 
-       /* free ignorelist */
-       while (ignored != NULL)
-       {
-               temp = ignored;
-               ignored = ignored->next;
-               free(temp->name);
-               free(temp);
-       }
-
        destroy_colours();
        if (event_user != NULL) free(event_user);
        if (event_body_text != NULL) free(event_body_text);
<span style="color: #aaaaaa">@@ -971,9 +923,6 @@ void close_down(int exitmode, char *sourceuser, char *reason)
</span> 
        mwlog("LOGOUT");
        sleep(1); //dodgy hack for race condition in checkonoff, cunningly we currently get woken by the very message we're waiting for.
-#ifdef RWHO
-       rwhocli_userlogout(user->name);
-#endif
 
        free(user);
        free(fold);
<span style="color: #aaaaaa">@@ -1804,84 +1753,6 @@ char *find_folder(const char *text, int state)
</span> }
 
 
-char *part_who(const char *text, int status)
-{
-       struct person uu;
-       struct who w;
-
-       static int ufile=0;
-       static int wfile=0;
-       static int len=0;
-
-       if (status==0)
-       {
-               if (wfile!=0) close(wfile);
-               if (ufile!=0) close(ufile);
-               wfile=who_open(O_RDONLY);
-               ufile=userdb_open(O_RDONLY);
-               if (wfile<0 || ufile<0) return(NULL); /* whoops */
-
-               len=strlen(text);
-       }
-
-       while (read(wfile,&w,sizeof(w)))
-       {
-               /* Skip invalid entries */
-               if (w.posn < 0)
-                       continue;
-
-               lseek(ufile,w.posn,0);
-               read(ufile,&uu,sizeof(uu));
-
-               if (len==0 || !strncasecmp(uu.name,text,len))
-                       return(dupstr(uu.name, ""));
-       }
-
-       close(wfile);
-       close(ufile);
-       return(NULL);
-}
-
-char *part_who_talk(const char *text, int status)
-{
-       struct person uu;
-       struct who w;
-
-       static int ufile=0;
-       static int wfile=0;
-       static int len=0;
-
-       if (status==0)
-       {
-               if (wfile!=0) close(wfile);
-               if (ufile!=0) close(ufile);
-               wfile=who_open(O_RDONLY);
-               ufile=userdb_open(O_RDONLY);
-               if (wfile<0 || ufile<0) return(NULL); /* whoops */
-
-               len=strlen(text);
-       }
-
-       while (read(wfile,&w,sizeof(w)))
-       {
-               /* Skip invalid entries */
-               if (w.posn < 0)
-                       continue;
-
-               lseek(ufile,w.posn,0);
-               read(ufile,&uu,sizeof(uu));
-
-               if (cm_flags(uu.chatmode, CM_ONCHAT, CM_MODE_ALL) &&
-                  (len==0 || !strncasecmp(uu.name,text,len)))
-                       return(dupstr(uu.name, ""));
-       }
-
-       close(wfile);
-       close(ufile);
-       return(NULL);
-}
-
-
 char *part_user(const char *text, int status) 
 {
        static int file=0;
</code></pre>

<br>
</li>
<li id='diff-10'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-10'>
<strong>
src/client/main.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/main.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/main.h
</span><span style="color: #aaaaaa">@@ -11,8 +11,6 @@ int idle(int fd, int millis);
</span> void set_rights(void);
 char *dupstr(const char *text, const char *prepend);
 
-char *part_who_talk(const char *text, int status);
-char *part_who(const char *text, int status);
 char *part_user(const char *text, int status);
 char *part_comm_search(const char *text, int status);
 char *part_comm_folder(const char *text, int status);
</code></pre>

<br>
</li>
<li id='diff-11'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-11'>
<strong>
src/client/mesg.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/mesg.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/mesg.c
</span><span style="color: #aaaaaa">@@ -1,6 +1,8 @@
</span> #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
<span style="color: #000000;background-color: #ddffdd">+#include <time.h>
+#include <unistd.h>
</span> #include <string.h>
 #include <stdarg.h>
 #include "talker_privs.h"
<span style="color: #aaaaaa">@@ -131,4 +133,36 @@ void broadcast(int state, const char *fmt, ...)
</span>   }
 }
 
<span style="color: #000000;background-color: #ddffdd">+extern struct person *user;
+
+void mwlog(const char *fmt, ...)
+{
+       va_list ap;
+       int file;
+       char outmsg[LOGLINESIZE];
+       char addstr[LOGLINESIZE];
+       char new[LOGLINESIZE];
+       time_t t;
+
+       va_start(ap, fmt);
+       
+       if ((file=open(LOGFILE,O_WRONLY|O_CREAT|O_APPEND,0600))<0)
+       {
+               perror("log");
+               return;
+       }
+       t=time(0);
+
+       vsnprintf(addstr, LOGLINESIZE-1, fmt, ap);
+       snprintf(outmsg, LOGLINESIZE-1, "%s", asctime(gmtime(&t)));
+       outmsg[strlen(outmsg)-1] = ' ';
+
+       snprintf(new, LOGLINESIZE-2, "%s| %*s | %s", outmsg, NAMESIZE, user->name, addstr);
+       strcat(new, "\n");
+
+       write(file,new,strlen(new));
+       close(file);
+
+       va_end(ap);
+}
</span> 
</code></pre>

<br>
</li>
<li id='diff-12'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-12'>
<strong>
src/client/mesg.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/mesg.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/mesg.h
</span><span style="color: #aaaaaa">@@ -7,5 +7,6 @@ void broadcast(int state, const char *fmt, ...) __attribute__((format(printf,2,3
</span> void inform_of_mail(char *to);
 void postinfo(struct person *who, struct folder *fol, struct Header *mesg);
 void send_mesg(char *from, const char *to, char *text, int wiz);
<span style="color: #000000;background-color: #ddffdd">+void mwlog(const char *fmt, ...) __attribute__((format(printf,1,2)));
</span> 
 #endif /* MESG_H */
</code></pre>

<br>
</li>
<li id='diff-13'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-13'>
<strong>
src/client/new.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/new.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/new.c
</span><span style="color: #aaaaaa">@@ -176,7 +176,7 @@ static int read_new(struct person *user, struct folder *data, int folnum)
</span>   return(0);
 }
 
-void new(struct person *user)
<span style="color: #000000;background-color: #ddffdd">+void show_new(struct person *user)
</span> {         
        struct folder *data;    
        int folderfile;
</code></pre>

<br>
</li>
<li id='diff-14'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-14'>
<strong>
src/client/new.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/new.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/new.h
</span><span style="color: #aaaaaa">@@ -4,7 +4,7 @@
</span> #include "user.h"
 
 void list_new_items(struct person *user, int flag);
-void new(struct person *user);
<span style="color: #000000;background-color: #ddffdd">+void show_new(struct person *user);
</span> void latest(struct person *user);
 
 #endif /* NEW_H */
</code></pre>

<br>
</li>
<li id='diff-15'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-15'>
<strong>
src/client/newmain.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/newmain.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/newmain.c
</span><span style="color: #aaaaaa">@@ -36,6 +36,7 @@
</span> #include "alias.h"
 #include "userio.h"
 #include "mesg.h"
<span style="color: #000000;background-color: #ddffdd">+#include "incoming.h"
</span> 
 extern Alias alias_list;
 
<span style="color: #aaaaaa">@@ -173,7 +174,7 @@ void c_listall(CommandList *cm, int argc, const char **argv, char *args)
</span> void c_new(CommandList *cm, int argc, const char **argv, char *args)
 {
        busy++;
-       new(user);
<span style="color: #000000;background-color: #ddffdd">+        show_new(user);
</span>   busy--;
        get_folder_number(fold,currentfolder);
        update_user(user,userposn);
<span style="color: #aaaaaa">@@ -485,7 +486,7 @@ void c_latest(CommandList *cm, int argc, const char **argv, char *args)
</span> void c_who(CommandList *cm, int argc, const char **argv, char *args)
 {
        update_user(user,userposn);
-       who_list(0);
<span style="color: #000000;background-color: #ddffdd">+        display_wholist(0);
</span> }
 
 void c_tell(CommandList *cm, int argc, const char **argv, char *args)
</code></pre>

<br>
</li>
<li id='diff-16'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-16'>
<strong>
src/client/script.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/script.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/script.c
</span><span style="color: #aaaaaa">@@ -22,6 +22,7 @@
</span> #include "js.h"
 #include "user.h"
 #include "userio.h"
<span style="color: #000000;background-color: #ddffdd">+#include "who.h"
</span> 
 extern Alias bind_list;
 
</code></pre>

<br>
</li>
<li id='diff-17'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-17'>
<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">@@ -24,6 +24,7 @@
</span> #include "perms.h"
 #include "main.h"
 #include "user.h"
<span style="color: #000000;background-color: #ddffdd">+#include "mesg.h"
</span> 
 extern struct person *user;
 extern long userposn;
<span style="color: #aaaaaa">@@ -83,9 +84,7 @@ Instruction inst_table[]={
</span> { "or",         0x0000, 2, "Bitwise OR", scr_math },
 { "output",  0x0000, 1, "Set event output ON or OFF", scr_output },
 { "print",   0x0000, 1, "Print text to screen with newline appended", scr_print },
-{ "q-ignore",        0x2000, 1, "Quietly ignore a user", scr_qignore },
 { "q-room",  0x2000, 1, "Quietly change to this room number", scr_room },
-{ "q-unignore",      0x2000, 1, "Quietly unignore a user", scr_qignore },
 { "quit",    0x0000, 0, "Quits the board", scr_quit },
 { "rand",    0x0000, 3, "Random number generator", scr_rand },
 { "range",   0x0000, 3, "Check if arg1 is in the range [arg2..arg3]", scr_range },
<span style="color: #aaaaaa">@@ -610,120 +609,6 @@ void scr_print( struct code *pc, int fargc, char **fargv )
</span>   free(text);
 }
 
-void scr_qignore( struct code *pc, int fargc, char **fargv ) 
-{
-       char                    *what;
-       struct IgnoreList       *newnode;
-
-       if (pc->argc<1) {
-               if (script_debug) printf("Error in function '%s' at %s too few arguments.\n", pc->inst->name, pc->debug);
-               return;
-       }
-       what=eval_arg(pc->argv[0], fargc, fargv);
-       compare_count++;
-
-       if (!strcasecmp(pc->inst->name, "q-ignore"))
-       {
-               /* ignore all users */
-               if (!strcmp(what, "*"))
-               {
-                       int ufile,wfile;
-                       struct person p;
-                       struct who w;   
-
-                       wfile=who_open(O_RDWR);
-                       ufile=userdb_open(O_RDONLY);
-                       if (wfile<0 || ufile<0) return; /* whoops */
-
-                       while (read(wfile,&w,sizeof(w)))
-                       {
-                               /* Skip invalid entries */
-                               if (w.posn < 0)
-                                       continue;
-
-                               lseek(ufile,w.posn,0);
-                               read(ufile,&p,sizeof(p));
-
-                               /* check they are still alive and show info */
-                               if (w.pid>-1 )
-                               {
-                                       if (cm_flags(p.chatmode,CM_ONCHAT,CM_MODE_ANY))
-                                       {
-                                               if (!is_ignored(p.name, NULL))
-                                               {   
-                                                       newnode = malloc(sizeof(struct IgnoreList));
-                                                       newnode->name = malloc(sizeof(char) * (strlen(p.name) + 1));
-                                                       strcpy(newnode->name, p.name);
-                                                       newnode->next = ignored;
-                                                       ignored = newnode;
-                                               }
-                                       }
-                               }
-                       }
-                       close(ufile);
-                       close(wfile);
-
-                       compare_match++;
-                       mwlog("Q-IGNORE(*)");
-               }
-               /* ignore one user */
-               else
-               {
-                       int32_t         tempposn; 
-                       struct person   tempusr;
-
-                       /* User exists, is logged on and isn't already ignored */
-                       if (is_old(&tempusr,what, &tempposn) && ison(what) && !is_ignored(what, NULL))
-                       {   
-                               newnode = malloc(sizeof(struct IgnoreList));
-                               newnode->name = strdup(what);
-                               newnode->next = ignored;
-                               ignored = newnode;
-                               compare_match++;
-                               mwlog("Q-IGNORE(%s)", tempusr.name);
-                       }
-               }
-       }
-       else if (!strcasecmp(pc->inst->name, "q-unignore"))
-       {
-               /* ignore all users */
-               if (!strcmp(what, "*"))
-               {
-                       struct IgnoreList *temp;
-
-                       /* unignore everyone in list */
-                       while (ignored != NULL)
-                       {
-                               temp = ignored;
-                               ignored = ignored->next;
-                               free(temp->name);
-                               free(temp);
-                       }
-                       compare_match++;
-                       mwlog("Q-UNIGNORE(*)");
-               }
-               /* ignore one user */
-               else
-               {
-                       struct IgnoreList *found, *prev = NULL;
-                       found = is_ignored(what, &prev);
-                       if (found)
-                       {
-                               /* if at front */
-                               if (prev == NULL) ignored = ignored->next;
-                               /* in middle/end */
-                               else prev->next = found->next;
-                               free(found->name);
-                               free(found);
-
-                               compare_match++;
-                               mwlog("Q-UNIGNORE(%s)", what);
-                       }
-               }
-       }
-       free(what);
-}
-
 int isanum(const char *a, int *result, int onlydecimal)
 {
        char *end;
<span style="color: #aaaaaa">@@ -2364,12 +2249,12 @@ void scr_sendipc( struct code *pc, int fargc, char **fargv )
</span> {
        int i, size, count;
        char *tmp, *p, *text;
-       int broadcast = 0;
<span style="color: #000000;background-color: #ddffdd">+        int bcast = 0;
</span>   int startarg;
 
-       if (!strcasecmp(pc->inst->name, "sendipb")) broadcast = 1;
<span style="color: #000000;background-color: #ddffdd">+        if (!strcasecmp(pc->inst->name, "sendipb")) bcast = 1;
</span> 
-       if (broadcast) {
<span style="color: #000000;background-color: #ddffdd">+        if (bcast) {
</span>           if (pc->argc < 1) return;
                startarg = 0;
        } else {
<span style="color: #aaaaaa">@@ -2398,7 +2283,7 @@ void scr_sendipc( struct code *pc, int fargc, char **fargv )
</span> 
        text = eval_arg(pc->argv[0], fargc, fargv);
 
-       sendipc(text,tmp,broadcast);
<span style="color: #000000;background-color: #ddffdd">+        sendipc(text,tmp,bcast);
</span> 
        free(text);
        free(tmp);
<span style="color: #aaaaaa">@@ -2408,12 +2293,12 @@ void scr_sendrpc( struct code *pc, int fargc, char **fargv )
</span> {
        int i, size, count;
        char *text, *p, *sendto, *msg;
-       int broadcast = 0;
<span style="color: #000000;background-color: #ddffdd">+        int bcast = 0;
</span>   int startarg;
 
-       if (!strcasecmp(pc->inst->name, "sendrpb")) broadcast = 1;
<span style="color: #000000;background-color: #ddffdd">+        if (!strcasecmp(pc->inst->name, "sendrpb")) bcast = 1;
</span> 
-       if (broadcast) {
<span style="color: #000000;background-color: #ddffdd">+        if (bcast) {
</span>           if (pc->argc < 2) return;
                startarg = 1;
        } else {
<span style="color: #aaaaaa">@@ -2440,7 +2325,7 @@ void scr_sendrpc( struct code *pc, int fargc, char **fargv )
</span>           free(p);
        }
 
-       if (broadcast)
<span style="color: #000000;background-color: #ddffdd">+        if (bcast)
</span>   {
                sendto = strdup("");
                msg = eval_arg(pc->argv[0], fargc, fargv);
<span style="color: #aaaaaa">@@ -2451,7 +2336,7 @@ void scr_sendrpc( struct code *pc, int fargc, char **fargv )
</span>           msg = eval_arg(pc->argv[1], fargc, fargv);
        }
 
-       sendrpc(sendto,msg,text,broadcast);
<span style="color: #000000;background-color: #ddffdd">+        sendrpc(sendto,msg,text,bcast);
</span> 
        free(text);
        free(msg);
</code></pre>

<br>
</li>
<li id='diff-18'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-18'>
<strong>
src/client/script_inst.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/script_inst.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/script_inst.h
</span><span style="color: #aaaaaa">@@ -27,7 +27,6 @@ void scr_math( struct code *, int, char **);
</span> void scr_math2( struct code *, int, char **);
 void scr_output( struct code *, int, char **);
 void scr_print( struct code *, int, char **);
-void scr_qignore( struct code *, int, char **);
 void scr_quit( struct code *, int, char **);
 void scr_rand( struct code *, int, char **);
 void scr_range( struct code *, int, char **);
</code></pre>

<br>
</li>
<li id='diff-19'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-19'>
<strong>
src/client/talker.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/talker.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/talker.c
</span><span style="color: #aaaaaa">@@ -31,6 +31,8 @@
</span> #include "userio.h"
 #include "user.h"
 #include "who.h"
<span style="color: #000000;background-color: #ddffdd">+#include "mesg.h"
+#include "incoming.h"
</span> 
 #include "alias.h"
 extern Alias bind_list;
<span style="color: #aaaaaa">@@ -54,9 +56,6 @@ static int runautoexec = 1;
</span> 
 extern struct room myroom;
 
-/* ignore list for current user */
-extern struct IgnoreList *ignored;
-
 extern CommandList table[];
 extern CommandList chattable[];
 
<span style="color: #aaaaaa">@@ -187,12 +186,13 @@ int screen_w(void)
</span> 
 void t_who(CommandList *cm, int argc, const char **argv, char *args)
 {
-       who_list(0);
<span style="color: #000000;background-color: #ddffdd">+        display_wholist(0);
</span> }
 
 void t_what(CommandList *cm, int argc, const const char **argv, char *args)
 {
-       who_list(1);
<span style="color: #000000;background-color: #ddffdd">+        //who_list(1);
+       display_wholist(1);
</span> }
 
 void t_uptime(CommandList *cm, int argc, const const char **argv, char *args)
<span style="color: #aaaaaa">@@ -905,212 +905,6 @@ void t_ungag(CommandList *cm, int argc, const char **argv, char *args)
</span>   ipcmsg_transmit(msg);
 }
 
-void t_ignorelist(CommandList *cm, int argc, const char **argv, char *args)
-{
-       int linecount = 1;
-       int screen_height = screen_h();
-       struct IgnoreList *tail;
<span style="color: #000000;background-color: #ffdddd">- 
</span>-  tail = ignored;
-       if (tail==NULL)
-       {
-               display_message("You are NOT currently ignoring any users", 0, 1);
-       }
-       else
-       {
-               display_message("You are currently ignoring:", 0, 1);
-
-               while (tail!=NULL)
-               {
-                       linecount++;
-                       printf("%s\n", tail->name);
-                       if (linecount>=(screen_height-1))
-                       {
-                               char foo[6];
-                               printf("---more---\r");
-                               echo_off();
-                               get_str(foo,5);
-                               echo_on();
-                               if (foo[0]=='q'|| foo[0]=='Q') break;
-                               printf("            \r");
-                               linecount=0;
-                       }
-                       tail = tail->next;
-               }
-       }
-}
<span style="color: #000000;background-color: #ffdddd">- 
</span>-void t_ignore(CommandList *cm, int argc, const char **argv, char *args)
-{
-       char                    text[MAXTEXTLENGTH];
-       struct IgnoreList       *newnode;
-       int32_t                 tempposn;
-       struct person           tempusr;
-       char                    *namebuff[MAX_ARGC];
-       int                     namecount;
-       int                     argloop;
-
-       if (strcmp(argv[1], "*") == 0)
-       {
-               int ufile,wfile;
-               struct person p;
-               struct who w;
-
-               wfile=who_open(O_RDWR);   
-               ufile=userdb_open(O_RDONLY);
-               if (wfile<0 || ufile<0) return; /* whoops */
-                       
-               while (read(wfile,&w,sizeof(w)))
-               {
-                       /* Skip invalid entries */
-                       if (w.posn < 0)
-                               continue;
-
-                       lseek(ufile,w.posn,0);
-                       read(ufile,&p,sizeof(p));
-
-                               if (cm_flags(p.chatmode,CM_ONCHAT,CM_MODE_ANY))
-                               {
-                                       if (is_ignored(p.name, NULL))
-                                       {
-                                               printf("*** User '%s' already ignored ***\n", p.name);
-                                       }
-                                       else
-                                       {
-                                               newnode = malloc(sizeof(struct IgnoreList));
-                                               newnode->name = malloc(sizeof(char) * (strlen(p.name) + 1));
-                                               strcpy(newnode->name, p.name);
-                                               newnode->next = ignored;
-                                               ignored = newnode;
-                                       }
-                               }
-               }
-               close(ufile);
-               close(wfile);
-
-               snprintf(text,MAXTEXTLENGTH-1,"\03315%s has just ignored everyone currently logged on", user->name);
-               talk_send_raw(text,user->room);
-               snprintf(text,MAXTEXTLENGTH-1,"*** You have now ignored everyone currently logged on ***");
-               display_message(text, 1, 1);
-
-               return;
-       }
-
-       namecount = 0;
-       for (argloop = 1; argloop < argc; argloop++)
-       {
-               if (!is_old(&tempusr,argv[argloop], &tempposn))
-               {
-                       snprintf(text,MAXTEXTLENGTH-1,"*** User '%s' does not exist ***", argv[argloop]);
-                       display_message(text, 1, 1);
-               }
-               else if (!ison(argv[argloop])) {
-                       snprintf(text,MAXTEXTLENGTH-1,"*** User '%s' is not currently logged on ***", tempusr.name);
-                       display_message(text, 1, 1);
-               }
-               else if (is_ignored(argv[argloop], NULL))
-               {
-                       snprintf(text,MAXTEXTLENGTH-1,"*** User '%s' is already being ignored ***", tempusr.name);
-                       display_message(text, 1, 1);
-               }
-               else
-               {   
-                       newnode = malloc(sizeof(struct IgnoreList));
-                       newnode->name = malloc(sizeof(char) * (strlen(tempusr.name) + 1));
-                       strcpy(newnode->name, tempusr.name);
-                       newnode->next = ignored;
-                       ignored = newnode;
-                       namebuff[namecount] = malloc(sizeof(char) * (strlen(tempusr.name) + 1));
-                       strcpy(namebuff[namecount], tempusr.name);
-                       namecount++;
-                       snprintf(text,MAXTEXTLENGTH-1,"*** You are now ignoring user '%s' ***", tempusr.name);
-                       display_message(text, 1, 1);
-               }
-       }
-
-       if (namecount == 0) return;
-
-       snprintf(text,MAXTEXTLENGTH-1,"\03315%s has just ignored ", user->name);
-       for (argloop = 0; argloop < namecount; argloop++)
-       {
-               strcat(text, namebuff[argloop]);
-               if (argloop == namecount - 2) strcat(text, " and ");
-               else if (argloop != namecount - 1) strcat(text, ", ");
-               free(namebuff[argloop]);
-       }
-       talk_send_raw(text,user->room);
-}
<span style="color: #000000;background-color: #ffdddd">- 
</span>-void t_unignore(CommandList *cm, int argc, const char **argv, char *args)
-{
-       char    text[MAXTEXTLENGTH];
-       const char *namebuff[MAX_ARGC];
-       int     namecount;
-       int     argloop;
-
-       if (strcmp(argv[1], "*") == 0)
-       {
-               struct IgnoreList *temp;
-
-               /* unignore everyone in list */
-
-               while (ignored != NULL)
-               {
-                       temp = ignored;
-                       ignored = ignored->next;
-                       free(temp->name);
-                       free(temp);
-               }
-
-               snprintf(text,MAXTEXTLENGTH-1,"\03315%s has just un-ignored everyone", user->name);
-               talk_send_raw(text,user->room);
-               snprintf(text,MAXTEXTLENGTH-1,"*** You have unignored everyone ***");
-               display_message(text, 1, 1);
-
-               return;
-       }
-
-       namecount = 0;
-       for (argloop = 1; argloop < argc; argloop++)
-       {
-               struct IgnoreList *found, *prev = NULL;
-               found = is_ignored(argv[argloop], &prev);
-               if (found)
-               {
-                       /* if at front */
-                       if (prev == NULL) ignored = ignored->next;
-                       /* in middle/end */
-                       else prev->next = found->next;
-                       free(found->name);
-                       free(found);
-
-                       /* argv is here for the duration so we can point into it */
-                       namebuff[namecount] = argv[argloop];
-                       namecount++;
-                       snprintf(text,MAXTEXTLENGTH-1,"*** You have just unignored user '%s' ***", argv[argloop]);
-                       display_message(text, 1, 1);
-               }
-               else
-               {   
-                       snprintf(text,MAXTEXTLENGTH-1,"*** User '%s' is not ignored ***", argv[argloop]);
-                       display_message(text, 1, 1);
-               }
-       }
-
-       if (namecount == 0) return;
-
-       snprintf(text,MAXTEXTLENGTH-1,"\03315%s has just un-ignored ", user->name);
-       for (argloop = 0; argloop < namecount; argloop++)
-       {
-               strcat(text, namebuff[argloop]);
-               if (argloop == namecount - 2)
-                       strcat(text, " and ");
-               else if (argloop != namecount - 1)
-                       strcat(text, ", ");
-       }
-       talk_send_raw(text, user->room);
-}
-
 void t_zod(CommandList *cm, int argc, const char **argv, char *args)
 {
        AUTOFREE_BUFFER excuse = remove_first_word(args);
<span style="color: #aaaaaa">@@ -1408,27 +1202,11 @@ void set_talk_rights(void)
</span>   current_rights = RIGHTS_TALK;
 }      
 
-struct IgnoreList *is_ignored(const char *name, struct IgnoreList **prev)
-{
-       struct IgnoreList *tail;
-
-       if (prev != NULL) *prev = NULL;
-
-       tail = ignored;
-       while (tail != NULL)
-       {
-               if (!strcasecmp(tail->name, name)) return tail;
-               if (prev != NULL) *prev = tail;
-               tail = tail->next;
-       }
-       return NULL;
-}
-
-void sendipc(char *to, char *text, int broadcast) 
<span style="color: #000000;background-color: #ddffdd">+void sendipc(char *to, char *text, int bcast) 
</span> {
        int count;
 
-       if (broadcast) 
<span style="color: #000000;background-color: #ddffdd">+        if (bcast) 
</span>   {
                count = ipc_send_to_all(IPC_SCRIPTIPC, text);
        }
<span style="color: #aaaaaa">@@ -1441,20 +1219,20 @@ void sendipc(char *to, char *text, int broadcast)
</span>           printf("User '%s' is not logged on.\n",to);
        }else
        {
-               if (broadcast)
<span style="color: #000000;background-color: #ddffdd">+                if (bcast)
</span>                   mwlog("SENDIPB %s", text);
                else
                        mwlog("SENDIPC(%s) %s",to,text);
        }
 }
 
-void sendrpc(char *to, char *type, char *text, int broadcast) 
<span style="color: #000000;background-color: #ddffdd">+void sendrpc(char *to, char *type, char *text, int bcast) 
</span> {
        char buff[MAXTEXTLENGTH];
        int count;
 
        snprintf(buff, MAXTEXTLENGTH, "%s %s", type, text);
-       if(broadcast)
<span style="color: #000000;background-color: #ddffdd">+        if(bcast)
</span>   {
                count = ipc_send_to_all(IPC_SCRIPTRPC, buff); 
        }
<span style="color: #aaaaaa">@@ -1467,7 +1245,7 @@ void sendrpc(char *to, char *type, char *text, int broadcast)
</span>           printf("User '%s' is not logged on.\n",to);
        }else
        {
-               if (broadcast)
<span style="color: #000000;background-color: #ddffdd">+                if (bcast)
</span>                   mwlog("SENDRPB(%s) %s", type, text);
                else
                        mwlog("SENDRPC(%s, %s) %s", to, type, text);
<span style="color: #aaaaaa">@@ -1495,7 +1273,7 @@ void enter_talker(int logontype)
</span>   if (autowho)
        {
                update_user(user,userposn);
-               who_list(0);
<span style="color: #000000;background-color: #ddffdd">+                display_wholist(0);
</span>           /* turn off the autowho, so it only occurs on first usage */
                autowho = 0;
        }
</code></pre>

<br>
</li>
<li id='diff-20'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-20'>
<strong>
src/client/talker.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/talker.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/talker.h
</span><span style="color: #aaaaaa">@@ -43,9 +43,6 @@ void t_mrod(CommandList *cm, int argc, const char **argv, char *args);
</span> void t_kick(CommandList *cm, int argc, const char **argv, char *args);
 void t_remove(CommandList *cm, int argc, const char **argv, char *args);
 void t_replay(CommandList *cm, int argc, const char **argv, char *args);
-void t_ignore(CommandList *cm, int argc, const char **argv, char *args);
-void t_unignore(CommandList *cm, int argc, const char **argv, char *args);
-void t_ignorelist(CommandList *cm, int argc, const char **argv, char *args);
 void t_raw(CommandList *cm, int argc, const char **argv, char *args);
 void t_room(CommandList *cm, int argc, const char **argv, char *args);
 void t_ventril(CommandList *cm, int argc, const char **argv, char *args);
<span style="color: #aaaaaa">@@ -78,8 +75,6 @@ void enter_talker(int logontype);
</span> int screen_h(void);
 int screen_w(void);
 
-struct IgnoreList *is_ignored(const char *name, struct IgnoreList **prev);
-
 void sendipc(char *to, char *text, int broadcast);
 void sendrpc(char *to, char *type, char *text, int broadcast);
 
</code></pre>

<br>
</li>
<li id='diff-21'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-21'>
<strong>
src/client/user.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/user.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/user.c
</span><span style="color: #aaaaaa">@@ -362,7 +362,6 @@ void login_ok(struct person *usr, int32_t *userposn, int *autochat)
</span>           else
                        okay=new_usr(usr,name,userposn);
        }while (!okay);
-       check_copies(*userposn);        
 }
 
 void list_users(int newonly) 
</code></pre>

<br>
</li>
<li id='diff-22'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-22'>
<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">@@ -22,10 +22,13 @@
</span> #include "userio.h"
 #include "who.h"
 #include "main.h"
<span style="color: #000000;background-color: #ddffdd">+#include <str_util.h>
+#include <util.h>
</span> 
 extern int busy;
 extern struct person *user;
 extern struct room myroom;
<span style="color: #000000;background-color: #ddffdd">+extern long userposn;
</span> 
 /* called only by cmdline flags */
 void what_list(void) {
<span style="color: #aaaaaa">@@ -48,276 +51,193 @@ void what_list(void) {
</span>   close(ufile);
 }
 
-void who_list(int mode)
<span style="color: #000000;background-color: #ddffdd">+char *itime(unsigned long t)
</span> {
-       struct person u;
-       struct who w;
-       int ufile,wfile;
-       char stats[10];
-       char chat;
-       int wizchat;
-       int wiz;
-       char *divider;
-
-       if (u_god(user->status)) wiz=1; else wiz=0;
-       busy++;
<span style="color: #000000;background-color: #ddffdd">+        static char out[7];
</span> 
-       wfile=who_open(O_RDWR);
-       ufile=userdb_open(O_RDONLY);
-       if (wfile<0 || ufile<0) return; /* whoops */
<span style="color: #000000;background-color: #ddffdd">+        if (t>=3600*48) sprintf(out,"%2ldd%2ldh",t/86400, (t%86400)/3600);
+       else
+       if (t>=3600) sprintf(out,"%2ldh%2ldm",t/3600,(t%3600)/60);
+       else
+       if (t>=60) sprintf(out,"%2ldm%2lds",t/60,t%60);
+       else
+       sprintf(out,"%5lds",t);
+       return(out);
+}
</span> 
-       /* do we tell them who can hear wiz messages */
-       if (s_wizchat(user->special)) wizchat=1; else wizchat=0;
<span style="color: #000000;background-color: #ddffdd">+#define json_array_foreach(array, index, value) \
+       for(index = 0; \
+       index < json_array_size(array) && (value = json_array_get(array, index)); \
+       index++)
+
+static json_t * whoinfo = NULL;
+static time_t   whowhen = 0;
+static int      whotype = -1;
+#define WHOCACHE 120  /* cache who data for this many seconds */
+
+void display_wholist(int mode)
+{
+       time_t now = time(NULL);
+
+       /* we dont have a recent cache of who list,
+        * request one, and get called back when it arrives */
+       if (whoinfo == NULL || whowhen < (now - WHOCACHE)) {
+               whotype = mode;
+               ipc_message_t * msg = ipcmsg_create(IPC_WHOLIST, userposn);
+               ipcmsg_transmit(msg);
+               return;
+       }
</span> 
-       if (mode==1) 
<span style="color: #000000;background-color: #ddffdd">+        busy++;
+       if (mode == 1)
</span>           format_message("\nUser status...");
        else
-       if (wiz) format_message("\nPID    %-*s %-*s  Idle  What...",NAMESIZE,"Name",20,"RealName");
-       else format_message("\n %-*s Idle   What...",NAMESIZE,"Name");
<span style="color: #000000;background-color: #ddffdd">+                format_message("\nPID    %-*s %-*s  Idle  What...",NAMESIZE,"Name",20,"RealName");
</span> 
-       divider = NULL;
<span style="color: #000000;background-color: #ddffdd">+        AUTOFREE_BUFFER divider = NULL;
</span>   for (int i = 0; i < screen_w(); i++) string_add(&divider, "-");
-
        format_message("%s", divider);
 
-       while (read(wfile,&w,sizeof(w)))
-       {
-               /* Skip invalid entries */
-               if (w.posn < 0)
-                       continue;
-
-               lseek(ufile,w.posn,0);
-               read(ufile,&u,sizeof(u));
-
-               show_user_stats(u.status,stats,true);
-
-               /* can they hear wiz messages ? */
-               if (s_wizchat(u.special) && !s_chatoff(u.special))
-                       chat='*';
-               else
-                       chat=' ';
-       
-               /* check they are still alive and show info */
-               {
-                       if (mode == 1) {
-                               if (u.dowhen && u.doing[0] != 0)
-                               format_message("%s %s\033-- (%s ago)",u.name, u.doing ,itime(time(0)-u.dowhen));
-                       } else {
-                       if (cm_flags(u.chatmode,CM_ONCHAT,CM_MODE_ANY))
-                       {
-                               int cml, cpl, pll, myapl;
-                               char *cmt, *cpt, plt[8];
-                               int off;
-                               unsigned long mask;
-       
-                               myapl = (user->chatprivs & CP_PROTMASK) >> CP_PROTSHIFT;
-                               mask=u.chatmode & 0xfffffffe;
-                               if (!cp_flags(user->chatprivs,CP_CANGLOBAL,CM_MODE_ALL)) mask&= ~(CM_GLOBAL);
-                               if (!cp_flags(user->chatprivs,CP_SPY,CM_MODE_ALL)) mask&= ~(CM_SPY);
-
-                               if (myapl > 0 && cm_flags(user->chatprivs, CP_PROTECT, CM_MODE_ALL)) /* replaced with better info */
-                                       mask&= ~(CM_PROTECTED);
-                               else if (u.chatmode & CM_PROTMASK)
-                                       mask |= CM_PROTECTED; /* looks like temp protect */
-
-                               snprintf(u.doing,DOINGSIZE, "Room %d",u.room);
-
-                               off=strlen(u.doing);
-                               snprintf(&u.doing[off],DOINGSIZE-off," (");
-                               /* Show chatmode flags */
-                               cmt=display_cmflags(mask);
-                               cml=strlen(display_cmflags(mask));
-                               off=strlen(u.doing);
-                               if (strlen(cmt)>0)
-                               {
-                                       snprintf(&u.doing[off],DOINGSIZE-off,"%-*s", cml, cmt);
-                               }
-                               /* Show protection */
-                               if (myapl > 0 && cm_flags(user->chatprivs, CP_PROTECT, CM_MODE_ALL))
-                               {
-                                       show_protection(u.chatmode, u.chatprivs, plt, myapl);
-                                       pll=strlen(plt);
-                                       if (plt[0] == '0' && cm_flags(u.chatmode, CM_PROTECTED, CM_MODE_ALL))
-                                               plt[0]='p';
-                                       if (plt[2] == '0' && cm_flags(u.chatprivs, CP_PROTECT, CM_MODE_ALL))
-                                               plt[2]='P';
-
-                                       off=strlen(u.doing);
-                                       if (strlen(cmt)>0)
-                                       {
-                                               snprintf(&u.doing[off],DOINGSIZE-off,",");
-                                       }
-                                       off=strlen(u.doing);
-                                       snprintf(&u.doing[off],DOINGSIZE-off,"%-*s", pll, plt);
-                               } else
-                                       plt[0] = '\0';
-                               /* Show chatpriv flags */
-                               if (myapl > 0 && cm_flags(user->chatprivs, CP_PROTECT, CM_MODE_ALL)) /* 'P' priv replaced with better info */
-                                       cpt=display_cpflags(u.chatprivs & user->chatprivs & ~CP_PROTECT);
-                               else
-                                       cpt=display_cpflags(u.chatprivs & user->chatprivs);
-                               off=strlen(u.doing);
-                               cpl=strlen(cpt);
-                               if ((strlen(cmt)+strlen(plt))>0 && cpl>0)
-                               {
-                                       snprintf(&u.doing[off],DOINGSIZE-off,",");
-                               }
-                               off=strlen(u.doing);
-                               if (cpl>0)
-                               {
-                                       snprintf(&u.doing[off],DOINGSIZE-off,"%-*s", cpl, cpt);
-                               }
-
-                               off=strlen(u.doing);
-                               snprintf(&u.doing[off],DOINGSIZE-off,")");
-                       }
-
-                       if (wiz)
-                       {
-                               format_message("%-5d %c%-*s %-20.20s %6s %s\033--",w.pid,chat,NAMESIZE,u.name,u.realname,itime(time(0)-u.idletime),u.doing);
-                       }else
-                       {
-                               format_message("%c%-*s %6s %s\033--",wizchat?chat:' ',NAMESIZE,u.name,itime(time(0)-u.idletime),u.doing);
-                       }
-                       }
<span style="color: #000000;background-color: #ddffdd">+        size_t wi;
+       json_t *entry;
+       json_array_foreach(whoinfo, wi, entry) {
+               int pid = json_getint(entry, "pid");
+               const char *name = json_getstring(entry, "name");
+               const char *realname = json_getstring(entry, "realname");
+               time_t dowhen = json_getint(entry, "dowhen");
+               const char * doing = json_getstring(entry, "doing");
+               time_t idletime = json_getint(entry, "idletime");
+               int channel = json_getint(entry, "channel");
+               json_t *perms = json_object_get(entry, "perms");
+
+               if (mode == 1) {
+                       if (dowhen && doing!=NULL && doing[0] != 0)
+                               format_message("%s %s\033-- (%s ago)",name, doing ,itime(time(0)-dowhen));
+               } else {
+                       char chat=' ';
+                       //const char *status = json_getstring(perms, "status");
+                       const char *chatmode = json_getstring(perms, "chatmode");
+                       const char *chatprivs = json_getstring(perms, "chatprivs");
+                       const char *prot = json_getstring(perms, "protection");
+
+                       if (json_getint(perms, "wizchat") > 0) chat='*';
+
+                       format_message("%-5d %c%-*s %-20.20s %6s Room %d (%s,%s,%s)\033--",pid,chat,NAMESIZE,name,realname,itime(now-idletime),channel, chatmode, prot, chatprivs);
</span>           }
        }
        format_message("%s", divider);
-       close(wfile);
-       close(ufile);
-
-       free(divider);
-
        busy--;
 }
 
-int32_t get_who_userposn(int pid)
<span style="color: #000000;background-color: #ddffdd">+void update_wholist(ipc_message_t *msg)
</span> {
-       struct who w;
-       int wfile;
-       long found=-1;
-       
-       if ((wfile=who_open(O_RDONLY))<0) return(-1);
-
-       while (read(wfile,&w,sizeof(w)))
-       {
-               if (w.posn >= 0 &&
-                   (pid==-w.pid || pid==w.pid ))
-               {
-                       found=w.posn;
-                       break;
-               }
<span style="color: #000000;background-color: #ddffdd">+        /* there is an old one, clear it */
+       if (whoinfo != NULL)
+               json_decref(whoinfo);
+
+       /* store the new one */
+       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);
+               whotype = -1;
</span>   }
-       close(wfile);
-       
-       return(found);
 }
 
-#ifdef RWHO
-void rwho_update(void)
<span style="color: #000000;background-color: #ddffdd">+char *part_who(const char *text, int status)
</span> {
-       static int setup=0;
-       static long t=0;
-
-       if (!setup)
-       {
-               setup=1;
-               rwhocli_setup("137.44.12.4","frodperfect","Milliways","THE Bulletin Board");
<span style="color: #000000;background-color: #ddffdd">+        static int len = 0;
+       static int index = 0; /* looking for the Nth answer */
+       time_t now = time(NULL);
+
+       /* we dont have a recent cache of who list,
+        * ask for an update, then do the best you can */
+       if (whoinfo == NULL || whowhen < (now - WHOCACHE)) {
+               ipc_message_t * msg = ipcmsg_create(IPC_WHOLIST, userposn);
+               ipcmsg_transmit(msg);
</span>   }
-       if (time(0)-t>240)
-       {
-               t=time(0);
-               rwhocli_pingalive();
-               rwho_list();
<span style="color: #000000;background-color: #ddffdd">+
+       /* we dont even have stale info */
+       if (whoinfo == NULL) return(NULL);
+
+       /* start a new search */
+       if (status == 0) {
+               len = strlen(text);
+               index = 0;
</span>   }
-}
 
-static void rwho_list(void)
-{
-       struct person user;
-       struct who w;
-       int ufile,wfile;
-       
-       wfile=openwhofile(O_RDWR);
-       ufile=openuserfile(O_RDONLY);
-
-       if (wfile<0 || ufile<0) return; /* whoops */      
-       while (read(wfile,&w,sizeof(w))>0)
-       {
-               if (w.posn!=-1L)
-               {
-                       lseek(ufile,w.posn,0);
-                       read(ufile,&user,sizeof(user));
-
-                       if (w.pid>-1)
-                       {
-                               rwhocli_userlogin(user.name,user.name,user.lastlogout);
-                       }else
-                       {
-                               rwhocli_userlogout(user.name);
<span style="color: #000000;background-color: #ddffdd">+        size_t wi;
+       json_t *entry;
+       int count = 0;
+       json_array_foreach(whoinfo, wi, entry) {
+               const char *name = json_getstring(entry, "name");
+               if (name == NULL) continue;
+               if (strncasecmp(name, text, len)==0) {
+                       /* found the one we want */
+                       if (count == index) {
+                               index++;
+                               return dupstr(name,"");
</span>                   }
<span style="color: #000000;background-color: #ddffdd">+                        /* found one we dont want */
+                       count++;
</span>           }
        }
-       close(wfile);
-       close(ufile);
<span style="color: #000000;background-color: #ddffdd">+        /* run out of answers */
+       return NULL;
</span> }
 
-#endif
-
-void check_copies(int32_t where)
<span style="color: #000000;background-color: #ddffdd">+char *part_who_talk(const char *text, int status)
</span> {
-       struct who u;
-       int file;
-       int count;
-       char buff[5];
-
-       file=who_open(O_RDWR);
-
-       if (file<0) return; /* whoops */
-       count=0;
-       lseek(file,0L,0);
-       while(read(file,&u,sizeof(u))>0)
-       {
-               if (u.pid>0 && u.posn==where) {
-                       count++;
-               }
<span style="color: #000000;background-color: #ddffdd">+        static int len = 0;
+       static int index = 0; /* looking for the Nth answer */
+       time_t now = time(NULL);
+
+       /* we dont have a recent cache of who list,
+        * ask for an update, then do the best you can */
+       if (whoinfo == NULL || whowhen < (now - WHOCACHE)) {
+               ipc_message_t * msg = ipcmsg_create(IPC_WHOLIST, userposn);
+               ipcmsg_transmit(msg);
</span>   }
 
-       if (count==1)
-       {
-               printf("You are already logged in.\n");
-       }else
-       if (count>1)
-       {
-               printf("You are already logged in %d times.\n",count);
<span style="color: #000000;background-color: #ddffdd">+        /* we dont even have stale info */
+       if (whoinfo == NULL) return(NULL);
+
+       /* start a new search */
+       if (status == 0) {
+               len = strlen(text);
+               index = 0;
</span>   }
-       if (count>0)
-       {
-               printf("Do you want to kill those sessions ?");
-               get_str(buff,4);
-               if (BoolOpt(buff)>0)
-               {
-                       printf("Killing... ");
-                       lseek(file,0L,0);
-                       while(read(file,&u,sizeof(u))>0)
-                               if (u.pid>0 && u.posn==where)
-                                       kill(u.pid,SIGTERM);
-                       printf("Done.\n");
<span style="color: #000000;background-color: #ddffdd">+
+       size_t wi;
+       json_t *entry;
+       int count = 0;
+       json_array_foreach(whoinfo, wi, entry) {
+               const char *name = json_getstring(entry, "name");
+               json_t * perms = json_object_get(entry, "perms");
+               const char *chatmode = NULL;
+               if (perms != NULL) chatmode=json_getstring(entry, "chatmode");
+
+               if (name == NULL) continue;
+               if (chatmode == NULL) continue;
+
+               /* isnt on chat */
+               if (strchr(chatmode, 'c')==NULL) continue;
+
+               if (strncasecmp(name, text, len)==0) {
+                       /* found the one we want */
+                       if (count == index) {
+                               index++;
+                               return dupstr(name,"");
+                       }
+                       /* found one we dont want */
+                       count++;
</span>           }
        }
-       close(file);
<span style="color: #000000;background-color: #ddffdd">+        /* run out of answers */
+       return NULL;
</span> }
 
-char *itime(unsigned long t)
-{
-       static char out[7];
-
-       if (t>=3600*48) sprintf(out,"%2ldd%2ldh",t/86400, (t%86400)/3600);
-       else
-       if (t>=3600) sprintf(out,"%2ldh%2ldm",t/3600,(t%3600)/60);
-       else
-       if (t>=60) sprintf(out,"%2ldm%2lds",t/60,t%60);
-       else
-       sprintf(out,"%5lds",t);
-       return(out);
-}
</code></pre>

<br>
</li>
<li id='diff-23'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-23'>
<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">@@ -2,11 +2,14 @@
</span> #define CLIENT_WHO_H
 
 #include <stdint.h>
<span style="color: #000000;background-color: #ddffdd">+#include <ipc.h>
</span> 
 void check_copies(int32_t where);
-void who_list(int mode);
-void what_list(void);
 char *itime(unsigned long t);
-int32_t get_who_userposn(int pid);
<span style="color: #000000;background-color: #ddffdd">+void display_wholist(int type);
+void update_wholist(ipc_message_t *msg);
+void what_list(void);
+char *part_who_talk(const char *text, int status);
+char *part_who(const char *text, int status);
</span> 
 #endif /* CLIENT_WHO_H */
</code></pre>

<br>
</li>
<li id='diff-24'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-24'>
<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">@@ -179,7 +179,6 @@ const char * ipc_nametype(enum ipc_types msgtype)
</span>           case IPC_CHANNEL: return "IPC_CHANNEL"; break;
                case IPC_WIZ: return "IPC_WIZ"; break;
                case IPC_GAG: return "IPC_GAG"; break;
-               case IPC_CLEARIGN: return "IPC_CLEARIGN"; break;
                case IPC_SCRIPTIPC: return "IPC_SCRIPTIPC"; break;
                case IPC_SCRIPTRPC: return "IPC_SCRIPTRPC"; break;
                case IPC_CHECKONOFF: return "IPC_CHECKONOFF"; break;
<span style="color: #aaaaaa">@@ -195,6 +194,7 @@ const char * ipc_nametype(enum ipc_types msgtype)
</span>           case IPC_REPLAY: return "IPC_REPLAY"; break;
                case IPC_EVENT: return "IPC_EVENT"; break;
                case IPC_ACTION: return "IPC_ACTION"; break;
<span style="color: #000000;background-color: #ddffdd">+                case IPC_WHOLIST: return "IPC_WHOLIST"; break;
</span>   }
        return "IPC_Unknown";
 }
</code></pre>

<br>
</li>
<li id='diff-25'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-25'>
<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">@@ -36,7 +36,6 @@ enum ipc_types {
</span>   IPC_CHANNEL     = 16,
        IPC_WIZ         = 17,
        IPC_GAG         = 18,
-       IPC_CLEARIGN    = 19,
        IPC_SCRIPTIPC   = 21,
        IPC_SCRIPTRPC   = 22,
        IPC_CHECKONOFF  = 23,
<span style="color: #aaaaaa">@@ -51,7 +50,8 @@ enum ipc_types {
</span>   IPC_TALKERROR   = FCC('TERR'),
        IPC_REPLAY      = FCC('PLAY'),
        IPC_EVENT       = FCC('EVNT'),
-       IPC_ACTION      = FCC('ACTN')
<span style="color: #000000;background-color: #ddffdd">+        IPC_ACTION      = FCC('ACTN'),
+       IPC_WHOLIST     = FCC('WHOL')
</span> };
 
 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
</code></pre>

<br>
</li>
<li id='diff-26'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-26'>
<strong>
src/perms.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/perms.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/perms.c
</span><span style="color: #aaaaaa">@@ -229,39 +229,6 @@ void show_fold_groups(char st, char *tmp, int flag)
</span>   tmp[pos] = '\0';
 }
 
-extern struct person *user;
-
-void mwlog(const char *fmt, ...)
-{
-       va_list ap;
-       int file;
-       char outmsg[LOGLINESIZE];
-       char addstr[LOGLINESIZE];
-       char new[LOGLINESIZE];
-       time_t t;
-
-       va_start(ap, fmt);
-       
-       if ((file=open(LOGFILE,O_WRONLY|O_CREAT|O_APPEND,0600))<0)
-       {
-               perror("log");
-               return;
-       }
-       t=time(0);
-
-       vsnprintf(addstr, LOGLINESIZE-1, fmt, ap);
-       snprintf(outmsg, LOGLINESIZE-1, "%s", asctime(gmtime(&t)));
-       outmsg[strlen(outmsg)-1] = ' ';
-
-       snprintf(new, LOGLINESIZE-2, "%s| %*s | %s", outmsg, NAMESIZE, user->name, addstr);
-       strcat(new, "\n");
-
-       write(file,new,strlen(new));
-       close(file);
-
-       va_end(ap);
-}
-
 int get_subscribe(struct person *usr, int folder)
 {
        if (folder<=31 && folder>=0)
</code></pre>

<br>
</li>
<li id='diff-27'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-27'>
<strong>
src/perms.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/perms.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/perms.h
</span><span style="color: #aaaaaa">@@ -4,8 +4,6 @@
</span> #include "folders.h"
 #include "user.h"
 
-void mwlog(const char *fmt, ...) __attribute__((format(printf,1,2)));
-
 char user_stats(const char *string, char stat);
 char mesg_stats(char *string, char stat);
 
</code></pre>

<br>
</li>
<li id='diff-28'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-28'>
<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">@@ -116,17 +116,20 @@ IPC_ACTION - user requests an action
</span> IPC_WHOLIST - list of all the users currently known to the system
        Send an empty body one of these to the server to request a refresh
        Respose:  json array() each element being one session
-               pid      - session idle
<span style="color: #000000;background-color: #ddffdd">+                pid      - session id
</span>           id       - user id
                name     - username
                realname - users actual name (if permitted)
-               idle     - seconds idle
<span style="color: #000000;background-color: #ddffdd">+                idletime - idle time
</span>           doing    - doing info
                dowhen   - when doing last updated
<span style="color: #000000;background-color: #ddffdd">+                channel  - Current (primary?) channel
</span>           perms    - object of permissions
-                       chatmode
-                       chatprivs
-                       protection
<span style="color: #000000;background-color: #ddffdd">+                    status
+                   chatmode
+                   chatprivs
+                   protection
+                   wizchat
</span> 
 
 all other codes are old unformatted messages and are to be phased out,
</code></pre>

<br>
</li>
<li id='diff-29'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-29'>
<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">@@ -10,6 +10,7 @@
</span> #include <arpa/inet.h>
 #include <stdlib.h>
 #include <sys/time.h>
<span style="color: #000000;background-color: #ddffdd">+#include <stdbool.h>
</span> #include <time.h>
 
 #include <socket.h>
<span style="color: #aaaaaa">@@ -23,6 +24,8 @@
</span> #include "replay.h"
 #include "actions.h"
 #include <gags.h>
<span style="color: #000000;background-color: #ddffdd">+#include <perms.h>
+#include <special.h>
</span> 
 struct list_head connection_list;
 
<span style="color: #aaaaaa">@@ -133,6 +136,10 @@ void drop_connection(ipc_connection_t * conn)
</span>   }
        bzero(conn, sizeof(ipc_connection_t));
        free(conn);
<span style="color: #000000;background-color: #ddffdd">+
+       ipc_message_t * whoinfo = msg_wholist();
+       msg_attach_to_all(whoinfo);
+       ipcmsg_destroy(whoinfo);
</span> }
 
 void watch_mainsock(int mainsock)
<span style="color: #aaaaaa">@@ -288,6 +295,10 @@ void process_msg(ipc_connection_t *conn, ipc_message_t *msg)
</span>           close(wfd);
                conn->state = IPCSTATE_VALID;
                ipcmsg_destroy(msg);
<span style="color: #000000;background-color: #ddffdd">+
+               ipc_message_t * whoinfo = msg_wholist();
+               msg_attach_to_all(whoinfo);
+               ipcmsg_destroy(whoinfo);
</span>           return;
        }
 
<span style="color: #aaaaaa">@@ -327,6 +338,14 @@ void process_msg(ipc_connection_t *conn, ipc_message_t *msg)
</span>           return;
        }
 
<span style="color: #000000;background-color: #ddffdd">+        if (msg->head.type == IPC_WHOLIST) {
+               ipc_message_t * whoinfo = msg_wholist();
+               msg_attach(whoinfo, conn);
+               ipcmsg_destroy(whoinfo);
+               ipcmsg_destroy(msg);
+               return;
+       }
+
</span>   /**** end of messages to the server
         *    all below this point are intended to be retransmitted
         */
<span style="color: #aaaaaa">@@ -592,3 +611,51 @@ void init_server()
</span>           pollfd = epoll_create(30);
        }
 }
<span style="color: #000000;background-color: #ddffdd">+
+ipc_message_t * msg_wholist(void)
+{
+       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;
+
+               lseek(users_fd, who.posn, SEEK_SET);
+               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);
+               json_addstring(j, "name", user.name);
+               json_addstring(j, "realname", user.realname);
+               json_addstring(j, "doing", user.doing);
+               json_addint(j, "dowhen", user.dowhen);
+               json_addint(j, "channel", user.room);
+               json_addint(j, "idletime", user.idletime);
+
+               json_t * p = json_init(NULL);
+               char info[80];
+               show_user_stats(user.status,info,true);
+               json_addstring(p, "status", info);
+               if (s_wizchat(user.special) && !s_chatoff(user.special))
+                       json_addint(p, "wizchat", 1);
+               json_addstring(p, "chatmode", display_cmflags(user.chatmode));
+               json_addstring(p, "chatprivs", display_cpflags(user.chatprivs));
+               show_protection(user.chatmode, user.chatprivs, info, 10);
+               json_addstring(p, "protection", info);
+               json_addobject(j, "perms", p);
+               json_decref(p);
+
+               json_array_append_new(list, j);
+       }
+       ipcmsg_json_encode(msg, list);
+       json_decref(list);
+       return msg;
+}
</span></code></pre>

<br>
</li>
<li id='diff-30'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-30'>
<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">@@ -19,4 +19,6 @@ void msg_attach(ipc_message_t *msg, ipc_connection_t *conn);
</span> void init_server(void);
 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);
<span style="color: #000000;background-color: #ddffdd">+ipc_message_t * msg_wholist(void);
+
</span> #endif /* SERVSOCK_H */
</code></pre>

<br>
</li>
<li id='diff-31'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-31'>
<strong>
src/socket.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/socket.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/socket.c
</span><span style="color: #aaaaaa">@@ -339,6 +339,15 @@ int json_addint(json_t * js, const char * key, int value)
</span>   return 0;
 }
 
<span style="color: #000000;background-color: #ddffdd">+int json_addobject(json_t * js, const char * key, json_t * obj)
+{
+       if (obj == NULL) return -1;
+       if (!json_is_object(js)) return -1;
+       if (!json_is_object(obj)) return -1;
+       json_object_set(js, key, obj);
+       return 0;
+}
+
</span> const char * json_getstring(json_t * js, const char * key)
 {
        json_t * tmp;
</code></pre>

<br>
</li>
<li id='diff-32'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-32'>
<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">@@ -80,6 +80,7 @@ int ipcmsg_json_encode(ipc_message_t *msg, json_t *js);
</span> json_t *json_init(ipc_message_t *msg);
 int json_addstring(json_t *js, const char *key, const char *value, ...);
 int json_addint(json_t *js, const char *key, int value);
<span style="color: #000000;background-color: #ddffdd">+int json_addobject(json_t *js, const char *key, json_t * obj);
</span> const char *json_getstring(json_t *js, const char *key);
 int json_getint(json_t *js, const char *key);
 void ipcmsg_summary(const char *intro, ipc_message_t *msg);
</code></pre>

<br>
</li>
<li id='diff-33'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-33'>
<strong>
src/webclient/Makefile
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/webclient/Makefile
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/webclient/Makefile
</span><span style="color: #aaaaaa">@@ -6,7 +6,7 @@ CFLAGS+= -I.. -I/usr/include/postgresql
</span> 
 build: mwpoll
 
-mwpoll: mwpoll.o import.o comms.o mwstring.o ../libmw.a
<span style="color: #000000;background-color: #ddffdd">+mwpoll: mwpoll.o import.o comms.o mwstring.o ../libmw.a 
</span>   $(CC) $(LDFLAGS) $(LDLIBS) -o $@ $^
 
 clean:
</code></pre>

<br>
</li>
<li id='diff-34'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-34'>
<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">@@ -69,6 +69,8 @@ struct list_head connlist;
</span> char * json_escape(char *in);
 static void handle_mesg(void);
 
<span style="color: #000000;background-color: #ddffdd">+void mwlog(const char *fmt, ...) __attribute__((format(printf,1,2)));
+
</span> /* unix socket to accept control commands from */
 void open_command_socket()
 {
<span style="color: #aaaaaa">@@ -579,3 +581,35 @@ void create_user(struct person *me, int *userposn, const char *username, const c
</span>   }
        userdb_write(me, userposn);
 }
<span style="color: #000000;background-color: #ddffdd">+
+void mwlog(const char *fmt, ...)
+{
+       va_list ap;
+       int file;
+       char outmsg[LOGLINESIZE];
+       char addstr[LOGLINESIZE];
+       char new[LOGLINESIZE];
+       time_t t;
+
+       va_start(ap, fmt);
+       
+       if ((file=open(LOGFILE,O_WRONLY|O_CREAT|O_APPEND,0600))<0)
+       {
+               perror("log");
+               return;
+       }
+       t=time(0);
+
+       vsnprintf(addstr, LOGLINESIZE-1, fmt, ap);
+       snprintf(outmsg, LOGLINESIZE-1, "%s", asctime(gmtime(&t)));
+       outmsg[strlen(outmsg)-1] = ' ';
+
+       snprintf(new, LOGLINESIZE-2, "%s| %*s | %s", outmsg, NAMESIZE, user->name, addstr);
+       strcat(new, "\n");
+
+       write(file,new,strlen(new));
+       close(file);
+
+       va_end(ap);
+}
+
</span></code></pre>

<br>
</li>
<li id='diff-35'>
<a href='https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5#diff-35'>
<strong>
src/who.c
</strong>
</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">+++ b/src/who.c
</span><span style="color: #aaaaaa">@@ -83,3 +83,4 @@ long who_find(const char * username)
</span> 
        return where;
 }
<span style="color: #000000;background-color: #ddffdd">+
</span></code></pre>

<br>
</li>

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

<br>
<a href="https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5">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/c4d8ec597f6369636ce5a960f4cec91c8a929fe5"}}</script>
</p>
</div>
</body>
</html>