shithub: wired

Download patch

ref: b59c7180abdd10cf3abe7fd1b58b17683b7436d8
author: james palmer <[email protected]>
date: Mon Jun 7 16:10:04 EDT 2021

init

--- /dev/null
+++ b/LICENSE
@@ -1,0 +1,19 @@
+Copyright © 2021 James Palmer
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
--- /dev/null
+++ b/main.c
@@ -1,0 +1,196 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <thread.h>
+#include <acme.h>
+
+typedef struct Session Session;
+struct Session {
+	AWin *cwin;
+	AWin *iwin;
+	
+	char *mtpt;
+	char *chan;
+	char *usr;
+	
+	Channel *ctl;
+	
+	int fd;
+};
+
+enum { Stack = 4*1024, };
+
+void
+chatcatproc(void *aux)
+{
+	Session *s;
+	AWin *w;
+	
+	w = aux;
+	s = w->aux;
+	
+	awincat(w, s->fd);
+}
+
+void
+wineventproc(void *aux)
+{
+	AWin *w;
+	AEvent ev;
+	Session *s;
+	Channel *ctl;
+	Channel *eventc;
+	
+	w = aux;
+	s = w->aux;
+	ctl = s->ctl;
+	eventc = aeventlisten(w);
+	
+	while(recv(eventc, &ev)) {
+		switch(ev.type) {
+		case 'x':
+			if(strcmp(ev.text, "Del") == 0)
+				sendp(ctl, "quit");
+			if(strcmp(ev.text, "Send") == 0)
+				sendp(ctl, "send");
+			if(strcmp(ev.text, "Action") == 0)
+				sendp(ctl, "act");
+				
+			break;
+		}
+	}	
+}
+
+char *
+readbody(AWin *w)
+{
+	Biobuf *fd;
+	char *buf;
+	
+	fd = awinfsbopen(w, "body", OREAD);
+	buf = Brdstr(fd, '\0', 0);
+	Bterm(fd);
+	
+	awinclear(w);
+	
+	return buf;
+}
+
+void
+domessage(Session *s, char *msg)
+{
+	char *buf;
+	
+	if(msg[0] == '\0')
+		return;
+	
+	buf = smprint("%s • %s\n", s->usr, msg);
+	write(s->fd, buf, strlen(buf));
+	
+	free(buf);
+	free(msg);
+}
+
+void
+doaction(Session *s, char *msg)
+{
+	char *buf;
+	
+	if(msg[0] == '\0')
+		return;
+	
+	buf = smprint("* %s %s", s->usr, msg);
+	write(s->fd, buf, strlen(buf));
+	
+	free(buf);
+	free(msg);
+}
+
+void
+dochat(char *mtpt, char *chan, char *usr)
+{
+	Session *s;
+	char buf[128];
+	char *ctl;
+	
+	s = mallocz(sizeof(Session), 1);
+
+	s->mtpt = strdup(mtpt);
+	s->chan = strdup(chan);
+	s->usr = strdup(usr);
+	
+	snprint(buf, sizeof(buf), "%s/%s", s->mtpt, s->chan);
+	s->fd = open(buf, ORDWR);
+	if(s->fd < 0) {
+		free(s->mtpt);
+		free(s->chan);
+		free(s->usr);
+		free(s);
+		
+		sysfatal("chat server not mounted");
+	};
+		
+	s->cwin = awincreate();
+	awinctl(s->cwin, "name /wired/chat\n");
+	awinctl(s->cwin, "scratch\n");
+	awinctl(s->cwin, "nomenu\n");
+	s->cwin->aux = s;
+	
+	s->iwin = awincreate();
+	awinctl(s->iwin, "name /wired/input\n");
+	awinctl(s->iwin, "scratch\n");
+	awinctl(s->iwin, "nomenu\n");
+	awinsettag(s->iwin, " Send Action ");
+	s->iwin->aux = s;
+	
+	s->ctl = chancreate(sizeof(char*), 0);
+	
+	proccreate(chatcatproc, s->cwin, Stack);
+	proccreate(wineventproc, s->cwin, Stack);
+	proccreate(wineventproc, s->iwin, Stack);
+	
+	while(ctl = recvp(s->ctl)) {
+		if(strcmp(ctl, "send") == 0)
+			domessage(s, readbody(s->iwin));
+		if(strcmp(ctl, "act") == 0)
+			doaction(s, readbody(s->iwin));
+		if(strcmp(ctl, "quit") == 0)
+			break;
+	}
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s [-s srv] [-c chan] [-u user]\n", argv0);
+	exits(nil);
+}
+
+void
+threadmain(int argc, char *argv[])
+{
+	char *srv, *user, *chan;
+	
+	srv = "/n/chat";
+	chan = "chat";
+	user = getuser();
+	
+	ARGBEGIN {
+	case 's':
+		srv = EARGF(usage());
+		break;
+	case 'c':
+		chan = EARGF(usage());
+		break;
+	case 'u':
+		user = EARGF(usage());
+		break;
+	default:
+		usage();
+	} ARGEND
+	
+	dochat(srv, chan, user);
+	
+	awincloseall();
+	threadexitsall(nil);
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,7 @@
+</$objtype/mkfile
+
+BIN=/acme/bin/$objtype
+TARG=Wired
+OFILES=main.$O
+
+</sys/src/cmd/mkone