[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