[mw-devel] MW3 r1178 - trunk/src/webclient

arthur at sucs.org arthur at sucs.org
Thu Oct 7 16:10:04 BST 2010


Author: arthur
Date: 2010-10-07 16:10:04 +0100 (Thu, 07 Oct 2010)
New Revision: 1178

Added:
   trunk/src/webclient/mwstring.c
   trunk/src/webclient/mwstring.h
Modified:
   trunk/src/webclient/Makefile
   trunk/src/webclient/comms.c
Log:
add who command, simplify string handling


Modified: trunk/src/webclient/Makefile
===================================================================
--- trunk/src/webclient/Makefile	2010-10-06 19:52:42 UTC (rev 1177)
+++ trunk/src/webclient/Makefile	2010-10-07 15:10:04 UTC (rev 1178)
@@ -48,7 +48,7 @@
 
 .PHONY: build install clean test
 
-mwpoll: mwpoll.o import.o comms.o ../perms.o ../strings.o ../files.o ../ipc.o ../iconv.o
+mwpoll: mwpoll.o import.o comms.o mwstring.o ../perms.o ../strings.o ../files.o ../ipc.o ../iconv.o
 	$(CC) $(LDFLAGS) $(LDLIBS) -o $@ $^
 
 clean:

Modified: trunk/src/webclient/comms.c
===================================================================
--- trunk/src/webclient/comms.c	2010-10-06 19:52:42 UTC (rev 1177)
+++ trunk/src/webclient/comms.c	2010-10-07 15:10:04 UTC (rev 1178)
@@ -21,6 +21,7 @@
 #include "import.h"
 #include "comms.h"
 #include "list.h"
+#include "mwstring.h"
 
 extern int incoming_pipe;
 int command_sock;
@@ -275,25 +276,16 @@
 {
 	MESG *tmp;
 	struct list_head *pos, *q;
-	int len;
-	char buff[8192];
+	mwstring *buff = mws_new(2048);
 
-	buff[0] = 0;
 	int n=0;
-	snprintf(buff, sizeof buff, "[");
+	mws_add(buff, "[");
 	list_for_each_safe(pos, q, &msglist) {
 		tmp = list_entry(pos, MESG, list);
-		len = strlen(buff);
 
-		/* too full, enough for now */
-		if (strlen(tmp->text)+64 > sizeof(buff)-len) break;
-
-		/* its okay, go ahead */
-
-		snprintf(&buff[len], sizeof(buff)-len, "{\"state\":%d,\"pid\":%d,\"username\":\"%s\",\"text\":\"%s\"}", tmp->state, tmp->pid, tmp->user.name, tmp->text);
+		mws_add(buff, "{\"state\":%d,\"pid\":%d,\"username\":\"%s\",\"text\":\"%s\"}", tmp->state, tmp->pid, tmp->user.name, tmp->text);
 		if (pos->next != &msglist) {
-			len = strlen(buff);
-			snprintf(&buff[len], sizeof(buff)-len, ",");
+			mws_add(buff, ",");
 		}
 
 		list_del(pos);
@@ -303,46 +295,44 @@
 		free(tmp);
 		n++;
 	}
-	len = strlen(buff);
-	snprintf(&buff[len], sizeof(buff)-len, "]");
+	mws_add(buff, "]");
 
 	co->longwait = 0;
-	send(co->fd, buff, strlen(buff), 0);
+	send(co->fd, mws_cstr(buff), mws_len(buff), 0);
+	mws_free(buff);
 	printf("Sending %d items.\n", n);
 	return 1;
 }
 
-
 char * json_escape(char *original)
 {
-	int maxlen = (strlen(original)*2) + 1;
-	char *line = malloc(maxlen);
-	line[0] = 0;
 	int i;
-	char *out = line;
 	unsigned char *in = (unsigned char *)original;
+	mwstring *line = mws_new(strlen(original)+1);
+	char * out;
 
 	for (i=0;i<strlen(original);i++) {
 		switch (*in) {
-			case '\b': snprintf(out, maxlen, "\\b"); out+=2; maxlen-=2; break;
-			case '\n': snprintf(out, maxlen, "\\n"); out+=2; maxlen-=2; break;
-			case '\r': snprintf(out, maxlen, "\\r"); out+=2; maxlen-=2; break;
-			case '\t': snprintf(out, maxlen, "\\t"); out+=2; maxlen-=2; break;
-			case '"': snprintf(out, maxlen, "\\\""); out+=2; maxlen-=2; break;
-			case '\\': snprintf(out, maxlen, "\\\\"); out+=2; maxlen-=2; break;
-			case '/': snprintf(out, maxlen, "\\/"); out+=2; maxlen-=2; break;
+			case '\b': mws_add(line, "\\b"); break;
+			case '\n': mws_add(line, "\\n"); break;
+			case '\r': mws_add(line, "\\r"); break;
+			case '\t': mws_add(line, "\\t"); break;
+			case '"':  mws_add(line, "\\\""); break;
+			case '\\': mws_add(line, "\\\\"); break;
+			case '/':  mws_add(line, "\\/"); break;
 			default:
 				  if (*in < ' ') {
-					snprintf(out, maxlen, "\\u%04x", *in); out+=6; maxlen-=6; break;
+					mws_add(line, "\\u%04x", *in); break;
 				  }else
-					snprintf(out, maxlen, "%c", *in); out+=1; maxlen-=1; break;
+					mws_add(line, "%c", *in); break;
 		}
 		in++;
-		if (maxlen < 2) break;
 	}
-	*out = 0;
 
-	return line;
+	out = (char *)mws_cstr(line);
+	free(line);
+
+	return out;
 }
 
 static int handle_command(CONNECTION *co)
@@ -393,6 +383,44 @@
 		send(co->fd, buff, strlen(buff), 0);
 		return 0; // dont close
 	}else
+	if (co->authd && strcasecmp(buff, "who")==0) {
+		struct person u;
+		struct who w;
+		int ufile, wfile;
+		int32_t now = time(NULL);
+		mwstring *line = mws_new(2048);
+
+		wfile = openwhofile(O_RDONLY);
+		ufile = openuserfile(O_RDONLY);
+
+		mws_add(line, "[");
+
+		while (read(wfile, &w, sizeof(w)))
+		{
+			char *realname;
+			char *doing;
+			if (w.posn < 0) continue;
+			lseek(ufile, w.posn, SEEK_SET);
+			read(ufile, &u, sizeof(u));
+			if (mws_cstr(line)[0] != '[') mws_add(line, ",");
+			realname = json_escape(u.realname);
+			doing = json_escape(u.doing);
+			mws_add(line, "{");
+			if (u_god(user->status)) {
+				mws_add(line, "\"pid\":%d,", w.pid);
+				mws_add(line, "\"realname\":\"%s\",", realname);
+			}
+			mws_add(line, "\"username\":\"%s\",", u.name);
+			mws_add(line, "\"channel\":%d,", u.room);
+			mws_add(line, "\"doing\":\"%s\",", doing);
+			mws_add(line, "\"idle\":%d}", now - u.idletime);
+			free(realname);
+			free(doing);
+		}
+		mws_add(line, "]");
+		send(co->fd, mws_cstr(line), mws_len(line), 0);
+		mws_free(line);
+	}else
 	if (co->authd && strncasecmp(buff, "say ", 4)==0) {
 		struct filter_info f_info;
 		char line[8192];

Added: trunk/src/webclient/mwstring.c
===================================================================
--- trunk/src/webclient/mwstring.c	                        (rev 0)
+++ trunk/src/webclient/mwstring.c	2010-10-07 15:10:04 UTC (rev 1178)
@@ -0,0 +1,48 @@
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include "mwstring.h"
+
+mwstring *mws_new(int size)
+{
+	mwstring *new = malloc(sizeof(mwstring));
+	new->body = malloc(size);
+	new->len = size;
+	bzero(new->body, new->len);
+	return new;
+}
+
+void mws_add(mwstring *s, const char *fmt, ...)
+{
+	char *new;
+	va_list va;
+	int newsize;
+
+	va_start(va, fmt);
+	vasprintf(&new, fmt, va);
+	va_end(va);
+
+	newsize = strlen(s->body) + strlen(new) + 1;
+	if (newsize > s->len) {
+		s->body = realloc(s->body, newsize);
+		s->len = newsize;
+	}
+	strcat(s->body, new);
+	free(new);
+}
+
+const char *mws_cstr(mwstring *s) {
+	return s->body;
+}
+
+int mws_len(mwstring *s) {
+	return strlen(s->body);
+}
+
+void mws_free(mwstring *s) {
+	free(s->body);
+	s->body = NULL;
+	s->len = 0;
+	free(s);
+}

Added: trunk/src/webclient/mwstring.h
===================================================================
--- trunk/src/webclient/mwstring.h	                        (rev 0)
+++ trunk/src/webclient/mwstring.h	2010-10-07 15:10:04 UTC (rev 1178)
@@ -0,0 +1,12 @@
+
+typedef struct {
+	char *body;
+	size_t len;
+} mwstring;
+
+/* mwstring.c */
+mwstring *mws_new(int size);
+void mws_add(mwstring *s, const char *fmt, ...);
+const char *mws_cstr(mwstring *s);
+int mws_len(mwstring *s);
+void mws_free(mwstring *s);




More information about the mw-devel mailing list