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

arthur at sucs.org arthur at sucs.org
Tue Oct 5 17:31:36 BST 2010


Author: arthur
Date: 2010-10-05 17:31:36 +0100 (Tue, 05 Oct 2010)
New Revision: 1173

Modified:
   trunk/src/webclient/Makefile
   trunk/src/webclient/comms.c
   trunk/src/webclient/comms.h
   trunk/src/webclient/import.c
   trunk/src/webclient/mwpoll.c
Log:
listening works, talking doesnt.


Modified: trunk/src/webclient/Makefile
===================================================================
--- trunk/src/webclient/Makefile	2010-10-04 15:48:18 UTC (rev 1172)
+++ trunk/src/webclient/Makefile	2010-10-05 16:31:36 UTC (rev 1173)
@@ -23,7 +23,7 @@
 DEFS+= -DMSGDIR=\"$(MSGDIR)\"
 
 ### uncomment for gdb debugging
-LDFLAGS+= -ggdb -g
+LDFLAGS+= -ggdb -g -lcrypt
 CFLAGS+= -ggdb -g -D__NO_STRING_INLINE -fstack-protector-all -std=c99
 
 ### Optimisation - uncomment for release & extra testing
@@ -49,7 +49,7 @@
 
 .PHONY: build install clean test
 
-mwpoll: mwpoll.o import.o comms.o ../perms.o ../strings.o ../files.o
+mwpoll: mwpoll.o import.o comms.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-04 15:48:18 UTC (rev 1172)
+++ trunk/src/webclient/comms.c	2010-10-05 16:31:36 UTC (rev 1173)
@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <time.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -30,6 +31,14 @@
 
 #define UNIX_PATH_MAX 108
 
+/* how long to wait for a long-poll */
+#define DEFAULT_TIMEOUT 20
+
+extern time_t lastcomm;
+extern char * authtext;
+
+extern struct person *user;
+
 typedef struct {
 	struct list_head list;
 	enum ipc_types state;
@@ -44,6 +53,9 @@
 typedef struct {
 	struct list_head list;
 	int fd;
+	int authd;
+	int timeout;
+	time_t longwait;
 } CONNECTION;
 
 struct list_head connlist;
@@ -76,7 +88,23 @@
 	INIT_LIST_HEAD(&connlist);
 }
 
+struct filter_info {
+        int     channel;
+        int     noloopback;
+};
 
+static int send_filter_oneroom(const struct person * usr, const struct who * who, const void * info) {
+// Everyone in a room except people with global turned on
+        struct filter_info *    f_info = (struct filter_info *) info;
+
+        if ((f_info->noloopback) && (getpid() == who->pid)) return 0;
+        if (! cm_flags(usr->chatmode, CM_ONCHAT, CM_MODE_ALL)) return 0;
+        if (cm_flags(usr->chatmode, CM_GLOBAL, CM_MODE_ALL)) return 0;
+
+        return (usr->room == f_info->channel);
+}
+
+
 /* we got a message */
 void accept_pipe_cmd(enum ipc_types state, char *newbuff, int mesg_pid, struct person *mesg_user)
 {
@@ -92,6 +120,9 @@
 
 }
 
+static int handle_command(CONNECTION *co);
+static int send_list(CONNECTION *co);
+
 static void accept_new(void)
 {
 	CONNECTION *new = malloc(sizeof(CONNECTION));
@@ -103,6 +134,9 @@
 		free(new);
 		return;
 	}
+	new->authd = 0;
+	new->timeout = DEFAULT_TIMEOUT;
+	new->longwait = 0;
 	list_add(&(new->list), &connlist);
 	printf("Adding connection fd %d\n", new->fd);
 }
@@ -150,7 +184,7 @@
                         return -1;
                 }
                 if (FD_ISSET(incoming_pipe, &readfds))
-                       handle_mesg();
+			handle_mesg();
                 if (FD_ISSET(command_sock, &readfds)) {
 			accept_new();
 		}
@@ -163,7 +197,7 @@
 				free(co);
 			}else
 			if (FD_ISSET(co->fd, &readfds)) {
-				if (handle_command(co->fd)) {
+				if (handle_command(co)) {
 					printf("Finishing connection fd=%d\n", co->fd);
 					list_del(pos);
 					close(co->fd);
@@ -172,6 +206,27 @@
 			}
 		}
         }
+	list_for_each_safe(pos, q, &connlist) {
+		CONNECTION *co = list_entry(pos, CONNECTION, list);
+		if (co->longwait != 0) {
+			time_t now = time(NULL);
+			if (!list_empty(&msglist)) {
+				if (send_list(co)) {
+					printf("Finishing connection after long wait fd=%d\n", co->fd);
+					list_del(pos);
+					close(co->fd);
+					free(co);
+				}
+			}else
+			if (now - co->longwait > co->timeout) {
+				printf("Long poll timeout fd=%d\n", co->fd);
+				send_list(co);
+				list_del(pos);
+				close(co->fd);
+				free(co);
+			}
+		}
+	}
 
         errno = select_error;
         if (ret<0 && select_error == EINVAL)
@@ -185,46 +240,98 @@
 		return 0;
 }
 
-int handle_command(int sock)
+static int send_list(CONNECTION *co)
 {
+	MESG *tmp;
+	struct list_head *pos, *q;
+	int len;
+	char buff[8192];
+
+	buff[0] = 0;
+	int n=0;
+	snprintf(buff, sizeof 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 */
+		list_del(pos);
+
+		snprintf(&buff[len], sizeof(buff)-len, "{\"state\":%d,\"pid\":%d,\"username\":\"%s\",\"text\":\"%s\"}", tmp->state, tmp->pid, tmp->user.name, tmp->text);
+		free(tmp->text);
+		free(tmp);
+		n++;
+	}
+	len = strlen(buff);
+	snprintf(&buff[len], sizeof(buff)-len, "]");
+
+	co->longwait = 0;
+	send(co->fd, buff, strlen(buff), 0);
+	printf("Sending %d items.\n", n);
+	return 1;
+}
+
+static int handle_command(CONNECTION *co)
+{
 	/* read and answer the command socket */
 	char buff[8192];
 	int ret;
 
-	if ((ret = recv(sock, buff, sizeof buff, MSG_DONTWAIT))<0) {
+	if ((ret = recv(co->fd, buff, sizeof buff, MSG_DONTWAIT))<0) {
 		fprintf(stderr, "Error on cmd sock read: %s\n", strerror(errno));
 		return 1;
 	}
 
+	buff[ret] = 0;
+	printf("handle_command(%s)\n", buff);
+
+	lastcomm = time(NULL);
+	user->idletime = lastcomm;
+
 	if (strcasecmp(buff, "quit")==0) {
 		snprintf(buff, sizeof buff, "BYE");
-		send(sock, buff, strlen(buff), 0);
+		send(co->fd, buff, strlen(buff), 0);
 		die = 1;
 		return 1;
 	}else
-	if (strcasecmp(buff, "fetch")==0) {
-		MESG *tmp;
-		struct list_head *pos, *q;
-		int len;
-
-		buff[0] = 0;
-		int n=0;
-		snprintf(buff, sizeof buff, "[");
-		list_for_each_safe(pos, q, &msglist) {
-			tmp = list_entry(pos, MESG, list);
-			list_del(pos);
-
-			len = strlen(buff);
-			snprintf(&buff[len], sizeof(buff)-len, "{\"state\":%d,\"pid\":%d,\"username\":\"%s\",\"text\":\"%s\"}", tmp->state, tmp->pid, tmp->user.name, tmp->text);
-			free(tmp->text);
-			free(tmp);
-			n++;
+	if (strncasecmp(buff, "auth ", 5)==0) {
+		int ret=0;
+		if (strcmp(&buff[5], authtext)==0)
+		{
+			co->authd = 1;
+			snprintf(buff, sizeof buff, "{\"status\":\"OK\"}");
+		}else {
+			snprintf(buff, sizeof buff, "{\"status\":\"Bad Auth\"}");
+			ret = 1;
 		}
-		len = strlen(buff);
-		snprintf(&buff[len], sizeof(buff)-len, "]");
-
-		send(sock, buff, strlen(buff), 0);
+		send(co->fd, buff, strlen(buff), 0);
+		return ret;
+	}else
+	if (strncasecmp(buff, "timeout ", 8)==0) {
+		co->timeout = atoi(&buff[8]);
+		snprintf(buff, sizeof buff, "{\"timeout\":%d}", co->timeout);
+		send(co->fd, buff, strlen(buff), 0);
+		return 0; // dont close
+	}else
+	if (co->authd && strncasecmp(buff, "say ", 4)==0) {
+		struct filter_info f_info;
+		memset(&f_info, 0, sizeof(f_info));
+		f_info.channel = user->room;
+		ipc_send_to_all(IPC_TEXT, &buff[4], send_filter_oneroom, &f_info);
+		snprintf(buff, sizeof buff, "{\"status\":\"Message Sent to channel %d\"}", user->room);
+		send(co->fd, buff, strlen(buff), 0);
 		return 1;
+	}else
+	if (co->authd && strcasecmp(buff, "fetch")==0) {
+		if (list_empty(&msglist)) {
+			co->longwait = time(NULL);
+			return 0;
+		} else {
+			return send_list(co);
+		}
 	}
 	return 0;
 }

Modified: trunk/src/webclient/comms.h
===================================================================
--- trunk/src/webclient/comms.h	2010-10-04 15:48:18 UTC (rev 1172)
+++ trunk/src/webclient/comms.h	2010-10-05 16:31:36 UTC (rev 1173)
@@ -4,6 +4,5 @@
 void open_command_socket(void);
 void accept_pipe_cmd(enum ipc_types state, char *newbuff, int mesg_pid, struct person *mesg_user);
 int mainloop(int millis);
-int handle_command(int sock);
 void handle_mesg(void);
 void close_cmd(void);

Modified: trunk/src/webclient/import.c
===================================================================
--- trunk/src/webclient/import.c	2010-10-04 15:48:18 UTC (rev 1172)
+++ trunk/src/webclient/import.c	2010-10-05 16:31:36 UTC (rev 1173)
@@ -65,11 +65,6 @@
         return(0);
 }
 
-int ipc_send_to_pid(pid_t dest, enum ipc_types msgtype, const char * data) 
-{
-	return 0;
-}
-
 int32_t get_who_userposn(int pid)
 {
         struct who w;
@@ -102,3 +97,70 @@
         close(outfile);
 }
 
+void who_delete(int pid)
+{
+	int fd;
+	struct who temp;
+	fd=openwhofile(O_RDWR);
+	if(fd==-1)
+	{
+		perror("who_delete");
+		exit(1);
+	}
+	Lock_File(fd);
+	while(read(fd,&temp,sizeof(temp))==sizeof(temp))
+	{
+		if (temp.pid==pid) {
+			lseek(fd,(long)-sizeof(temp),1);
+			temp.pid=-1;
+			temp.posn=-1L;
+			write(fd,&temp,sizeof(temp));
+		}
+	}
+	Unlock_File(fd);
+	close(fd);
+}
+
+char *quotetext(const char *a)
+{
+        int     count;
+        int     ai, bi;
+        char    *b;
+
+        ai=0;
+        count=0;
+        while(a[ai]!=0)
+        {
+                if (a[ai]=='|') count++;
+                ai++;
+        }
+
+        b = malloc(sizeof(char) * (strlen(a) + count + 1));
+
+        ai=bi=0;
+        while (a[ai]!=0)
+        {
+                if (a[ai]=='|')
+                {
+                        b[bi]=1;
+                        bi++;
+                }
+
+                b[bi]=a[ai];
+                bi++;
+                ai++;
+        }
+        b[bi]=0;
+
+        return (b);
+}
+
+void strip_quote(char *a)
+{
+    char *end = a + strlen(a);
+
+    /* Step back through quote chars */
+    while (end > a && *(--end) == '\001')
+        *end = '\0';
+}
+

Modified: trunk/src/webclient/mwpoll.c
===================================================================
--- trunk/src/webclient/mwpoll.c	2010-10-04 15:48:18 UTC (rev 1172)
+++ trunk/src/webclient/mwpoll.c	2010-10-05 16:31:36 UTC (rev 1173)
@@ -24,6 +24,35 @@
 int internet = 0;
 int idle = 0;
 
+#define DEFAULT_IDLE 60
+int clientidle = DEFAULT_IDLE;
+time_t lastcomm = 0;
+
+char *authtext = NULL;
+
+int mydaemon(void)
+{
+	int pid = fork();
+
+	if (pid == -1) {
+		printf("Fork failed: %s\n", strerror(errno));
+		exit(0);
+	} else
+	if (pid != 0) {
+		return pid;
+	} else {
+		if (seteuid(110)) {
+			printf("seteuid failed. %s\n", strerror(errno));
+			exit(0);
+		}
+		setsid();
+		close(0);
+		close(1);
+		close(2);
+	}
+	return 0;
+}
+
 void usage(const char *name)
 {
 	printf("Usage: %s [-u username] [-c channel]\n", name);
@@ -59,6 +88,25 @@
 		return 1;
 	}
 
+	/* read a password and check it */
+	{
+		char buff[80];
+		char *p;
+		char salt[3];
+
+		if (fgets(buff, 80, stdin) == NULL) {
+			printf("Expected password\n");
+			return 1;
+		}
+		if ((p=strchr(buff,'\r'))!=NULL) *p=0;
+		if ((p=strchr(buff,'\n'))!=NULL) *p=0;
+		strncpy(salt, me.passwd, 2);
+		if (strcmp(crypt(buff,salt), me.passwd)!=0) {
+			printf("Incorrect password\n");
+			return 1;
+		}
+	}
+
 	/* mark as in talker */
 	user->chatmode=0;
 	user->chatmode=cm_flags(user->chatmode,CM_ONCHAT,CM_MODE_SET);
@@ -66,17 +114,41 @@
 	user->room = channel;
 	update_user(user,userposn);
 
-	printf("Starting up session %d\n", getpid());
+	/* choose an authtext */
+	{
+		int i;
+		authtext = malloc(9);
+		srand(time(NULL));
+		for (i=0;i<8;i++) authtext[i] = 'A' + (rand() % 26);
+	}
 
+	int cpid = mydaemon();
+	if (cpid != 0) {
+		printf("%d\n%s\n", cpid, authtext);
+		return 0;
+	}
+
 	/* load us up */
 	create_pipe();
 	open_incoming_fifo();
 	open_command_socket();
 	who_add(getpid(),userposn);
+	lastcomm = time(NULL);
 
 	/* the main loop */
-	while (mainloop(-1)==0) {};
+	while (mainloop(1000)==0) {
+		time_t now = time(NULL);
+		update_user(user,userposn);
+		if ((now - lastcomm) > clientidle) {
+			printf("Client Idle out.\n");
+			break;
+		}
+	};
 
+	user->idletime=time(0);
+	update_user(user,userposn);
+	who_delete(getpid());
 	close_fifo();
 	close_cmd();
+	return 0;
 }




More information about the mw-devel mailing list