[mw-devel] [Git][arthur/mw][master] Remove the last of the references to who file from main client

Justin Mitchell arthur at sucs.org
Wed Oct 7 17:16:41 BST 2015


Justin Mitchell pushed to branch master at Justin Mitchell / mw


Commits:
b5193749 by Justin Mitchell at 2015-10-07T17:15:47Z
Remove the last of the references to who file from main client

- - - - -


7 changed files:

- src/client/js.c
- src/client/script_inst.c
- src/client/who.c
- src/client/who.h
- src/gags.c
- src/str_util.c
- src/str_util.h


Changes:

=====================================
src/client/js.c
=====================================
--- a/src/client/js.c
+++ b/src/client/js.c
@@ -8,6 +8,8 @@
 #include <pwd.h>
 #include <readline/readline.h>
 #include <curl/curl.h>
+#include <jansson.h>
+#include "who.h"
 
 /* Ugly but necessary (this is how gjs shuts up the warnings,
    only gcc 4.6 has a nicer (push/pop) way to do it */
@@ -655,63 +657,63 @@ static JSBool js_termsize(JSContext *cx, unsigned int argc, jsval *vp)
 
 // Provides a javascript function to query the wholist
 static JSBool js_wholist(JSContext *cx, unsigned int argc, jsval *vp) {
-	struct person u;
-	struct who w;
-	int ufile, wfile;
 	JSObject *res;
 	int n=0;
 
-	wfile=who_open(O_RDWR);
-	ufile=userdb_open(O_RDONLY);
-	if (wfile<0 || ufile<0) {
-		JS_ReportError(cx, "wholist() could not open userdb.");
-	
+	json_t * wlist = grab_wholist();
+	if (wlist == NULL) {
+		JS_ReportError(cx, "Could not grab wholist, try again");
 		return JS_FALSE;
 	}
+
 	res = JS_NewArrayObject(cx, 0, NULL);
 	JS_AddObjectRoot(cx, &res);
 
-	while (read(wfile,&w,sizeof(w))) {
+	size_t wi;
+	json_t *entry;
+	time_t now = time(0);
+	json_array_foreach(wlist, wi, entry) {
+		json_t * perms = json_object_get(entry, "perms");
+
 		JSObject *user_record;
 		JSString *jsstr;
 		jsval jv, user_jv;
 
-		if (w.posn < 0) continue;
-		lseek(ufile,w.posn,SEEK_SET);
-		read(ufile,&u,sizeof(u));
-
 		/* make a new row and populate it */
 		user_record = JS_NewObject(cx, &js_userrecordclass, NULL, NULL);
 		user_jv = OBJECT_TO_JSVAL(user_record);
 		/* user name */
-		jsstr = JS_NewStringCopyZ(cx, u.name);
+		jsstr = JS_NewStringCopyZ(cx, json_getstring(entry, "name"));
 		jv = STRING_TO_JSVAL(jsstr);
 		JS_DefineProperty(cx, user_record, "username", jv, NULL, NULL, 0);
 		/* room number */
-		jv = INT_TO_JSVAL(u.room);
+		jv = INT_TO_JSVAL( json_getint(entry, "channel") );
 		JS_DefineProperty(cx, user_record, "room", jv, NULL, NULL, 0);
 		/* idle time */
-		jv = INT_TO_JSVAL(time(0)-u.idletime);
+		jv = INT_TO_JSVAL(now - json_getint(entry, "idletime"));
 		JS_DefineProperty(cx, user_record, "idle", jv, NULL, NULL, 0);
 		/* chat modes */
-		jsstr = JS_NewStringCopyZ(cx, display_cmflags(u.chatmode));
+		jsstr = JS_NewStringCopyZ(cx, json_getstring(entry, "chatmode"));
 		jv = STRING_TO_JSVAL(jsstr);
 		JS_DefineProperty(cx, user_record, "chatmodes", jv, NULL, NULL, 0);
 		/* protection level */
-		jv = INT_TO_JSVAL((u.chatmode & CM_PROTMASK) >> CM_PROTSHIFT);
+		const char * prot = json_getstring(perms, "protection");
+		jv = INT_TO_JSVAL( prot[0] - '0');
 		JS_DefineProperty(cx, user_record, "protection_level", jv, NULL, NULL, 0);
-		jv = INT_TO_JSVAL((u.chatprivs & CP_PROTMASK) >> CP_PROTSHIFT);
+		jv = INT_TO_JSVAL( prot[2] - '0');
 		JS_DefineProperty(cx, user_record, "protection_power", jv, NULL, NULL, 0);
-		/* chat privs */
-		jsstr = JS_NewStringCopyZ(cx, display_cpflags(u.chatprivs & user->chatprivs));
+		/* chat perms */
+		jsstr = JS_NewStringCopyZ(cx, json_getstring(perms, "chatprivs") );
 		jv = STRING_TO_JSVAL(jsstr);
 		JS_DefineProperty(cx, user_record, "chatprivs", jv, NULL, NULL, 0);
 		/* status string */
-		jsstr = JS_NewStringCopyZ(cx, u.doing);
+		jsstr = JS_NewStringCopyZ(cx, json_getstring(entry, "doing"));
 		jv = STRING_TO_JSVAL(jsstr);
 		JS_DefineProperty(cx, user_record, "doing", jv, NULL, NULL, 0);
-		if (u.dowhen)
-			jv = INT_TO_JSVAL(time(0)-u.dowhen);
+
+		int dowhen = json_getint(entry, "dowhen");
+		if (dowhen)
+			jv = INT_TO_JSVAL(now - dowhen);
 		else
 			jv = INT_TO_JSVAL(0);
 		JS_DefineProperty(cx, user_record, "since", jv, NULL, NULL, 0);
@@ -719,11 +721,10 @@ static JSBool js_wholist(JSContext *cx, unsigned int argc, jsval *vp) {
 		/* stick line into master array */
 		JS_SetElement(cx, res, n++, &user_jv);
 	}
-	close(wfile);
-	close(ufile);
 
 	JS_RemoveObjectRoot(cx, &res);
 	JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(res));
+	json_decref(wlist);
 	return JS_TRUE;
 }
 


=====================================
src/client/script_inst.c
=====================================
--- a/src/client/script_inst.c
+++ b/src/client/script_inst.c
@@ -25,6 +25,8 @@
 #include "main.h"
 #include "user.h"
 #include "mesg.h"
+#include "util.h"
+#include "who.h"
 
 extern struct person *user;
 extern long userposn;
@@ -139,8 +141,9 @@ Instruction inst_table[]={
 
 void scr_time( struct code *pc, int fargc, char **fargv )
 {
-	char *what;
-	char value[MAXTEXTLENGTH];
+	AUTOFREE_BUFFER what = NULL;
+	AUTOFREE_BUFFER value = NULL;
+	time_t now = time(0);
 
 	if (pc->argc < 1) {
 		if (script_debug) printf("Error in %s at %s too few arguments.\n", pc->inst->name, pc->debug);
@@ -150,31 +153,23 @@ void scr_time( struct code *pc, int fargc, char **fargv )
 
 	if (!strcasecmp(pc->inst->name, "unixtime"))
 	{
-		snprintf(value,MAXTEXTLENGTH-1,"%d",(int)time(NULL));
+		string_add(&value, "%ld", now);
 	}
 	else if (!strcasecmp(pc->inst->name, "idletime"))
 	{
-		snprintf(value, MAXTEXTLENGTH - 1, "%ld", (long)time(0) - user->idletime);
-		if (script_debug) printf("- Idle time is %ld\n", (long)time(0) - user->idletime);
+		string_add(&value, "%ld", now - user->idletime);
+		if (script_debug) printf("- Idle time is %ld\n", now - user->idletime);
 	}
 	else if (!strcasecmp(pc->inst->name, "useridle"))
 	{
-		struct person u2;
-		struct who w;
-		int ufile,wfile;
-		char *uname;
-
-		uname=eval_arg(pc->argv[1], fargc, fargv);
+		AUTOFREE_BUFFER uname = eval_arg(pc->argv[1], fargc, fargv);
 
 		if (script_debug) escprintf("- %s: Getting idletime of user '%s'.\n", pc->inst->name, uname); 
 
-		wfile=who_open(O_RDWR);
-		ufile=userdb_open(O_RDONLY);
-		if (wfile<0 || ufile<0)
+		json_t * wlist = grab_wholist();
+		if (wlist == NULL)
 		{
 			/* hideous problems with user info files */
-			free(what);
-			free(uname);
 			printf("- %s: Can't open user/who information files\n", pc->inst->name);
 			return;
 		}
@@ -182,36 +177,25 @@ void scr_time( struct code *pc, int fargc, char **fargv )
 		/* set default idle time to zero */
 		snprintf(value, MAXTEXTLENGTH - 1, "0");
 
-		while (read(wfile,&w,sizeof(w)))
-		{
-			/* Skip invalid entries */
-			if (w.posn < 0)
-				continue;
-
-			lseek(ufile,w.posn,0);
-			read(ufile,&u2,sizeof(u2));
+		size_t wi;
+		json_t *entry;
+		json_array_foreach(wlist, wi, entry) {
+			const char *name = json_getstring(entry, "name");
+			time_t idletime = json_getint(entry, "idletime");
 
-			if (!strcasecmp(u2.name, uname))
+			if (!strcasecmp(name, uname))
 			{
-				/* check they are still alive and show info */
-				if (w.pid>-1 )
-				{
-					snprintf(value, MAXTEXTLENGTH - 1, "%ld", (long)time(0) - u2.idletime);
-					if (script_debug) printf("- %s: Idletime is %ld\n", pc->inst->name, (long)time(0) - u2.idletime);
-				}
+				snprintf(value, MAXTEXTLENGTH - 1, "%ld", now - idletime);
+				if (script_debug) printf("- %s: Idletime is %ld\n", pc->inst->name, now - idletime);
 			}
 		}
-		free(uname);
-		close(wfile);
-		close(ufile);
+		json_decref(wlist);
 	}
 	else if (!strcasecmp(pc->inst->name, "whenami"))
 	{
-		time_t t;
 		struct tm *tt;
 
-		t=time(0);
-		tt=localtime(&t);
+		tt=localtime(&now);
 		strftime(value, MAXTEXTLENGTH-1, "%H:%M", tt);
 	}
 	else if (!strcasecmp(pc->inst->name, "date"))
@@ -224,16 +208,16 @@ void scr_time( struct code *pc, int fargc, char **fargv )
 		t = localtime(&oldt);
 
 		/* print date information into the string in the format "dd/mm/yyyy HH:MM:SS" */
-		snprintf(value, MAXTEXTLENGTH - 1, "%02d/%02d/%04d %02d:%02d:%02d", t->tm_mday, t->tm_mon + 1, t->tm_year + 1900, t->tm_hour, t->tm_min, t->tm_sec);
+		string_add(&value, "%02d/%02d/%04d %02d:%02d:%02d", t->tm_mday, t->tm_mon + 1, t->tm_year + 1900, t->tm_hour, t->tm_min, t->tm_sec);
 	}
 	var_str_force_2(what, value);
-	free(what);
 }
 
 void scr_say( struct code *pc, int fargc, char **fargv )
 {
 	int i, size, count;
-	char *tmp, *p;
+	AUTOFREE_BUFFER tmp = NULL;
+	AUTOFREE_BUFFER p = NULL;
 	char utf8buff[MAXTEXTLENGTH];
 	int conversion_result;
 	
@@ -257,7 +241,6 @@ void scr_say( struct code *pc, int fargc, char **fargv )
 		count+=strlen(p);
 		if (count>=size) { size=count+512; tmp=realloc(tmp, size); }
 		strcat(tmp, p);
-		free(p);
 	}
 
 	flood++;
@@ -265,7 +248,6 @@ void scr_say( struct code *pc, int fargc, char **fargv )
 	{
 		printf("FLOOD: This script has flooded the room. Terminating.\n");
 		script_terminate = 2;
-		free(tmp);
 		return;
 	}
 
@@ -273,13 +255,11 @@ void scr_say( struct code *pc, int fargc, char **fargv )
 	if(conversion_result < 0)
 	{
 		printf("Error %d occured trying to clean up the script output.\n", conversion_result);
-		free(tmp);
 		return;
 	}
 	if(conversion_result & WINVALIDCHARS)
 	{
 		printf("Error: Your script produced invalid utf-8 which has not been sent.\n");
-		free(tmp);
 		return;
 	}		
 	if(conversion_result & WOUTPUTTOOSHORT)
@@ -305,7 +285,6 @@ void scr_say( struct code *pc, int fargc, char **fargv )
 	{
 		talk_send_raw(utf8buff, user->room);
 	}
-	free(tmp);
 }
 
 void scr_beep( struct code *pc, int fargc, char **fargv )
@@ -320,7 +299,7 @@ void scr_showrunaway( struct code *pc, int fargc, char **fargv )
 
 void scr_output( struct code *pc, int fargc, char **fargv )
 {
-	char *what;
+	AUTOFREE_BUFFER what = NULL;
 	int i;
 
 	if (event_user==NULL)
@@ -340,51 +319,36 @@ void scr_output( struct code *pc, int fargc, char **fargv )
 		if (script_debug) printf("- OUTPUT: Error, invalid argument\n");
 	}
 	else script_output = i;
-
-	free(what);
 }
 
 void scr_wholist( struct code *pc, int fargc, char **fargv )
 {
-	struct person u2;
-	struct who w;
-	int ufile,wfile;
-	char *what;
-	char buff[2048];
+	AUTOFREE_BUFFER what = NULL;
+	AUTOFREE_BUFFER buff = NULL;
 	
 	if (pc->argc < 1) {
 		if (script_debug) printf("Error in %s at %s too few arguments.\n", pc->inst->name, pc->debug);
 		return;
 	}
-	what=eval_arg(pc->argv[0], fargc, fargv);
+	what = eval_arg(pc->argv[0], fargc, fargv);
 
-	wfile=who_open(O_RDWR);
-	ufile=userdb_open(O_RDONLY);
-	if (wfile<0 || ufile<0) return; /* whoops */
+	json_t * wlist = grab_wholist();
+	if (wlist == NULL) return;
 
-	buff[0] = 0;
+	size_t wi;
+	json_t *entry;
+	json_array_foreach(wlist, wi, entry) {
+		json_t * perms = json_object_get(entry, "perms");
+		const char *name = json_getstring(entry, "name");
+		const char *chatmode = NULL;
+		if (perms!=NULL) chatmode=json_getstring(perms, "chatmode");
 
-	while (read(wfile,&w,sizeof(w)))
-	{
-		/* Skip invalid entries */
-		if (w.posn < 0)
-			continue;
-
-		lseek(ufile,w.posn,0);
-		read(ufile,&u2,sizeof(u2));
-
-		/* check they are still alive and show info */
-		if (w.pid>-1 )
+		if (chatmode != NULL && strchr(chatmode, 'c')!=NULL)
 		{
-			if (cm_flags(u2.chatmode,CM_ONCHAT,CM_MODE_ANY))
-			{
-				strcat(buff, u2.name);
-				strcat(buff, " ");
-			}
+			string_add(&buff, "%s ", name);
 		}
 	}
-	close(wfile);
-	close(ufile);
+	json_decref(wlist);
 	
 	{
 		char *p;
@@ -392,12 +356,11 @@ void scr_wholist( struct code *pc, int fargc, char **fargv )
 	}
 
 	var_str_force_2(what, buff);
-	free(what);
 }
 
 void scr_roomnum( struct code *pc, int fargc, char **fargv )
 {
-	char *what;
+	AUTOFREE_BUFFER what = NULL;
 	char rn[10];
 
 	/* set initial room to -1 for unknown */
@@ -439,53 +402,34 @@ void scr_roomnum( struct code *pc, int fargc, char **fargv )
 	}
 	else if (!strcasecmp(pc->inst->name, "userroom"))
 	{
-		struct person u2;
-		struct who w;
-		int ufile,wfile;
-		char *uname;
+		AUTOFREE_BUFFER uname = NULL;
 		int rnum = -1;
 
 		uname=eval_arg(pc->argv[1], fargc, fargv);
 
 		if (script_debug) escprintf("- %s: Getting room of user '%s'.\n", pc->inst->name, uname); 
 
-		wfile=who_open(O_RDWR);
-		ufile=userdb_open(O_RDONLY);
-		if (wfile<0 || ufile<0)
-		{
-			/* hideous problems with user info files */
-			free(what);
-			free(uname);
-			printf("- %s: Can't open user/who information files\n", pc->inst->name);
-			return;
+		json_t * wlist = grab_wholist();
+		if (wlist == NULL) return;
+
+		size_t wi;
+		json_t *entry;
+		json_array_foreach(wlist, wi, entry) {
+			json_t * perms = json_object_get(entry, "perms");
+			const char *name = json_getstring(entry, "name");
+			const char *chatmode = NULL;
+			if (perms!=NULL) chatmode=json_getstring(perms, "chatmode");
+			int room = json_getint(entry, "room");
+
+			/* wrong person */
+			if (strcasecmp(name, uname)!=0) continue;
+			/* wasnt on chat */
+			if (chatmode != NULL && strchr(chatmode, 'c')==NULL) continue;
+			rnum = room;
 		}
+		json_decref(wlist);
 
-		while (read(wfile,&w,sizeof(w)))
-		{
-			/* Skip invalid entries */
-			if (w.posn < 0)
-				continue;
-
-			lseek(ufile,w.posn,0);
-			read(ufile,&u2,sizeof(u2));
-
-			if (!strcasecmp(u2.name, uname))
-			{
-				/* check they are still alive and show info */
-				if (w.pid>-1 )
-				{
-					/* do validity checks */
-					if (cm_flags(u2.chatmode,CM_ONCHAT,CM_MODE_ANY))
-					{
-						rnum = u2.room;
-						snprintf(rn, 9, "%d", rnum);
-					}
-				}
-			}
-		}
-		free(uname);
-		close(wfile);
-		close(ufile);
+		snprintf(rn, 9, "%d", rnum);
 	}
 
 	var_str_force_2(what, rn);
@@ -494,15 +438,15 @@ void scr_roomnum( struct code *pc, int fargc, char **fargv )
 
 void scr_talkpriv( struct code *pc, int fargc, char **fargv )
 {
-	char *what;
-	char *buff;
+	AUTOFREE_BUFFER what = NULL;
+	AUTOFREE_BUFFER buff = NULL;
 	unsigned long mask = 0xffffffff;
 
 	if (pc->argc < 1) {
 		if (script_debug) printf("Error in %s at %s too few arguments.\n", pc->inst->name, pc->debug);
 		return;
 	}
-	what=eval_arg(pc->argv[0], fargc, fargv);
+	what = eval_arg(pc->argv[0], fargc, fargv);
 
 	/* Empty string "" means no privs. For every extra priv/mode available, the following character is added:
 	 *  T     - Timestamps enabled
@@ -514,14 +458,12 @@ void scr_talkpriv( struct code *pc, int fargc, char **fargv )
 
 	mask &= ~(CM_ONCHAT);
 	mask &= ~(CM_STICKY);
-	if (s_timestamp(user->special)) buff = strdup("T"); else buff = strdup("");
+	if (s_timestamp(user->special)) string_add(&buff, "T");
 	if (!u_beep(user->status)) string_add(&buff, "B");
 	if (u_god(user->status)) string_add(&buff, "S");
-	string_add(&buff, display_cmflags(user->chatmode & mask));
+	string_add(&buff, "%s", display_cmflags(user->chatmode & mask));
 
 	var_str_force_2(what, buff);
-	free(what);
-	free(buff);
 }
 
 void scr_quit( struct code *pc, int fargc, char **fargv )
@@ -667,7 +609,8 @@ int isanumul(const char *a, unsigned long *result, int onlydecimal)
 
 void scr_compare( struct code *pc, int fargc, char **fargv ) 
 {
-	char *a, *b;
+	AUTOFREE_BUFFER a = NULL;
+	AUTOFREE_BUFFER b = NULL;
 	int aa=0, bb=0;
 	int numeric=0;
 
@@ -739,14 +682,13 @@ void scr_compare( struct code *pc, int fargc, char **fargv )
 			if (strcasecmp(a,b) >=0) compare_match++;
 		}
 	}
-	free(a);
-	free(b);
 }
 
 void scr_math( struct code *pc, int fargc, char **fargv )
 {
 	int a, b;
-	char *aa, *bb;
+	AUTOFREE_BUFFER aa = NULL;
+	AUTOFREE_BUFFER bb = NULL;
 	var_op_t var;
 	int result=0;
 
@@ -760,7 +702,6 @@ void scr_math( struct code *pc, int fargc, char **fargv )
 	if (!eval_var(aa, &var))
 	{
 		scr_devel_msg(pc, "Invalid variable name '%s'", aa);
-		free(aa);
 	}
 
 	if (!VAR_FOUND(&var)) {
@@ -775,15 +716,11 @@ void scr_math( struct code *pc, int fargc, char **fargv )
 	}else
 	{ /* looks like their not numbers, cant math strings */
 		if (script_debug) escprintf("- math: either $%s (%s) or '%s' were not numbers\n", aa, var_str_val(&var), bb);
-		free(aa);
-		free(bb);
 		VAR_KEY_FREE(&var);
 		return;
 	}
-	free(bb);
 
 	if (script_debug) escprintf("- math operation on $%s (%d) and %d\n", aa, a, b);
-	free(aa);
 	
 	if (!strcasecmp(pc->inst->name, "add"))
 		result = a+b;
@@ -819,7 +756,8 @@ void scr_math( struct code *pc, int fargc, char **fargv )
 void scr_math2( struct code *pc, int fargc, char **fargv )
 {
 	int a;
-	char *aa, *bb;
+	AUTOFREE_BUFFER aa = NULL;
+	AUTOFREE_BUFFER bb = NULL;
 	var_op_t var;
 	int result=0;
 
@@ -833,7 +771,6 @@ void scr_math2( struct code *pc, int fargc, char **fargv )
 	if (!eval_var(aa, &var))
 	{
 		scr_devel_msg(pc, "Invalid variable name '%s'", aa);
-		free(aa);
 	}
 
 	if (!VAR_FOUND(&var)) {
@@ -849,15 +786,11 @@ void scr_math2( struct code *pc, int fargc, char **fargv )
 	{
 		/* looks like arg2 is not a number, cant math string */
 		if (script_debug) escprintf("- math: '%s' is not a number\n", bb);
-		free(aa);
-		free(bb);
 		VAR_KEY_FREE(&var);
 		return;
 	}
-	free(bb);
 
 	if (script_debug) printf("- math operation on %d\n", a);
-	free(aa);
 	
 	if (!strcasecmp(pc->inst->name, "abs"))
 	{
@@ -870,7 +803,7 @@ void scr_math2( struct code *pc, int fargc, char **fargv )
 
 void scr_sleep( struct code *pc, int fargc, char **fargv )
 {
-	char	*aa;
+	AUTOFREE_BUFFER	aa = NULL;
 	int	a;
 	struct timeval delay;
 
@@ -892,13 +825,14 @@ void scr_sleep( struct code *pc, int fargc, char **fargv )
 	}
 	else
 		if (script_debug) escprintf("- Sleep input not number '%s'\n", aa);
-	free(aa);
 }
 
 void scr_rand( struct code *pc, int fargc, char **fargv )
 {
 	char	buff[20];
-	char	*aa, *bb, *what;
+	AUTOFREE_BUFFER	aa = NULL;
+	AUTOFREE_BUFFER bb = NULL;
+	AUTOFREE_BUFFER what = NULL;
 	int	a, b;
 
 	if (pc->argc<3) {
@@ -915,20 +849,14 @@ void scr_rand( struct code *pc, int fargc, char **fargv )
 		/* looks like they're not numbers, cant math strings */
 		var_str_force_2(what, "-1");
 		if (script_debug) escprintf("- rand: either '%s' or '%s' were not numbers\n", aa, bb);
-		free(aa);
-		free(bb);
-		free(what);
 		return;
 	}
-	free(aa);
-	free(bb);
 
 	/* bad min/max */
 	if (b < a)
 	{
 		var_str_force_2(what, "-1");
 		if (script_debug) printf("- rand operation. second argument (%d) smaller than first (%d)\n", b, a);
-		free(what);
 		return;
 	}
 	/* not positive */
@@ -936,7 +864,6 @@ void scr_rand( struct code *pc, int fargc, char **fargv )
 	{
 		var_str_force_2(what, "-1");
 		if (script_debug) printf("- rand operation. arguments (%d, %d) must be positive", a, b);
-		free(what);
 		return;
 	}
 
@@ -944,12 +871,14 @@ void scr_rand( struct code *pc, int fargc, char **fargv )
 
 	snprintf(buff, 19, "%d", get_rand(a,b));
 	var_str_force_2(what, buff);
-	free(what);
 }
 
 void scr_makestr( struct code *pc, int fargc, char **fargv )
 {
-	char *aa, *bb, *cc, *out;
+	AUTOFREE_BUFFER aa=NULL;
+	AUTOFREE_BUFFER bb=NULL;
+	AUTOFREE_BUFFER cc=NULL;
+	AUTOFREE_BUFFER out=NULL;
 	var_op_t var;
 	int i, j;
 
@@ -966,44 +895,34 @@ void scr_makestr( struct code *pc, int fargc, char **fargv )
 
 	VAR_STR_PREPARE_2(&var, local_vars, &var_list, aa, NULL);
 
-	free(aa);
-
 	if (!isanum(bb, &i, 0)) {
 		if (script_debug) escprintf("- %s: cant make string because arg2 '%s' is not a number\n", pc->inst->name, bb);
-		free(bb);
-		free(cc);
 		return;
 	}
 	if (i < 1) {
 		if (script_debug) printf("- %s: cant make string because arg2 '%d' is less than 1\n", pc->inst->name, i);
-		free(bb);
-		free(cc);
 		return;
 	}
 	if (!strcmp(cc, "")) {
 		if (script_debug) printf("- %s: cant make string because arg3 is empty\n", pc->inst->name);
-		free(bb);
-		free(cc);
 		return;
 	}
 
-	out = strdup("");
 	for (j = 0; j < i; j++) {
-		string_add(&out, cc);
+		string_add(&out, "%s", cc);
 	}
 
 	VAR_STR_UPDATE(&var, out);
 
 	if (script_debug) escprintf("- %s: '%d' x '%s' --> '%s'\n", pc->inst->name, i, cc, var_str_val(&var));
-
-	free(bb);
-	free(cc);
-	free(out);
 }
 
 void scr_split( struct code *pc, int fargc, char **fargv )
 {
-	char *aa, *bb, *cc, *text;
+	AUTOFREE_BUFFER aa=NULL;
+	AUTOFREE_BUFFER bb=NULL;
+	AUTOFREE_BUFFER cc=NULL;
+	AUTOFREE_BUFFER text=NULL;
 	var_op_t var1, var2;
 
 	if (pc->argc<3) {
@@ -1020,13 +939,9 @@ void scr_split( struct code *pc, int fargc, char **fargv )
 	VAR_STR_PREPARE_2(&var1, local_vars, &var_list, bb, NULL);
 	VAR_STR_PREPARE_2(&var2, local_vars, &var_list, cc, NULL);
 
-	free(bb);
-	free(cc);
-
 	/* source string was empty */
 	if (!strcmp(aa, "")) {
 		if (script_debug) printf("- Source string to %s empty, returning blank head and tail.\n", pc->inst->name);
-		free(aa);
 		VAR_STR_UPDATE(&var1, "");
 		VAR_STR_UPDATE(&var2, "");
 		return;
@@ -1034,11 +949,11 @@ void scr_split( struct code *pc, int fargc, char **fargv )
 
 	/* skip spaces at start of string */
 	text = strdup(aa);
-	cc = text;
-	while ((cc != NULL) && isspace(*cc)) cc++;
+	char *ccp = text;
+	while ((ccp != NULL) && isspace(*ccp)) ccp++;
 
 	/* if all spaces at start of string, then return the spaces as head, and tail as nothing */
-	if (cc == NULL)
+	if (ccp == NULL)
 	{
 		VAR_STR_UPDATE(&var1, aa);
 		VAR_STR_UPDATE(&var2, "");
@@ -1046,32 +961,31 @@ void scr_split( struct code *pc, int fargc, char **fargv )
 	/* if there were spaces at the front of the string, ignore them, and split about next space */
 	else
 	{
-		if ((bb = strchr(cc, ' ')) == NULL)
+		char *bbp;
+		if ((bbp = strchr(ccp, ' ')) == NULL)
 		{
 			VAR_STR_UPDATE(&var1, cc);
 			VAR_STR_UPDATE(&var2, "");
 		}
 		else
 		{
-			char *dd = bb;
-			dd++;
-			VAR_STR_UPDATE(&var2, dd);
+			bbp = bb;
+			bbp++;
+			VAR_STR_UPDATE(&var2, bbp);
 			*bb=0;
 			VAR_STR_UPDATE(&var1, cc);
 		}
 	}
 
 	if (script_debug) escprintf("- %s: '%s' --> <'%s','%s'>\n", pc->inst->name, aa, var_str_val(&var1), var_str_val(&var2));
-
-	free(aa);
-	free(text);
 }
 
 void scr_strcat( struct code *pc, int fargc, char **fargv )
 {
 	var_op_t var;
-	char *a, *b, *new;
-	int i;
+	AUTOFREE_BUFFER a=NULL;
+	AUTOFREE_BUFFER b=NULL;
+	AUTOFREE_BUFFER nbuff=NULL;
 
 	if (pc->argc<2) {
 		if (script_debug) printf("Error in %s at %s too few arguments.\n", pc->inst->name, pc->debug);
@@ -1086,28 +1000,20 @@ void scr_strcat( struct code *pc, int fargc, char **fargv )
 
 	if (VAR_FOUND(&var))
 	{
-		i=strlen(var_str_val(&var)) + strlen(b);
-		new=(char *)malloc(i+1);
-		*new=0;
-		strcpy(new, var_str_val(&var));
-		strcat(new, b);
-		VAR_STR_UPDATE(&var, new);
-		free(new);
-		free(b);
+		string_add(&nbuff, "%s", var_str_val(&var));
+		string_add(&nbuff, "%s", b);
+		VAR_STR_UPDATE(&var, nbuff);
 	} else
 	{
 		VAR_STR_CREATE(&var, b);
 	}
-
-	free(a);
 }
 
 void scr_set(struct code *pc, int fargc, char **fargv)
 {
 	var_op_t var;
-	char *what;
-	char *a, *text;
-	int i, len, size;
+	AUTOFREE_BUFFER what = NULL;
+	AUTOFREE_BUFFER text = NULL;
 
 	if (pc->argc < 2) {
 		if (script_debug) printf("Error in %s at %s too few arguments.\n", pc->inst->name, pc->debug);
@@ -1122,24 +1028,10 @@ void scr_set(struct code *pc, int fargc, char **fargv)
 		return;
 	}
 
-	size=0;
-	for (i=1; i<pc->argc; i++) {
-		size+=strlen(pc->argv[i])+1;
-	}
-
-	size=size*2;
-	text=(char *)malloc(size);
-
-	*text=0;
-	for (i=1; i<pc->argc; i++) {
-		a=eval_arg(pc->argv[i], fargc, fargv);
-		len=strlen(a);
-		if (strlen(text)+len+5 >= size) {
-			size+=len+80;
-			text=realloc(text, size);
-		}
-		strcat(text, a);
-		if (i>0 && i<pc->argc-1) strcat(text, " ");
+	for (int i=1; i<pc->argc; i++) {
+		char * a = eval_arg(pc->argv[i], fargc, fargv);
+		string_add(&text, "%s", a);
+		if (i>0 && i<pc->argc-1) string_add(&text, " ");
 		free(a);
 	}
 
@@ -1151,16 +1043,14 @@ void scr_set(struct code *pc, int fargc, char **fargv)
 		if (script_debug) escprintf("- set: creating var $%s setting to '%s'\n", what, text);
 	}
 
-	free(text);
 	VAR_KEY_FREE(&var);
-	free(what);
 }
 
 void scr_getvar(struct code *pc, int fargc, char **fargv)
 {
 	var_op_t var, var2;
-	char *what;
-	char *value=NULL;
+	AUTOFREE_BUFFER what = NULL;
+	AUTOFREE_BUFFER value=NULL;
 
 	if (pc->argc < 2) {
 		if (script_debug) printf("Error in %s at %s too few arguments.\n", pc->inst->name, pc->debug);
@@ -1171,7 +1061,6 @@ void scr_getvar(struct code *pc, int fargc, char **fargv)
 	if (!eval_var(what, &var))
 	{
 		scr_devel_msg(pc, "'%s' is not a valid variable name", what);
-		free(what);
 		return;
 	}
 
@@ -1204,15 +1093,13 @@ void scr_getvar(struct code *pc, int fargc, char **fargv)
 		VAR_STR_CREATE(&var, value);
 		if (script_debug) escprintf("- set: creating var $%s setting to '%s'\n", what, value);
 	}
-	if (value!=NULL) free(value);
 	VAR_KEY_FREE(&var);
-	free(what);
 }
 
 void scr_unset(struct code *pc, int fargc, char **fargv)
 {
 	var_op_t var;
-	char *what;
+	AUTOFREE_BUFFER what = NULL;
 
 	if (pc->argc < 1)
 	{
@@ -1231,16 +1118,14 @@ void scr_unset(struct code *pc, int fargc, char **fargv)
 		else if (script_debug) escprintf("- unset: %s was not a variable.\n", what);
 		VAR_KEY_FREE(&var);
 	}
-
-	free(what);
 }
 
 void scr_clearvars(struct code *pc, int fargc, char **fargv)
 {
 	var_op_t iter;
 	var_op_t op;
-	char *what = NULL;
-	char *key;
+	AUTOFREE_BUFFER what = NULL;
+	AUTOFREE_BUFFER key = NULL;
 
 	if (pc->argc > 1) {
 		if (script_debug) printf("Error in %s at %s too many arguments.\n", pc->inst->name, pc->debug);
@@ -1263,7 +1148,6 @@ void scr_clearvars(struct code *pc, int fargc, char **fargv)
 		{
 			VAR_LIST_NEXT(&iter);
 		}
-		free(key);
 	}
 
 	/* 2nd pass garbage-collects hashes (does nothing with lists)
@@ -1271,8 +1155,6 @@ void scr_clearvars(struct code *pc, int fargc, char **fargv)
 	 */
 	VAR_LIST_ITERATE(&iter, &var_list);
 	while (VAR_FOUND(&iter)) VAR_LIST_NEXT(&iter);
-
-	if (what != NULL) free(what);
 }
 
 void scr_local(struct code *pc, int fargc, char **fargv )


=====================================
src/client/who.c
=====================================
--- a/src/client/who.c
+++ b/src/client/who.c
@@ -65,11 +65,6 @@ char *itime(unsigned long t)
 	return(out);
 }
 
-#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;
@@ -241,3 +236,19 @@ char *part_who_talk(const char *text, int status)
 	return NULL;
 }
 
+/* grab a handle to the current wholist
+ * you need to json_decref it when finished
+ */
+json_t * grab_wholist(void)
+{
+	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 (whoinfo != NULL) json_incref(whoinfo);
+	return whoinfo;
+}


=====================================
src/client/who.h
=====================================
--- a/src/client/who.h
+++ b/src/client/who.h
@@ -11,5 +11,13 @@ 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);
+json_t * grab_wholist(void);
+
+#ifndef json_array_foreach
+#define json_array_foreach(array, index, value) \
+	for(index = 0; \
+	index < json_array_size(array) && (value = json_array_get(array, index)); \
+	index++)
+#endif
 
 #endif /* CLIENT_WHO_H */


=====================================
src/gags.c
=====================================
--- a/src/gags.c
+++ b/src/gags.c
@@ -593,7 +593,7 @@ static char *apply_morse(char *in)
 	for (i=0; i<strlen(in); i++)
 	{
 		if (i>0) string_add(&out, " ");
-		string_add(&out, lookup_morse(in[i]));
+		string_add(&out, "%s", lookup_morse(in[i]));
 	}
 	string_add(&out, " .-.-.");
 


=====================================
src/str_util.c
=====================================
--- a/src/str_util.c
+++ b/src/str_util.c
@@ -1,9 +1,12 @@
 #include <stdlib.h>
-#include <stdio.h>
 #include <fcntl.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdarg.h>
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdio.h>
 #include "bb.h"
 #include "str_util.h"
 
@@ -66,19 +69,25 @@ int get_rand(int min, int max)
 	return ((int)fValue);
 }
 
-void string_add(char **str, const char *add)
+void string_add(char **str, const char *fmt, ...)
 {
-	if (add != NULL)
+	va_list va;
+	char *text = NULL;
+	if (fmt == NULL) return;
+
+	va_start(va, fmt);
+	vasprintf(&text, fmt, va);
+	va_end(va);
+		
+	if (*str == NULL)
 	{
-		if (*str == NULL)
-		{
-			*str = strdup(add);
-		}
-		else
-		{
-			*str = realloc(*str, sizeof(char) * (strlen(*str) + strlen(add) + 1));
-			strcat(*str, add);
-		}
+		/* was an empty string, give it this one */
+		*str = text;
+	} else {
+		/* was not empty, append */
+		*str = realloc(*str, sizeof(char) * (strlen(*str) + strlen(text) + 1));
+		strcat(*str, text);
+		free(text);
 	}
 }
 


=====================================
src/str_util.h
=====================================
--- a/src/str_util.h
+++ b/src/str_util.h
@@ -5,7 +5,7 @@
 int stringcmp(const char *a, const char *b, int n);
 void strip_str(char *string);
 int get_rand(int min, int max);
-void string_add(char **str, const char *add);
+void string_add(char **str, const char *fmt, ...)  __attribute__((format(gnu_printf,2,3)));
 int allspace(char *in);
 void strlower(char *szString);
 void escprintf(const char *szFormat, ...);



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


More information about the mw-devel mailing list