[mw-devel] [Git][arthur/mw][master] Try to rid the world of references to who_open(), almost done

Justin Mitchell arthur at sucs.org
Wed Oct 7 15:11:40 BST 2015


Justin Mitchell pushed to branch master at Justin Mitchell / mw


Commits:
c4d8ec59 by Justin Mitchell at 2015-10-07T15:10:59Z
Try to rid the world of references to who_open(), almost done

- - - - -


36 changed files:

- .gitignore
- + src/.gitignore
- src/bb.h
- src/client/chattable.c
- src/client/completion.c
- src/client/edit.c
- src/client/folders.c
- src/client/incoming.c
- src/client/incoming.h
- src/client/main.c
- src/client/main.h
- src/client/mesg.c
- src/client/mesg.h
- src/client/new.c
- src/client/new.h
- src/client/newmain.c
- src/client/script.c
- src/client/script_inst.c
- src/client/script_inst.h
- src/client/talker.c
- src/client/talker.h
- src/client/user.c
- src/client/who.c
- src/client/who.h
- src/ipc.c
- src/ipc.h
- src/perms.c
- src/perms.h
- src/server/PROTOCOL
- src/server/servsock.c
- src/server/servsock.h
- src/socket.c
- src/socket.h
- src/webclient/Makefile
- src/webclient/comms.c
- src/who.c


Changes:

=====================================
.gitignore
=====================================
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
 *.so
 *.pyc
 *.swp
+*.deb
 .deps
 cscope.out
 src/client/mw


=====================================
src/.gitignore
=====================================
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1 @@
+tags


=====================================
src/bb.h
=====================================
--- a/src/bb.h
+++ b/src/bb.h
@@ -53,13 +53,6 @@
 #define RIGHTS_BBS	0
 #define RIGHTS_TALK	1
 
-
-struct IgnoreList
-{
-	char			*name;
-	struct IgnoreList	*next;
-};
-                
 #define PACKAGE	"mw"
 #define LOCALEDIR HOMEPATH"/locale"
 


=====================================
src/client/chattable.c
=====================================
--- a/src/client/chattable.c
+++ b/src/client/chattable.c
@@ -44,8 +44,6 @@ CommandList chattable[]={
 {"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},
@@ -77,7 +75,6 @@ CommandList chattable[]={
 {"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},


=====================================
src/client/completion.c
=====================================
--- a/src/client/completion.c
+++ b/src/client/completion.c
@@ -3,6 +3,7 @@
 #include "main.h"
 #include "talker_privs.h"
 #include "alias.h"
+#include "who.h"
 
 /*
   modes:	0 - commands
@@ -49,7 +50,6 @@ CompletionList tctable[]={
 {"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},
@@ -64,7 +64,6 @@ CompletionList tctable[]={
 {"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},


=====================================
src/client/edit.c
=====================================
--- a/src/client/edit.c
+++ b/src/client/edit.c
@@ -36,7 +36,7 @@
 const char *partlist_user[]={
 "edit", "status", "special", "groups", "passwd", "chatprivs", "chatmode",
 "realname", "username", "contact", "timeout", "lastread", "view", "room",
-"clearignore", "protection", "doing", NULL};
+"protection", "doing", NULL};
 
 extern int busy;
 extern int mesg_waiting;
@@ -571,22 +571,6 @@ void edit_user(const char *args, const char *name)
 		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"));


=====================================
src/client/folders.c
=====================================
--- a/src/client/folders.c
+++ b/src/client/folders.c
@@ -15,6 +15,7 @@
 #include "user.h"
 #include "userio.h"
 #include "folders.h"
+#include "mesg.h"
 
 void add_folder(void)
 {


=====================================
src/client/incoming.c
=====================================
--- a/src/client/incoming.c
+++ b/src/client/incoming.c
@@ -27,6 +27,9 @@
 #include "who.h"
 #include "user.h"
 #include "util.h"
+#include "incoming.h"
+#include <jansson.h>
+#include <str_util.h>
 
 extern Alias rpc_list;
 extern Alias event_list;
@@ -40,7 +43,6 @@ extern ipc_connection_t *ipcsock;
 
 int new_mail_waiting=0;
 int mesg_waiting = 0;
-struct IgnoreList *ignored;
 char *mrod_user=NULL;
 
 static int MesgStacked=0;
@@ -61,7 +63,6 @@ static void force_gag(char *text, unsigned long theirprivs, const char *from);
 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);
 
@@ -718,13 +719,13 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct person *mesg_user)
 			reset_timeout(user->timeout);
 			break;
 		case IPC_TEXT:
-			if (!is_ignored(mesg_user->name, NULL)) force_text(msg, newbuff, mesg_user->name);
+			force_text(msg, newbuff, mesg_user->name);
 			break;
 		case IPC_SCRIPTIPC:
-			if (!is_ignored(mesg_user->name, NULL)) force_ipc(newbuff, mesg_user->name);
+			force_ipc(newbuff, mesg_user->name);
 			break;
 		case IPC_SCRIPTRPC:
-			if (!is_ignored(mesg_user->name, NULL)) force_rpc(newbuff, mesg_user->name);
+			force_rpc(newbuff, mesg_user->name);
 			break;
 		case IPC_CHECKONOFF:
 			force_checkonoff(newbuff, mesg_user->name);
@@ -738,9 +739,6 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct person *mesg_user)
 		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;
@@ -753,6 +751,9 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct person *mesg_user)
 		case IPC_TALKERROR:
 			display_error(msg);
 			break;
+		case IPC_WHOLIST:
+			update_wholist(msg);
+			break;
 		default:
 			devel_msg("incoming_mesg", "unknown message type %d.\007", state);
 	}
@@ -854,21 +855,6 @@ static void force_rpc(char *text, char *from)
 	}
 }
 
-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);
@@ -1115,4 +1101,3 @@ static void mrod(char *from, char *msg)
 	strcpy(mrod_user, from);
 	close_down(3, from, msg);
 }
-


=====================================
src/client/incoming.h
=====================================
--- a/src/client/incoming.h
+++ b/src/client/incoming.h
@@ -1,5 +1,6 @@
 #ifndef INCOMING_H
 #define INCOMING_H
+#include <ipc.h>
 
 /* Incoming message flags */
 #define MST_EVENT	0x01	/* Event script will be called */
@@ -26,9 +27,6 @@ struct mstack
 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);


=====================================
src/client/main.c
=====================================
--- a/src/client/main.c
+++ b/src/client/main.c
@@ -243,9 +243,6 @@ static void accept_line(char *line)
 			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);
@@ -353,8 +350,6 @@ int main(int argc, char **argv)
 	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;
@@ -381,8 +376,6 @@ int main(int argc, char **argv)
 	user=(struct person *)malloc(sizeof(*user));
 	fold=(struct folder *)malloc(sizeof(*fold));
 
-	/* init ignore list */
-	ignored = NULL;
 	output=stdout;
 
 #ifdef GNUTLS_VERSION_MAJOR
@@ -406,8 +399,6 @@ int main(int argc, char **argv)
 		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;
 
@@ -506,30 +497,6 @@ int main(int argc, char **argv)
 		}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;
@@ -547,7 +514,7 @@ int main(int argc, char **argv)
 	}
 
 	/* if any 'view and quit' options specified, then quit */
-	if (view_new || view_who || view_since || view_what)
+	if (view_new || view_since)
 	{
 		free(user);
 		free(fold);
@@ -602,7 +569,7 @@ int main(int argc, char **argv)
 			exit(-1);
 		}
 		remote=true;
-		new(user);  
+		show_new(user);  
 		update_user(user,tmp);
 		free(user);
 		free(fold);
@@ -682,10 +649,6 @@ int main(int argc, char **argv)
 		quietmode=0;
 	}
 
-#ifdef RWHO
-	rwho_update();
-#endif
-
 	{
 		struct sockaddr sa;
 		socklen_t ss;
@@ -890,8 +853,6 @@ void close_down(int exitmode, char *sourceuser, char *reason)
 {
 	extern char *event_user;
 	extern char *event_body_text;
-	extern struct IgnoreList *ignored;
-	struct IgnoreList *temp;
 
 	disable_rl(0);
 
@@ -932,15 +893,6 @@ void close_down(int exitmode, char *sourceuser, char *reason)
 	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);
@@ -971,9 +923,6 @@ void close_down(int exitmode, char *sourceuser, char *reason)
 
 	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);
@@ -1804,84 +1753,6 @@ char *find_folder(const char *text, int state)
 }
 
 
-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;


=====================================
src/client/main.h
=====================================
--- a/src/client/main.h
+++ b/src/client/main.h
@@ -11,8 +11,6 @@ int idle(int fd, int millis);
 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);


=====================================
src/client/mesg.c
=====================================
--- a/src/client/mesg.c
+++ b/src/client/mesg.c
@@ -1,6 +1,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
 #include <string.h>
 #include <stdarg.h>
 #include "talker_privs.h"
@@ -131,4 +133,36 @@ void broadcast(int state, const char *fmt, ...)
 	}
 }
 
+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);
+}
 


=====================================
src/client/mesg.h
=====================================
--- a/src/client/mesg.h
+++ b/src/client/mesg.h
@@ -7,5 +7,6 @@ void broadcast(int state, const char *fmt, ...) __attribute__((format(printf,2,3
 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);
+void mwlog(const char *fmt, ...) __attribute__((format(printf,1,2)));
 
 #endif /* MESG_H */


=====================================
src/client/new.c
=====================================
--- a/src/client/new.c
+++ b/src/client/new.c
@@ -176,7 +176,7 @@ static int read_new(struct person *user, struct folder *data, int folnum)
 	return(0);
 }
 
-void new(struct person *user)
+void show_new(struct person *user)
 {		
 	struct folder *data;	
 	int folderfile;


=====================================
src/client/new.h
=====================================
--- a/src/client/new.h
+++ b/src/client/new.h
@@ -4,7 +4,7 @@
 #include "user.h"
 
 void list_new_items(struct person *user, int flag);
-void new(struct person *user);
+void show_new(struct person *user);
 void latest(struct person *user);
 
 #endif /* NEW_H */


=====================================
src/client/newmain.c
=====================================
--- a/src/client/newmain.c
+++ b/src/client/newmain.c
@@ -36,6 +36,7 @@
 #include "alias.h"
 #include "userio.h"
 #include "mesg.h"
+#include "incoming.h"
 
 extern Alias alias_list;
 
@@ -173,7 +174,7 @@ void c_listall(CommandList *cm, int argc, const char **argv, char *args)
 void c_new(CommandList *cm, int argc, const char **argv, char *args)
 {
 	busy++;
-	new(user);
+	show_new(user);
 	busy--;
 	get_folder_number(fold,currentfolder);
 	update_user(user,userposn);
@@ -485,7 +486,7 @@ void c_latest(CommandList *cm, int argc, const char **argv, char *args)
 void c_who(CommandList *cm, int argc, const char **argv, char *args)
 {
 	update_user(user,userposn);
-	who_list(0);
+	display_wholist(0);
 }
 
 void c_tell(CommandList *cm, int argc, const char **argv, char *args)


=====================================
src/client/script.c
=====================================
--- a/src/client/script.c
+++ b/src/client/script.c
@@ -22,6 +22,7 @@
 #include "js.h"
 #include "user.h"
 #include "userio.h"
+#include "who.h"
 
 extern Alias bind_list;
 


=====================================
src/client/script_inst.c
=====================================
--- a/src/client/script_inst.c
+++ b/src/client/script_inst.c
@@ -24,6 +24,7 @@
 #include "perms.h"
 #include "main.h"
 #include "user.h"
+#include "mesg.h"
 
 extern struct person *user;
 extern long userposn;
@@ -83,9 +84,7 @@ Instruction inst_table[]={
 { "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 },
@@ -610,120 +609,6 @@ void scr_print( struct code *pc, int fargc, char **fargv )
 	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;
@@ -2364,12 +2249,12 @@ void scr_sendipc( struct code *pc, int fargc, char **fargv )
 {
 	int i, size, count;
 	char *tmp, *p, *text;
-	int broadcast = 0;
+	int bcast = 0;
 	int startarg;
 
-	if (!strcasecmp(pc->inst->name, "sendipb")) broadcast = 1;
+	if (!strcasecmp(pc->inst->name, "sendipb")) bcast = 1;
 
-	if (broadcast) {
+	if (bcast) {
 		if (pc->argc < 1) return;
 		startarg = 0;
 	} else {
@@ -2398,7 +2283,7 @@ void scr_sendipc( struct code *pc, int fargc, char **fargv )
 
 	text = eval_arg(pc->argv[0], fargc, fargv);
 
-	sendipc(text,tmp,broadcast);
+	sendipc(text,tmp,bcast);
 
 	free(text);
 	free(tmp);
@@ -2408,12 +2293,12 @@ void scr_sendrpc( struct code *pc, int fargc, char **fargv )
 {
 	int i, size, count;
 	char *text, *p, *sendto, *msg;
-	int broadcast = 0;
+	int bcast = 0;
 	int startarg;
 
-	if (!strcasecmp(pc->inst->name, "sendrpb")) broadcast = 1;
+	if (!strcasecmp(pc->inst->name, "sendrpb")) bcast = 1;
 
-	if (broadcast) {
+	if (bcast) {
 		if (pc->argc < 2) return;
 		startarg = 1;
 	} else {
@@ -2440,7 +2325,7 @@ void scr_sendrpc( struct code *pc, int fargc, char **fargv )
 		free(p);
 	}
 
-	if (broadcast)
+	if (bcast)
 	{
 		sendto = strdup("");
 		msg = eval_arg(pc->argv[0], fargc, fargv);
@@ -2451,7 +2336,7 @@ void scr_sendrpc( struct code *pc, int fargc, char **fargv )
 		msg = eval_arg(pc->argv[1], fargc, fargv);
 	}
 
-	sendrpc(sendto,msg,text,broadcast);
+	sendrpc(sendto,msg,text,bcast);
 
 	free(text);
 	free(msg);


=====================================
src/client/script_inst.h
=====================================
--- a/src/client/script_inst.h
+++ b/src/client/script_inst.h
@@ -27,7 +27,6 @@ void scr_math( struct code *, int, char **);
 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 **);


=====================================
src/client/talker.c
=====================================
--- a/src/client/talker.c
+++ b/src/client/talker.c
@@ -31,6 +31,8 @@
 #include "userio.h"
 #include "user.h"
 #include "who.h"
+#include "mesg.h"
+#include "incoming.h"
 
 #include "alias.h"
 extern Alias bind_list;
@@ -54,9 +56,6 @@ static int runautoexec = 1;
 
 extern struct room myroom;
 
-/* ignore list for current user */
-extern struct IgnoreList *ignored;
-
 extern CommandList table[];
 extern CommandList chattable[];
 
@@ -187,12 +186,13 @@ int screen_w(void)
 
 void t_who(CommandList *cm, int argc, const char **argv, char *args)
 {
-	who_list(0);
+	display_wholist(0);
 }
 
 void t_what(CommandList *cm, int argc, const const char **argv, char *args)
 {
-	who_list(1);
+	//who_list(1);
+	display_wholist(1);
 }
 
 void t_uptime(CommandList *cm, int argc, const const char **argv, char *args)
@@ -905,212 +905,6 @@ void t_ungag(CommandList *cm, int argc, const char **argv, char *args)
 	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;
- 
-	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;
-		}
-	}
-}
- 
-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);
-}
- 
-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);
@@ -1408,27 +1202,11 @@ void set_talk_rights(void)
 	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) 
+void sendipc(char *to, char *text, int bcast) 
 {
 	int count;
 
-	if (broadcast) 
+	if (bcast) 
 	{
 		count = ipc_send_to_all(IPC_SCRIPTIPC, text);
 	}
@@ -1441,20 +1219,20 @@ void sendipc(char *to, char *text, int broadcast)
 		printf("User '%s' is not logged on.\n",to);
 	}else
 	{
-		if (broadcast)
+		if (bcast)
 			mwlog("SENDIPB %s", text);
 		else
 			mwlog("SENDIPC(%s) %s",to,text);
 	}
 }
 
-void sendrpc(char *to, char *type, char *text, int broadcast) 
+void sendrpc(char *to, char *type, char *text, int bcast) 
 {
 	char buff[MAXTEXTLENGTH];
 	int count;
 
 	snprintf(buff, MAXTEXTLENGTH, "%s %s", type, text);
-	if(broadcast)
+	if(bcast)
 	{
 		count = ipc_send_to_all(IPC_SCRIPTRPC, buff); 
 	}
@@ -1467,7 +1245,7 @@ void sendrpc(char *to, char *type, char *text, int broadcast)
 		printf("User '%s' is not logged on.\n",to);
 	}else
 	{
-		if (broadcast)
+		if (bcast)
 			mwlog("SENDRPB(%s) %s", type, text);
 		else
 			mwlog("SENDRPC(%s, %s) %s", to, type, text);
@@ -1495,7 +1273,7 @@ void enter_talker(int logontype)
 	if (autowho)
 	{
 		update_user(user,userposn);
-		who_list(0);
+		display_wholist(0);
 		/* turn off the autowho, so it only occurs on first usage */
 		autowho = 0;
 	}


=====================================
src/client/talker.h
=====================================
--- a/src/client/talker.h
+++ b/src/client/talker.h
@@ -43,9 +43,6 @@ void t_mrod(CommandList *cm, int argc, const char **argv, char *args);
 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);
@@ -78,8 +75,6 @@ void enter_talker(int logontype);
 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);
 


=====================================
src/client/user.c
=====================================
--- a/src/client/user.c
+++ b/src/client/user.c
@@ -362,7 +362,6 @@ void login_ok(struct person *usr, int32_t *userposn, int *autochat)
 		else
 			okay=new_usr(usr,name,userposn);
 	}while (!okay);
-	check_copies(*userposn); 	
 }
 
 void list_users(int newonly) 


=====================================
src/client/who.c
=====================================
--- a/src/client/who.c
+++ b/src/client/who.c
@@ -22,10 +22,13 @@
 #include "userio.h"
 #include "who.h"
 #include "main.h"
+#include <str_util.h>
+#include <util.h>
 
 extern int busy;
 extern struct person *user;
 extern struct room myroom;
+extern long userposn;
 
 /* called only by cmdline flags */
 void what_list(void) {
@@ -48,276 +51,193 @@ void what_list(void) {
 	close(ufile);
 }
 
-void who_list(int mode)
+char *itime(unsigned long t)
 {
-	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++;
+	static char out[7];
 
-	wfile=who_open(O_RDWR);
-	ufile=userdb_open(O_RDONLY);
-	if (wfile<0 || ufile<0) return; /* whoops */
+	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);
+}
 
-	/* do we tell them who can hear wiz messages */
-	if (s_wizchat(user->special)) wizchat=1; else wizchat=0;
+#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;
+	}
 
-	if (mode==1) 
+	busy++;
+	if (mode == 1)
 		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");
+		format_message("\nPID    %-*s %-*s  Idle  What...",NAMESIZE,"Name",20,"RealName");
 
-	divider = NULL;
+	AUTOFREE_BUFFER divider = NULL;
 	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);
-			}
-			}
+	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);
 		}
 	}
 	format_message("%s", divider);
-	close(wfile);
-	close(ufile);
-
-	free(divider);
-
 	busy--;
 }
 
-int32_t get_who_userposn(int pid)
+void update_wholist(ipc_message_t *msg)
 {
-	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;
-		}
+	/* 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;
 	}
-	close(wfile);
-	
-	return(found);
 }
 
-#ifdef RWHO
-void rwho_update(void)
+char *part_who(const char *text, int status)
 {
-	static int setup=0;
-	static long t=0;
-
-	if (!setup)
-	{
-		setup=1;
-		rwhocli_setup("137.44.12.4","frodperfect","Milliways","THE Bulletin Board");
+	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);
 	}
-	if (time(0)-t>240)
-	{
-		t=time(0);
-		rwhocli_pingalive();
-		rwho_list();
+
+	/* we dont even have stale info */
+	if (whoinfo == NULL) return(NULL);
+
+	/* start a new search */
+	if (status == 0) {
+		len = strlen(text);
+		index = 0;
 	}
-}
 
-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);
+	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,"");
 			}
+			/* found one we dont want */
+			count++;
 		}
 	}
-	close(wfile);
-	close(ufile);
+	/* run out of answers */
+	return NULL;
 }
 
-#endif
-
-void check_copies(int32_t where)
+char *part_who_talk(const char *text, int status)
 {
-	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++;
-		}
+	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);
 	}
 
-	if (count==1)
-	{
-		printf("You are already logged in.\n");
-	}else
-	if (count>1)
-	{
-		printf("You are already logged in %d times.\n",count);
+	/* we dont even have stale info */
+	if (whoinfo == NULL) return(NULL);
+
+	/* start a new search */
+	if (status == 0) {
+		len = strlen(text);
+		index = 0;
 	}
-	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");
+
+	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++;
 		}
 	}
-	close(file);
+	/* run out of answers */
+	return NULL;
 }
 
-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);
-}


=====================================
src/client/who.h
=====================================
--- a/src/client/who.h
+++ b/src/client/who.h
@@ -2,11 +2,14 @@
 #define CLIENT_WHO_H
 
 #include <stdint.h>
+#include <ipc.h>
 
 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);
+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);
 
 #endif /* CLIENT_WHO_H */


=====================================
src/ipc.c
=====================================
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -179,7 +179,6 @@ const char * ipc_nametype(enum ipc_types msgtype)
 		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;
@@ -195,6 +194,7 @@ const char * ipc_nametype(enum ipc_types msgtype)
 		case IPC_REPLAY: return "IPC_REPLAY"; break;
 		case IPC_EVENT: return "IPC_EVENT"; break;
 		case IPC_ACTION: return "IPC_ACTION"; break;
+		case IPC_WHOLIST: return "IPC_WHOLIST"; break;
 	}
 	return "IPC_Unknown";
 }


=====================================
src/ipc.h
=====================================
--- a/src/ipc.h
+++ b/src/ipc.h
@@ -36,7 +36,6 @@ enum ipc_types {
 	IPC_CHANNEL	= 16,
 	IPC_WIZ		= 17,
 	IPC_GAG		= 18,
-	IPC_CLEARIGN	= 19,
 	IPC_SCRIPTIPC	= 21,
 	IPC_SCRIPTRPC	= 22,
 	IPC_CHECKONOFF	= 23,
@@ -51,7 +50,8 @@ enum ipc_types {
 	IPC_TALKERROR	= FCC('TERR'),
 	IPC_REPLAY      = FCC('PLAY'),
 	IPC_EVENT	= FCC('EVNT'),
-	IPC_ACTION	= FCC('ACTN')
+	IPC_ACTION	= FCC('ACTN'),
+	IPC_WHOLIST	= FCC('WHOL')
 };
 
 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))


=====================================
src/perms.c
=====================================
--- a/src/perms.c
+++ b/src/perms.c
@@ -229,39 +229,6 @@ void show_fold_groups(char st, char *tmp, int flag)
 	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)


=====================================
src/perms.h
=====================================
--- a/src/perms.h
+++ b/src/perms.h
@@ -4,8 +4,6 @@
 #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);
 


=====================================
src/server/PROTOCOL
=====================================
--- a/src/server/PROTOCOL
+++ b/src/server/PROTOCOL
@@ -116,17 +116,20 @@ IPC_ACTION - user requests an action
 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
+		pid	 - session id
 		id	 - user id
 		name     - username
 		realname - users actual name (if permitted)
-		idle	 - seconds idle
+		idletime - idle time
 		doing    - doing info
 		dowhen   - when doing last updated
+		channel  - Current (primary?) channel
 		perms    - object of permissions
-			chatmode
-			chatprivs
-			protection
+		    status
+		    chatmode
+		    chatprivs
+		    protection
+		    wizchat
 
 
 all other codes are old unformatted messages and are to be phased out,


=====================================
src/server/servsock.c
=====================================
--- a/src/server/servsock.c
+++ b/src/server/servsock.c
@@ -10,6 +10,7 @@
 #include <arpa/inet.h>
 #include <stdlib.h>
 #include <sys/time.h>
+#include <stdbool.h>
 #include <time.h>
 
 #include <socket.h>
@@ -23,6 +24,8 @@
 #include "replay.h"
 #include "actions.h"
 #include <gags.h>
+#include <perms.h>
+#include <special.h>
 
 struct list_head connection_list;
 
@@ -133,6 +136,10 @@ void drop_connection(ipc_connection_t * conn)
 	}
 	bzero(conn, sizeof(ipc_connection_t));
 	free(conn);
+
+	ipc_message_t * whoinfo = msg_wholist();
+	msg_attach_to_all(whoinfo);
+	ipcmsg_destroy(whoinfo);
 }
 
 void watch_mainsock(int mainsock)
@@ -288,6 +295,10 @@ void process_msg(ipc_connection_t *conn, ipc_message_t *msg)
 		close(wfd);
 		conn->state = IPCSTATE_VALID;
 		ipcmsg_destroy(msg);
+
+		ipc_message_t * whoinfo = msg_wholist();
+		msg_attach_to_all(whoinfo);
+		ipcmsg_destroy(whoinfo);
 		return;
 	}
 
@@ -327,6 +338,14 @@ void process_msg(ipc_connection_t *conn, ipc_message_t *msg)
 		return;
 	}
 
+	if (msg->head.type == IPC_WHOLIST) {
+		ipc_message_t * whoinfo = msg_wholist();
+		msg_attach(whoinfo, conn);
+		ipcmsg_destroy(whoinfo);
+		ipcmsg_destroy(msg);
+		return;
+	}
+
 	/**** end of messages to the server
 	 *    all below this point are intended to be retransmitted
 	 */
@@ -592,3 +611,51 @@ void init_server()
 		pollfd = epoll_create(30);
 	}
 }
+
+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;
+}


=====================================
src/server/servsock.h
=====================================
--- a/src/server/servsock.h
+++ b/src/server/servsock.h
@@ -19,4 +19,6 @@ void msg_attach(ipc_message_t *msg, ipc_connection_t *conn);
 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);
+ipc_message_t * msg_wholist(void);
+
 #endif /* SERVSOCK_H */


=====================================
src/socket.c
=====================================
--- a/src/socket.c
+++ b/src/socket.c
@@ -339,6 +339,15 @@ int json_addint(json_t * js, const char * key, int value)
 	return 0;
 }
 
+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;
+}
+
 const char * json_getstring(json_t * js, const char * key)
 {
 	json_t * tmp;


=====================================
src/socket.h
=====================================
--- a/src/socket.h
+++ b/src/socket.h
@@ -80,6 +80,7 @@ int ipcmsg_json_encode(ipc_message_t *msg, json_t *js);
 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);
+int json_addobject(json_t *js, const char *key, json_t * obj);
 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);


=====================================
src/webclient/Makefile
=====================================
--- a/src/webclient/Makefile
+++ b/src/webclient/Makefile
@@ -6,7 +6,7 @@ CFLAGS+= -I.. -I/usr/include/postgresql
 
 build: mwpoll
 
-mwpoll: mwpoll.o import.o comms.o mwstring.o ../libmw.a
+mwpoll: mwpoll.o import.o comms.o mwstring.o ../libmw.a 
 	$(CC) $(LDFLAGS) $(LDLIBS) -o $@ $^
 
 clean:


=====================================
src/webclient/comms.c
=====================================
--- a/src/webclient/comms.c
+++ b/src/webclient/comms.c
@@ -69,6 +69,8 @@ struct list_head connlist;
 char * json_escape(char *in);
 static void handle_mesg(void);
 
+void mwlog(const char *fmt, ...) __attribute__((format(printf,1,2)));
+
 /* unix socket to accept control commands from */
 void open_command_socket()
 {
@@ -579,3 +581,35 @@ void create_user(struct person *me, int *userposn, const char *username, const c
 	}
 	userdb_write(me, userposn);
 }
+
+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);
+}
+


=====================================
src/who.c
=====================================
--- a/src/who.c
+++ b/src/who.c
@@ -83,3 +83,4 @@ long who_find(const char * username)
 
 	return where;
 }
+



View it on GitLab: https://projects.sucs.org/arthur/mw/commit/c4d8ec597f6369636ce5a960f4cec91c8a929fe5
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sucs.org/pipermail/mw-devel/attachments/20151007/af709008/attachment-0001.html>


More information about the mw-devel mailing list