9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] make faces generic
@ 2020-10-14 23:42 covertusername967
  2020-10-15  3:24 ` covertusername967
  2020-10-17  0:26 ` Alex Musolino
  0 siblings, 2 replies; 7+ messages in thread
From: covertusername967 @ 2020-10-14 23:42 UTC (permalink / raw)
  To: covertusername967, 9front

Hello,

The following patch allows faces to receive notifications from
programs other than the mail system.  As an example, a modification of
ircrc has been included that allows it to send any received mentions
to faces.  Some minor changes were made to upas/fs to support this.  I
have been running this patch for a few weeks now with no issues,
although I will say that I do not personally use ircrc.

diff -r e05e4b6c6546 rc/bin/ircrc
--- a/rc/bin/ircrc	Mon Oct 12 02:03:52 2020 +0200
+++ b/rc/bin/ircrc	Wed Oct 14 18:35:56 2020 -0500
@@ -169,6 +169,14 @@
 		switch ($line) {
 		case *PRIVMSG*
 			line = `{echo -n $line | privmsg}
+			switch($line) {
+			case *^$nick^*
+				digest = ircrc.$pid.`{date -n}
+				sender = `{echo -n $line | sed 'y/«»/  /' | awk '{print $2}'}
+				data = `{echo -n $line | sed 'y/()/  /' | awk '{print $1}'}
+				winid = `{cat /dev/winid}
+				plumb -dnotify -a 'digest='^$digest^' dst=irc sender='^$sender^'@'^$server^' winid='^$winid^' date='''^`"{date}^'''' -s ircrc $data
+			}
 		case *JOIN* *QUIT* *PART* *NICK*
 			line = `{echo -n $line | misc}
 		case *NOTICE*
diff -r e05e4b6c6546 rc/bin/vwhois
--- a/rc/bin/vwhois	Mon Oct 12 02:03:52 2020 +0200
+++ b/rc/bin/vwhois	Wed Oct 14 18:35:56 2020 -0500
@@ -2,16 +2,5 @@
 
 rfork e
 
-box=mbox
-if(! test -d /mail/fs/$box)
-	box=`{ls -p /mail/fs | grep -v ctl | sed 1q}
-if(~ $#box 0)
-	box=mbox	# we tried
-
-if(~ $#box 1 && test -f /mnt/plumb/seemail || test -f /mnt/term/mnt/plumb/seemail){
-	for(i)
-		plumb -dseemail -a 'filetype=vwhois digest='$i.$pid' mailtype=new sender='$i /mail/fs/$box/XXXvwhois
-}
-if not for (i){
-	echo vwhois: vwhois: vwhois: delivered `{cat /dev/user} From $i '(vwho)' >> /sys/log/mail
-}
+for(i)
+	plumb -dnotify -a 'digest='$i.$pid' sender='$i /XXXvwhois
diff -r e05e4b6c6546 sys/lib/plumb/basic
--- a/sys/lib/plumb/basic	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/lib/plumb/basic	Wed Oct 14 18:35:56 2020 -0500
@@ -4,8 +4,8 @@
 include fileaddr
 
 # declarations of ports without rules
-plumb to seemail
 plumb to showmail
+plumb to notify
 
 # open urls with web browser
 type is text
diff -r e05e4b6c6546 sys/src/cmd/faces/facedb.c
--- a/sys/src/cmd/faces/facedb.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/facedb.c	Wed Oct 14 18:35:56 2020 -0500
@@ -315,14 +315,14 @@
 }
 
 static char*
-tryfindfile(char *dom, char *user)
+tryfindfile(char *dom, char *user, char *facedir)
 {
 	char *p;
 
 	while(dom && *dom){
 		if(homeface && (p = tryfindfiledir(dom, user, homeface)) != nil)
 			return p;
-		if((p = tryfindfiledir(dom, user, "/lib/face")) != nil)
+		if((p = tryfindfiledir(dom, user, facedir)) != nil)
 			return p;
 		if((dom = strchr(dom, '.')) == nil)
 			break;
@@ -351,13 +351,13 @@
 	}
 
 	f->unknown = 0;
-	if((p = tryfindfile(dom, user)) != nil)
+	if((p = tryfindfile(dom, user, f->str[Sfacedir])) != nil)
 		return p;
 	f->unknown = 1;
-	p = tryfindfile(dom, "unknown");
+	p = tryfindfile(dom, "unknown", f->str[Sfacedir]);
 	if(p != nil || strcmp(dom, facedom) == 0)
 		return p;
-	return tryfindfile("unknown", "unknown");
+	return tryfindfile("unknown", "unknown", f->str[Sfacedir]);
 }
 
 static
diff -r e05e4b6c6546 sys/src/cmd/faces/faces.h
--- a/sys/src/cmd/faces/faces.h	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/faces.h	Wed Oct 14 18:35:56 2020 -0500
@@ -4,6 +4,11 @@
 	Sdomain,
 	Sshow,
 	Sdigest,
+	Sdst,
+	Sfacedir,
+	Sattrs,
+	Swdir,
+	Swinid,
 	Nstring
 };
 
@@ -42,9 +47,6 @@
 };
 
 extern char	date[];
-extern char	*maildir;
-extern char	**maildirs;
-extern int	nmaildirs;
 
 Face*	nextface(void);
 void	findbit(Face*);
@@ -54,7 +56,6 @@
 void	showmail(Face*);
 void	delete(char*, char*);
 void	freefacefile(Facefile*);
-Face*	dirface(char*, char*);
 void	resized(void);
 int	alreadyseen(char*);
 ulong	dirlen(char*);
@@ -63,4 +64,3 @@
 void	*erealloc(void*, ulong);
 char	*estrdup(char*);
 char	*findfile(Face*, char*, char*);
-void	addmaildir(char*);
diff -r e05e4b6c6546 sys/src/cmd/faces/main.c
--- a/sys/src/cmd/faces/main.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/main.c	Wed Oct 14 18:35:56 2020 -0500
@@ -7,9 +7,6 @@
 #include <bio.h>
 #include "faces.h"
 
-int	history = 0;	/* use old interface, showing history of mailbox rather than current state */
-int	initload = 0;	/* initialize program with contents of mail box */
-
 enum
 {
 	Facesep = 6,	/* must be even to avoid damaging background stipple */
@@ -68,7 +65,6 @@
 
 char	date[64];
 Face	**faces;
-char	*maildir = "/mail/fs/mbox";
 ulong	now;
 
 Point	datep = { 8, 6 };
@@ -163,7 +159,7 @@
 	Face *f;
 
 	if(!digest)
-		return 0;
+		return 1;
 
 	/* can do accurate check */
 	for(i=0; i<nfaces; i++){
@@ -358,25 +354,6 @@
 }
 
 void
-loadmboxfaces(char *maildir)
-{
-	int dirfd;
-	Dir *d;
-	int i, n;
-
-	dirfd = open(maildir, OREAD);
-	if(dirfd >= 0){
-		chdir(maildir);
-		while((n = dirread(dirfd, &d)) > 0){
-			for(i=0; i<n; i++)
-				addface(dirface(maildir, d[i].name));
-			free(d);
-		}
-		close(dirfd);
-	}
-}
-
-void
 freeface(Face *f)
 {
 	int i;
@@ -435,16 +412,8 @@
 void
 dodelete(int i)
 {
-	Face *f;
-
-	f = faces[i];
-	if(history){
-		free(f->str[Sshow]);
-		f->str[Sshow] = estrdup("");
-	}else{
-		delface(i);
-		flushimage(display, 1);
-	}
+	delface(i);
+	flushimage(display, 1);
 }
 
 void
@@ -586,25 +555,12 @@
 	case 1:
 		if(scroll(1, p))
 			break;
-		if(history){
-			/* click clears display */
-			lockdisplay(display);
-			for(i=0; i<nfaces; i++)
-				freeface(faces[i]);
-			free(faces);
-			faces=nil;
-			nfaces = 0;
-			unlockdisplay(display);
-			eresized(0);
-			return;
-		}else{
-			for(i=first; i<last; i++)	/* clear vwhois faces */
-				if(ptinrect(p, facerect(i-first)) 
-				&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
-					delface(i);
-					flushimage(display, 1);
-				}
-		}
+		for(i=first; i<last; i++)	/* clear vwhois faces */
+			if(ptinrect(p, facerect(i-first)) 
+			&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
+				delface(i);
+				flushimage(display, 1);
+			}
 		break;
 	case 2:
 		scroll(2, p);
@@ -675,26 +631,14 @@
 void
 usage(void)
 {
-	fprint(2, "usage: faces [-hi] [-m maildir]\n");
+	fprint(2, "usage: faces\n");
 	exits("usage");
 }
 
 void
 main(int argc, char *argv[])
 {
-	int i;
-
 	ARGBEGIN{
-	case 'h':
-		history++;
-		break;
-	case 'i':
-		initload++;
-		break;
-	case 'm':
-		addmaildir(EARGF(usage()));
-		maildir = nil;
-		break;
 	default:
 		usage();
 	}ARGEND
@@ -703,8 +647,6 @@
 		fprint(2, "faces: initdraw failed: %r\n");
 		exits("initdraw");
 	}
-	if(maildir)
-		addmaildir(maildir);
 	init();
 	unlockdisplay(display);	/* initdraw leaves it locked */
 	display->locking = 1;	/* tell library we're using the display lock */
@@ -714,9 +656,6 @@
 	pids[Mainp] = getpid();
 	startproc(timeproc, Timep);
 	startproc(mouseproc, Mousep);
-	if(initload)
-		for(i = 0; i < nmaildirs; i++)
-		 loadmboxfaces(maildirs[i]);
 	faceproc();
 	fprint(2, "faces: %s process exits\n", procnames[Mainp]);
 	killall(nil);
diff -r e05e4b6c6546 sys/src/cmd/faces/plumb.c
--- a/sys/src/cmd/faces/plumb.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/plumb.c	Wed Oct 14 18:35:56 2020 -0500
@@ -6,53 +6,56 @@
 #include <bio.h>
 #include "faces.h"
 
-static int	showfd = -1;
-static int	seefd = -1;
+static int		notefd = -1;
+static int		showfd = -1;
 static char	*user;
-
-char		**maildirs;
-int		nmaildirs;
+static char	*logtag;
 
 void
 initplumb(void)
 {
 	if((showfd = plumbopen("send", OWRITE)) == -1)
 		sysfatal("plumbopen send: %r");
-	if((seefd = plumbopen("seemail", OREAD)) == -1)
-		sysfatal("plumbopen seemail: %r");
-}
-
-void
-addmaildir(char *dir)
-{
-	maildirs = erealloc(maildirs, (nmaildirs+1)*sizeof(char*));
-	maildirs[nmaildirs++] = dir;
-}
-
-char*
-attr(Face *f)
-{
-	static char buf[128];
-
-	if(f->str[Sdigest]){
-		snprint(buf, sizeof buf, "digest=%s", f->str[Sdigest]);
-		return buf;
+	if((notefd = plumbopen("notify", OREAD)) == -1){
+		sysfatal("plumbopen notify: %r);
 	}
-	return nil;
 }
 
 void
 showmail(Face *f)
 {
-	char *s;
-	int n;
+	char *s, buf[73], *fields[6];
+	int n, len, wctl;
 
-	if(showfd<0 || f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
+	if(f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
 		return;
-	s = emalloc(128+strlen(f->str[Sshow])+1);
-	n = sprint(s, "faces\nshowmail\n/mail/fs/\ntext\n%s\n%ld\n%s", attr(f), strlen(f->str[Sshow]), f->str[Sshow]);
-	write(showfd, s, n);
-	free(s);
+	if(f->str[Swinid][0] != '0'){
+		snprint(buf, 73, "/dev/wsys/%s/wctl", f->str[Swinid]);
+		wctl = open(buf, ORDWR);
+		if(wctl < 0)
+			return;
+		if(read(wctl, buf, 72) != 72){
+			close(wctl);
+			return;
+		}
+		buf[72] = '\0';
+		if(tokenize(buf, fields, 6) != 6){
+			close(wctl);
+			return;
+		}
+		if(strcmp(fields[5], "hidden") == 0)
+			write(wctl, "unhide", 6);
+		else
+			write(wctl, "current", 7);
+		close(wctl);
+	}
+	else {
+		len = 128+strlen(f->str[Sdst])+strlen(f->str[Swdir])+strlen(f->str[Sattrs])+strlen(f->str[Sshow])+1;
+		s = emalloc(len);
+		n = snprint(s, len, "faces\n%s\n%s\ntext\n%s\n%ld\n%s", f->str[Sdst], f->str[Swdir], f->str[Sattrs], strlen(f->str[Sshow]), f->str[Sshow]);
+		write(showfd, s, n);
+		free(s);
+	}
 }
 
 char*
@@ -69,7 +72,7 @@
 void
 setname(Face *f, char *sender)
 {
-	char *at, *bang;
+	char *at;
 	char *p;
 
 	/* works with UTF-8, although it's written as ASCII */
@@ -82,13 +85,6 @@
 		f->str[Sdomain] = estrdup(at);
 		return;
 	}
-	bang = strchr(sender, '!');
-	if(bang){
-		*bang++ = '\0';
-		f->str[Suser] = estrdup(bang);
-		f->str[Sdomain] = sender;
-		return;
-	}
 }
 
 ulong
@@ -123,117 +119,57 @@
 Face*
 nextface(void)
 {
-	int i;
 	Face *f;
 	Plumbmsg *m;
-	char *t, *senderp, *showmailp, *digestp;
+	char *senderp, *showmailp, *digestp, *dstp, *facep, *winid;
 	ulong xtime;
+	Dir *facedir;
 
 	f = emalloc(sizeof(Face));
 	for(;;){
-		m = plumbrecv(seefd);
+		m = plumbrecv(notefd);
 		if(m == nil)
-			killall("error on seemail plumb port");
-		t = value(m->attr, "mailtype", "");
-		if(strcmp(t, "modify") == 0)
-			goto Ignore;
-		else if(strcmp(t, "delete") == 0)
-			delete(m->data, value(m->attr, "digest", nil));
-		else if(strcmp(t, "new") == 0)
-			for(i=0; i<nmaildirs; i++){
-				if(strncmp(m->data, maildirs[i], strlen(maildirs[i])) == 0)
-					goto Found;
-			}
-		else
-			fprint(2, "faces: unknown plumb message type %s\n", t);
-	Ignore:
-		plumbfree(m);
-		continue;
-
-	Found:
-		xtime = parsedate(value(m->attr, "date", date));
-		digestp = value(m->attr, "digest", nil);
+			killall("error on notify plumb port");
+		digestp = estrdup(value(m->attr, "digest", "inedible"));
 		if(alreadyseen(digestp)){
-			/* duplicate upas/fs can send duplicate messages */
+			/* duplicate programs can send duplicate messages */
 			plumbfree(m);
 			continue;
 		}
-		senderp = estrdup(value(m->attr, "sender", "???"));
+		facep = estrdup(value(m->attr, "facedir", "/lib/face"));
+		if(access(facep, AEXIST) == 0){
+			facedir = dirstat(facep);
+			if(facedir == nil){
+				plumbfree(m);
+				continue;
+			}
+			if(facedir->qid.type != QTDIR){
+				free(facedir);
+				plumbfree(m);
+				continue;
+			}
+			free(facedir);
+		}
+		else {
+			plumbfree(m);
+			continue;
+		}
+		dstp = estrdup(value(m->attr, "dst", "none"));
+		senderp = estrdup(value(m->attr, "sender", "unknown"));
+		winid = estrdup(value(m->attr, "winid", "0"));
+		xtime = parsedate(value(m->attr, "date", date));
 		showmailp = estrdup(m->data);
-		if(digestp)
-			digestp = estrdup(digestp);
+		f->str[Sattrs] = plumbpackattr(m->attr);
+		f->str[Swdir] = estrdup(m->wdir);
 		plumbfree(m);
 		setname(f, senderp);
 		f->time = xtime;
 		f->tm = *localtime(xtime);
 		f->str[Sshow] = showmailp;
 		f->str[Sdigest] = digestp;
+		f->str[Sdst] = dstp;
+		f->str[Sfacedir] = facep;
+		f->str[Swinid] = winid;
 		return f;
 	}
 }
-
-char*
-iline(char *data, char **pp)
-{
-	char *p;
-
-	for(p=data; *p!='\0' && *p!='\n'; p++)
-		;
-	if(*p == '\n')
-		*p++ = '\0';
-	*pp = p;
-	return data;
-}
-
-Face*
-dirface(char *dir, char *num)
-{
-	Face *f;
-	char *from, *date;
-	char buf[1024], pwd[1024], *info, *p, *digest;
-	int n, fd;
-	ulong len;
-
-	/*
-	 * loadmbox leaves us in maildir, so we needn't
-	 * walk /mail/fs/mbox for each face; this makes startup
-	 * a fair bit quicker.
-	 */
-	if(getwd(pwd, sizeof pwd) != nil && strcmp(pwd, dir) == 0)
-		sprint(buf, "%s/info", num);
-	else
-		sprint(buf, "%s/%s/info", dir, num);
-	len = dirlen(buf);
-	if(len <= 0)
-		return nil;
-	fd = open(buf, OREAD);
-	if(fd < 0)
-		return nil;
-	info = emalloc(len+1);
-	n = readn(fd, info, len);
-	close(fd);
-	if(n < 0){
-		free(info);
-		return nil;
-	}
-	info[n] = '\0';
-	f = emalloc(sizeof(Face));
-	from = iline(info, &p);	/* from */
-	iline(p, &p);	/* to */
-	iline(p, &p);	/* cc */
-	iline(p, &p);	/* replyto */
-	date = iline(p, &p);	/* date */
-	setname(f, estrdup(from));
-	f->time = parsedate(date);
-	f->tm = *localtime(f->time);
-	sprint(buf, "%s/%s", dir, num);
-	f->str[Sshow] = estrdup(buf);
-	iline(p, &p);	/* subject */
-	iline(p, &p);	/* mime content type */
-	iline(p, &p);	/* mime disposition */
-	iline(p, &p);	/* filename */
-	digest = iline(p, &p);	/* digest */
-	f->str[Sdigest] = estrdup(digest);
-	free(info);
-	return f;
-}
diff -r e05e4b6c6546 sys/src/cmd/upas/fs/mbox.c
--- a/sys/src/cmd/upas/fs/mbox.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/upas/fs/mbox.c	Wed Oct 14 18:35:56 2020 -0500
@@ -1547,11 +1547,12 @@
 static void
 mailplumb(Mailbox *mb, Message *m)
 {
-	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], *from, *subject;
+	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], addr[320], *from, *subject, *bang, *unixfrom;
 	int ai;
 	Plumbmsg p;
 	Plumbattr a[7];
 	static int fd = -1;
+	int didflip;
 
 	subject = m->subject;
 	if(subject == nil)
@@ -1572,8 +1573,27 @@
 	if(fd < 0)
 		return;
 
+	/* convert uucp address for faces */
+	didflip = 0;
+	if(from == m->unixfrom){
+		unixfrom = strdup(m->unixfrom);
+		if(unixfrom == nil)
+			return;
+		bang = strchr(unixfrom, '!');
+		*bang++ = '\0';
+		strcpy(addr, bang);
+		strcat(addr, "@");
+		strcat(addr, unixfrom);
+		from = strdup(addr);
+		if(from == nil){
+			free(unixfrom);
+			return;
+		}
+		didflip++;
+	}
+
 	p.src = "mailfs";
-	p.dst = "seemail";
+	p.dst = "notify";
 	p.wdir = "/mail/fs";
 	p.type = "text";
 
@@ -1603,12 +1623,18 @@
 	a[ai].value = date;
 	a[ai-1].next = &a[ai];
 
-	if(m->digest){
-		snprint(dbuf, sizeof dbuf, "%A", m->digest);
-		a[++ai].name = "digest";
-		a[ai].value = dbuf;
-		a[ai-1].next = &a[ai];
-	}
+	if(m->digest == nil)
+		digestmessage(mb, m);
+	snprint(dbuf, sizeof dbuf, "%A", m->digest);
+	
+	a[++ai].name = "digest";
+	a[ai].value = dbuf;
+	a[ai-1].next = &a[ai];
+
+	a[++ai].name = "dst";
+	a[ai].value = "showmail";
+	a[ai-1].next = &a[ai];
+	
 	a[ai].next = nil;
 	p.attr = a;
 	snprint(buf, sizeof buf, "%s/%s/%s",
@@ -1617,6 +1643,11 @@
 	p.data = buf;
 
 	myplumbsend(fd, &p);
+
+	if(didflip != 0){
+		free(unixfrom);
+		free(from);
+	}
 }
 
 /*



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9front] make faces generic
  2020-10-14 23:42 [9front] make faces generic covertusername967
@ 2020-10-15  3:24 ` covertusername967
  2020-10-17  2:04   ` ori
  2020-10-17  0:26 ` Alex Musolino
  1 sibling, 1 reply; 7+ messages in thread
From: covertusername967 @ 2020-10-15  3:24 UTC (permalink / raw)
  To: covertusername967, 9front

[-- Attachment #1: Type: text/plain, Size: 15268 bytes --]

Hello,

When sending the previous email I found a bug in acme mail related to this patch (I only use acme mail to send mail.) The below patch is the same as the previous one and also fixes acme mail.

diff -r e05e4b6c6546 rc/bin/ircrc
--- a/rc/bin/ircrc	Mon Oct 12 02:03:52 2020 +0200
+++ b/rc/bin/ircrc	Wed Oct 14 19:02:10 2020 -0500
@@ -169,6 +169,14 @@
 		switch ($line) {
 		case *PRIVMSG*
 			line = `{echo -n $line | privmsg}
+			switch($line) {
+			case *^$nick^*
+				digest = ircrc.$pid.`{date -n}
+				sender = `{echo -n $line | sed 'y/«»/  /' | awk '{print $2}'}
+				data = `{echo -n $line | sed 'y/()/  /' | awk '{print $1}'}
+				winid = `{cat /dev/winid}
+				plumb -dnotify -a 'digest='^$digest^' dst=irc sender='^$sender^'@'^$server^' winid='^$winid^' date='''^`"{date}^'''' -s ircrc $data
+			}
 		case *JOIN* *QUIT* *PART* *NICK*
 			line = `{echo -n $line | misc}
 		case *NOTICE*
diff -r e05e4b6c6546 rc/bin/vwhois
--- a/rc/bin/vwhois	Mon Oct 12 02:03:52 2020 +0200
+++ b/rc/bin/vwhois	Wed Oct 14 19:02:10 2020 -0500
@@ -2,16 +2,5 @@
 
 rfork e
 
-box=mbox
-if(! test -d /mail/fs/$box)
-	box=`{ls -p /mail/fs | grep -v ctl | sed 1q}
-if(~ $#box 0)
-	box=mbox	# we tried
-
-if(~ $#box 1 && test -f /mnt/plumb/seemail || test -f /mnt/term/mnt/plumb/seemail){
-	for(i)
-		plumb -dseemail -a 'filetype=vwhois digest='$i.$pid' mailtype=new sender='$i /mail/fs/$box/XXXvwhois
-}
-if not for (i){
-	echo vwhois: vwhois: vwhois: delivered `{cat /dev/user} From $i '(vwho)' >> /sys/log/mail
-}
+for(i)
+	plumb -dnotify -a 'digest='$i.$pid' sender='$i /XXXvwhois
diff -r e05e4b6c6546 sys/lib/plumb/basic
--- a/sys/lib/plumb/basic	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/lib/plumb/basic	Wed Oct 14 19:02:10 2020 -0500
@@ -4,8 +4,8 @@
 include fileaddr
 
 # declarations of ports without rules
-plumb to seemail
 plumb to showmail
+plumb to notify
 
 # open urls with web browser
 type is text
diff -r e05e4b6c6546 sys/src/cmd/faces/facedb.c
--- a/sys/src/cmd/faces/facedb.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/facedb.c	Wed Oct 14 19:02:10 2020 -0500
@@ -315,14 +315,14 @@
 }
 
 static char*
-tryfindfile(char *dom, char *user)
+tryfindfile(char *dom, char *user, char *facedir)
 {
 	char *p;
 
 	while(dom && *dom){
 		if(homeface && (p = tryfindfiledir(dom, user, homeface)) != nil)
 			return p;
-		if((p = tryfindfiledir(dom, user, "/lib/face")) != nil)
+		if((p = tryfindfiledir(dom, user, facedir)) != nil)
 			return p;
 		if((dom = strchr(dom, '.')) == nil)
 			break;
@@ -351,13 +351,13 @@
 	}
 
 	f->unknown = 0;
-	if((p = tryfindfile(dom, user)) != nil)
+	if((p = tryfindfile(dom, user, f->str[Sfacedir])) != nil)
 		return p;
 	f->unknown = 1;
-	p = tryfindfile(dom, "unknown");
+	p = tryfindfile(dom, "unknown", f->str[Sfacedir]);
 	if(p != nil || strcmp(dom, facedom) == 0)
 		return p;
-	return tryfindfile("unknown", "unknown");
+	return tryfindfile("unknown", "unknown", f->str[Sfacedir]);
 }
 
 static
diff -r e05e4b6c6546 sys/src/cmd/faces/faces.h
--- a/sys/src/cmd/faces/faces.h	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/faces.h	Wed Oct 14 19:02:10 2020 -0500
@@ -4,6 +4,11 @@
 	Sdomain,
 	Sshow,
 	Sdigest,
+	Sdst,
+	Sfacedir,
+	Sattrs,
+	Swdir,
+	Swinid,
 	Nstring
 };
 
@@ -42,9 +47,6 @@
 };
 
 extern char	date[];
-extern char	*maildir;
-extern char	**maildirs;
-extern int	nmaildirs;
 
 Face*	nextface(void);
 void	findbit(Face*);
@@ -54,7 +56,6 @@
 void	showmail(Face*);
 void	delete(char*, char*);
 void	freefacefile(Facefile*);
-Face*	dirface(char*, char*);
 void	resized(void);
 int	alreadyseen(char*);
 ulong	dirlen(char*);
@@ -63,4 +64,3 @@
 void	*erealloc(void*, ulong);
 char	*estrdup(char*);
 char	*findfile(Face*, char*, char*);
-void	addmaildir(char*);
diff -r e05e4b6c6546 sys/src/cmd/faces/main.c
--- a/sys/src/cmd/faces/main.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/main.c	Wed Oct 14 19:02:10 2020 -0500
@@ -7,9 +7,6 @@
 #include <bio.h>
 #include "faces.h"
 
-int	history = 0;	/* use old interface, showing history of mailbox rather than current state */
-int	initload = 0;	/* initialize program with contents of mail box */
-
 enum
 {
 	Facesep = 6,	/* must be even to avoid damaging background stipple */
@@ -68,7 +65,6 @@
 
 char	date[64];
 Face	**faces;
-char	*maildir = "/mail/fs/mbox";
 ulong	now;
 
 Point	datep = { 8, 6 };
@@ -163,7 +159,7 @@
 	Face *f;
 
 	if(!digest)
-		return 0;
+		return 1;
 
 	/* can do accurate check */
 	for(i=0; i<nfaces; i++){
@@ -358,25 +354,6 @@
 }
 
 void
-loadmboxfaces(char *maildir)
-{
-	int dirfd;
-	Dir *d;
-	int i, n;
-
-	dirfd = open(maildir, OREAD);
-	if(dirfd >= 0){
-		chdir(maildir);
-		while((n = dirread(dirfd, &d)) > 0){
-			for(i=0; i<n; i++)
-				addface(dirface(maildir, d[i].name));
-			free(d);
-		}
-		close(dirfd);
-	}
-}
-
-void
 freeface(Face *f)
 {
 	int i;
@@ -435,16 +412,8 @@
 void
 dodelete(int i)
 {
-	Face *f;
-
-	f = faces[i];
-	if(history){
-		free(f->str[Sshow]);
-		f->str[Sshow] = estrdup("");
-	}else{
-		delface(i);
-		flushimage(display, 1);
-	}
+	delface(i);
+	flushimage(display, 1);
 }
 
 void
@@ -586,25 +555,12 @@
 	case 1:
 		if(scroll(1, p))
 			break;
-		if(history){
-			/* click clears display */
-			lockdisplay(display);
-			for(i=0; i<nfaces; i++)
-				freeface(faces[i]);
-			free(faces);
-			faces=nil;
-			nfaces = 0;
-			unlockdisplay(display);
-			eresized(0);
-			return;
-		}else{
-			for(i=first; i<last; i++)	/* clear vwhois faces */
-				if(ptinrect(p, facerect(i-first)) 
-				&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
-					delface(i);
-					flushimage(display, 1);
-				}
-		}
+		for(i=first; i<last; i++)	/* clear vwhois faces */
+			if(ptinrect(p, facerect(i-first)) 
+			&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
+				delface(i);
+				flushimage(display, 1);
+			}
 		break;
 	case 2:
 		scroll(2, p);
@@ -675,26 +631,14 @@
 void
 usage(void)
 {
-	fprint(2, "usage: faces [-hi] [-m maildir]\n");
+	fprint(2, "usage: faces\n");
 	exits("usage");
 }
 
 void
 main(int argc, char *argv[])
 {
-	int i;
-
 	ARGBEGIN{
-	case 'h':
-		history++;
-		break;
-	case 'i':
-		initload++;
-		break;
-	case 'm':
-		addmaildir(EARGF(usage()));
-		maildir = nil;
-		break;
 	default:
 		usage();
 	}ARGEND
@@ -703,8 +647,6 @@
 		fprint(2, "faces: initdraw failed: %r\n");
 		exits("initdraw");
 	}
-	if(maildir)
-		addmaildir(maildir);
 	init();
 	unlockdisplay(display);	/* initdraw leaves it locked */
 	display->locking = 1;	/* tell library we're using the display lock */
@@ -714,9 +656,6 @@
 	pids[Mainp] = getpid();
 	startproc(timeproc, Timep);
 	startproc(mouseproc, Mousep);
-	if(initload)
-		for(i = 0; i < nmaildirs; i++)
-		 loadmboxfaces(maildirs[i]);
 	faceproc();
 	fprint(2, "faces: %s process exits\n", procnames[Mainp]);
 	killall(nil);
diff -r e05e4b6c6546 sys/src/cmd/faces/plumb.c
--- a/sys/src/cmd/faces/plumb.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/plumb.c	Wed Oct 14 19:02:10 2020 -0500
@@ -6,53 +6,56 @@
 #include <bio.h>
 #include "faces.h"
 
-static int	showfd = -1;
-static int	seefd = -1;
+static int		notefd = -1;
+static int		showfd = -1;
 static char	*user;
-
-char		**maildirs;
-int		nmaildirs;
+static char	*logtag;
 
 void
 initplumb(void)
 {
 	if((showfd = plumbopen("send", OWRITE)) == -1)
 		sysfatal("plumbopen send: %r");
-	if((seefd = plumbopen("seemail", OREAD)) == -1)
-		sysfatal("plumbopen seemail: %r");
-}
-
-void
-addmaildir(char *dir)
-{
-	maildirs = erealloc(maildirs, (nmaildirs+1)*sizeof(char*));
-	maildirs[nmaildirs++] = dir;
-}
-
-char*
-attr(Face *f)
-{
-	static char buf[128];
-
-	if(f->str[Sdigest]){
-		snprint(buf, sizeof buf, "digest=%s", f->str[Sdigest]);
-		return buf;
+	if((notefd = plumbopen("notify", OREAD)) == -1){
+		sysfatal("plumbopen notify: %r);
 	}
-	return nil;
 }
 
 void
 showmail(Face *f)
 {
-	char *s;
-	int n;
+	char *s, buf[73], *fields[6];
+	int n, len, wctl;
 
-	if(showfd<0 || f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
+	if(f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
 		return;
-	s = emalloc(128+strlen(f->str[Sshow])+1);
-	n = sprint(s, "faces\nshowmail\n/mail/fs/\ntext\n%s\n%ld\n%s", attr(f), strlen(f->str[Sshow]), f->str[Sshow]);
-	write(showfd, s, n);
-	free(s);
+	if(f->str[Swinid][0] != '0'){
+		snprint(buf, 73, "/dev/wsys/%s/wctl", f->str[Swinid]);
+		wctl = open(buf, ORDWR);
+		if(wctl < 0)
+			return;
+		if(read(wctl, buf, 72) != 72){
+			close(wctl);
+			return;
+		}
+		buf[72] = '\0';
+		if(tokenize(buf, fields, 6) != 6){
+			close(wctl);
+			return;
+		}
+		if(strcmp(fields[5], "hidden") == 0)
+			write(wctl, "unhide", 6);
+		else
+			write(wctl, "current", 7);
+		close(wctl);
+	}
+	else {
+		len = 128+strlen(f->str[Sdst])+strlen(f->str[Swdir])+strlen(f->str[Sattrs])+strlen(f->str[Sshow])+1;
+		s = emalloc(len);
+		n = snprint(s, len, "faces\n%s\n%s\ntext\n%s\n%ld\n%s", f->str[Sdst], f->str[Swdir], f->str[Sattrs], strlen(f->str[Sshow]), f->str[Sshow]);
+		write(showfd, s, n);
+		free(s);
+	}
 }
 
 char*
@@ -69,7 +72,7 @@
 void
 setname(Face *f, char *sender)
 {
-	char *at, *bang;
+	char *at;
 	char *p;
 
 	/* works with UTF-8, although it's written as ASCII */
@@ -82,13 +85,6 @@
 		f->str[Sdomain] = estrdup(at);
 		return;
 	}
-	bang = strchr(sender, '!');
-	if(bang){
-		*bang++ = '\0';
-		f->str[Suser] = estrdup(bang);
-		f->str[Sdomain] = sender;
-		return;
-	}
 }
 
 ulong
@@ -123,117 +119,57 @@
 Face*
 nextface(void)
 {
-	int i;
 	Face *f;
 	Plumbmsg *m;
-	char *t, *senderp, *showmailp, *digestp;
+	char *senderp, *showmailp, *digestp, *dstp, *facep, *winid;
 	ulong xtime;
+	Dir *facedir;
 
 	f = emalloc(sizeof(Face));
 	for(;;){
-		m = plumbrecv(seefd);
+		m = plumbrecv(notefd);
 		if(m == nil)
-			killall("error on seemail plumb port");
-		t = value(m->attr, "mailtype", "");
-		if(strcmp(t, "modify") == 0)
-			goto Ignore;
-		else if(strcmp(t, "delete") == 0)
-			delete(m->data, value(m->attr, "digest", nil));
-		else if(strcmp(t, "new") == 0)
-			for(i=0; i<nmaildirs; i++){
-				if(strncmp(m->data, maildirs[i], strlen(maildirs[i])) == 0)
-					goto Found;
-			}
-		else
-			fprint(2, "faces: unknown plumb message type %s\n", t);
-	Ignore:
-		plumbfree(m);
-		continue;
-
-	Found:
-		xtime = parsedate(value(m->attr, "date", date));
-		digestp = value(m->attr, "digest", nil);
+			killall("error on notify plumb port");
+		digestp = estrdup(value(m->attr, "digest", "inedible"));
 		if(alreadyseen(digestp)){
-			/* duplicate upas/fs can send duplicate messages */
+			/* duplicate programs can send duplicate messages */
 			plumbfree(m);
 			continue;
 		}
-		senderp = estrdup(value(m->attr, "sender", "???"));
+		facep = estrdup(value(m->attr, "facedir", "/lib/face"));
+		if(access(facep, AEXIST) == 0){
+			facedir = dirstat(facep);
+			if(facedir == nil){
+				plumbfree(m);
+				continue;
+			}
+			if(facedir->qid.type != QTDIR){
+				free(facedir);
+				plumbfree(m);
+				continue;
+			}
+			free(facedir);
+		}
+		else {
+			plumbfree(m);
+			continue;
+		}
+		dstp = estrdup(value(m->attr, "dst", "none"));
+		senderp = estrdup(value(m->attr, "sender", "unknown"));
+		winid = estrdup(value(m->attr, "winid", "0"));
+		xtime = parsedate(value(m->attr, "date", date));
 		showmailp = estrdup(m->data);
-		if(digestp)
-			digestp = estrdup(digestp);
+		f->str[Sattrs] = plumbpackattr(m->attr);
+		f->str[Swdir] = estrdup(m->wdir);
 		plumbfree(m);
 		setname(f, senderp);
 		f->time = xtime;
 		f->tm = *localtime(xtime);
 		f->str[Sshow] = showmailp;
 		f->str[Sdigest] = digestp;
+		f->str[Sdst] = dstp;
+		f->str[Sfacedir] = facep;
+		f->str[Swinid] = winid;
 		return f;
 	}
 }
-
-char*
-iline(char *data, char **pp)
-{
-	char *p;
-
-	for(p=data; *p!='\0' && *p!='\n'; p++)
-		;
-	if(*p == '\n')
-		*p++ = '\0';
-	*pp = p;
-	return data;
-}
-
-Face*
-dirface(char *dir, char *num)
-{
-	Face *f;
-	char *from, *date;
-	char buf[1024], pwd[1024], *info, *p, *digest;
-	int n, fd;
-	ulong len;
-
-	/*
-	 * loadmbox leaves us in maildir, so we needn't
-	 * walk /mail/fs/mbox for each face; this makes startup
-	 * a fair bit quicker.
-	 */
-	if(getwd(pwd, sizeof pwd) != nil && strcmp(pwd, dir) == 0)
-		sprint(buf, "%s/info", num);
-	else
-		sprint(buf, "%s/%s/info", dir, num);
-	len = dirlen(buf);
-	if(len <= 0)
-		return nil;
-	fd = open(buf, OREAD);
-	if(fd < 0)
-		return nil;
-	info = emalloc(len+1);
-	n = readn(fd, info, len);
-	close(fd);
-	if(n < 0){
-		free(info);
-		return nil;
-	}
-	info[n] = '\0';
-	f = emalloc(sizeof(Face));
-	from = iline(info, &p);	/* from */
-	iline(p, &p);	/* to */
-	iline(p, &p);	/* cc */
-	iline(p, &p);	/* replyto */
-	date = iline(p, &p);	/* date */
-	setname(f, estrdup(from));
-	f->time = parsedate(date);
-	f->tm = *localtime(f->time);
-	sprint(buf, "%s/%s", dir, num);
-	f->str[Sshow] = estrdup(buf);
-	iline(p, &p);	/* subject */
-	iline(p, &p);	/* mime content type */
-	iline(p, &p);	/* mime disposition */
-	iline(p, &p);	/* filename */
-	digest = iline(p, &p);	/* digest */
-	f->str[Sdigest] = estrdup(digest);
-	free(info);
-	return f;
-}
diff -r e05e4b6c6546 sys/src/cmd/upas/Mail/mail.c
--- a/sys/src/cmd/upas/Mail/mail.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/upas/Mail/mail.c	Wed Oct 14 19:02:10 2020 -0500
@@ -86,7 +86,7 @@
 
 	/* open these early so we won't miss notification of new mail messages while we read mbox */
 	plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
-	plumbseemailfd = plumbopen("seemail", OREAD|OCEXEC);
+	plumbseemailfd = plumbopen("notify", OREAD|OCEXEC);
 	plumbshowmailfd = plumbopen("showmail", OREAD|OCEXEC);
 
 	shortmenu = 0;
diff -r e05e4b6c6546 sys/src/cmd/upas/fs/mbox.c
--- a/sys/src/cmd/upas/fs/mbox.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/upas/fs/mbox.c	Wed Oct 14 19:02:10 2020 -0500
@@ -1547,11 +1547,12 @@
 static void
 mailplumb(Mailbox *mb, Message *m)
 {
-	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], *from, *subject;
+	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], addr[320], *from, *subject, *bang, *unixfrom;
 	int ai;
 	Plumbmsg p;
 	Plumbattr a[7];
 	static int fd = -1;
+	int didflip;
 
 	subject = m->subject;
 	if(subject == nil)
@@ -1572,8 +1573,27 @@
 	if(fd < 0)
 		return;
 
+	/* convert uucp address for faces */
+	didflip = 0;
+	if(from == m->unixfrom){
+		unixfrom = strdup(m->unixfrom);
+		if(unixfrom == nil)
+			return;
+		bang = strchr(unixfrom, '!');
+		*bang++ = '\0';
+		strcpy(addr, bang);
+		strcat(addr, "@");
+		strcat(addr, unixfrom);
+		from = strdup(addr);
+		if(from == nil){
+			free(unixfrom);
+			return;
+		}
+		didflip++;
+	}
+
 	p.src = "mailfs";
-	p.dst = "seemail";
+	p.dst = "notify";
 	p.wdir = "/mail/fs";
 	p.type = "text";
 
@@ -1603,12 +1623,18 @@
 	a[ai].value = date;
 	a[ai-1].next = &a[ai];
 
-	if(m->digest){
-		snprint(dbuf, sizeof dbuf, "%A", m->digest);
-		a[++ai].name = "digest";
-		a[ai].value = dbuf;
-		a[ai-1].next = &a[ai];
-	}
+	if(m->digest == nil)
+		digestmessage(mb, m);
+	snprint(dbuf, sizeof dbuf, "%A", m->digest);
+	
+	a[++ai].name = "digest";
+	a[ai].value = dbuf;
+	a[ai-1].next = &a[ai];
+
+	a[++ai].name = "dst";
+	a[ai].value = "showmail";
+	a[ai-1].next = &a[ai];
+	
 	a[ai].next = nil;
 	p.attr = a;
 	snprint(buf, sizeof buf, "%s/%s/%s",
@@ -1617,6 +1643,11 @@
 	p.data = buf;
 
 	myplumbsend(fd, &p);
+
+	if(didflip != 0){
+		free(unixfrom);
+		free(from);
+	}
 }
 
 /*

[-- Attachment #2: Type: text/plain, Size: 15625 bytes --]

Return-Path: <covertusername967@gmail.com>
Received: from pi9term.covert9net (67-198-106-217.dyn.grandenetworks.net. [67.198.106.217])
        by smtp.gmail.com with ESMTPSA id j83sm453477oia.19.2020.10.14.16.42.35
        (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);
        Wed, 14 Oct 2020 16:42:36 -0700 (PDT)
From: covertusername967@gmail.com
X-Google-Original-From: glenda@gmail.com
Message-ID: <4EDC5C64B03145DA8A66C77F737FA4A1@gmail.com>
To: covertusername967@gmail.com, 9front@9front.org
Subject: [9front] make faces generic
Date: Wed, 14 Oct 2020 18:42:35 -0500
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit

Hello,

The following patch allows faces to receive notifications from
programs other than the mail system.  As an example, a modification of
ircrc has been included that allows it to send any received mentions
to faces.  Some minor changes were made to upas/fs to support this.  I
have been running this patch for a few weeks now with no issues,
although I will say that I do not personally use ircrc.

diff -r e05e4b6c6546 rc/bin/ircrc
--- a/rc/bin/ircrc	Mon Oct 12 02:03:52 2020 +0200
+++ b/rc/bin/ircrc	Wed Oct 14 18:35:56 2020 -0500
@@ -169,6 +169,14 @@
 		switch ($line) {
 		case *PRIVMSG*
 			line = `{echo -n $line | privmsg}
+			switch($line) {
+			case *^$nick^*
+				digest = ircrc.$pid.`{date -n}
+				sender = `{echo -n $line | sed 'y/«»/  /' | awk '{print $2}'}
+				data = `{echo -n $line | sed 'y/()/  /' | awk '{print $1}'}
+				winid = `{cat /dev/winid}
+				plumb -dnotify -a 'digest='^$digest^' dst=irc sender='^$sender^'@'^$server^' winid='^$winid^' date='''^`"{date}^'''' -s ircrc $data
+			}
 		case *JOIN* *QUIT* *PART* *NICK*
 			line = `{echo -n $line | misc}
 		case *NOTICE*
diff -r e05e4b6c6546 rc/bin/vwhois
--- a/rc/bin/vwhois	Mon Oct 12 02:03:52 2020 +0200
+++ b/rc/bin/vwhois	Wed Oct 14 18:35:56 2020 -0500
@@ -2,16 +2,5 @@
 
 rfork e
 
-box=mbox
-if(! test -d /mail/fs/$box)
-	box=`{ls -p /mail/fs | grep -v ctl | sed 1q}
-if(~ $#box 0)
-	box=mbox	# we tried
-
-if(~ $#box 1 && test -f /mnt/plumb/seemail || test -f /mnt/term/mnt/plumb/seemail){
-	for(i)
-		plumb -dseemail -a 'filetype=vwhois digest='$i.$pid' mailtype=new sender='$i /mail/fs/$box/XXXvwhois
-}
-if not for (i){
-	echo vwhois: vwhois: vwhois: delivered `{cat /dev/user} From $i '(vwho)' >> /sys/log/mail
-}
+for(i)
+	plumb -dnotify -a 'digest='$i.$pid' sender='$i /XXXvwhois
diff -r e05e4b6c6546 sys/lib/plumb/basic
--- a/sys/lib/plumb/basic	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/lib/plumb/basic	Wed Oct 14 18:35:56 2020 -0500
@@ -4,8 +4,8 @@
 include fileaddr
 
 # declarations of ports without rules
-plumb to seemail
 plumb to showmail
+plumb to notify
 
 # open urls with web browser
 type is text
diff -r e05e4b6c6546 sys/src/cmd/faces/facedb.c
--- a/sys/src/cmd/faces/facedb.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/facedb.c	Wed Oct 14 18:35:56 2020 -0500
@@ -315,14 +315,14 @@
 }
 
 static char*
-tryfindfile(char *dom, char *user)
+tryfindfile(char *dom, char *user, char *facedir)
 {
 	char *p;
 
 	while(dom && *dom){
 		if(homeface && (p = tryfindfiledir(dom, user, homeface)) != nil)
 			return p;
-		if((p = tryfindfiledir(dom, user, "/lib/face")) != nil)
+		if((p = tryfindfiledir(dom, user, facedir)) != nil)
 			return p;
 		if((dom = strchr(dom, '.')) == nil)
 			break;
@@ -351,13 +351,13 @@
 	}
 
 	f->unknown = 0;
-	if((p = tryfindfile(dom, user)) != nil)
+	if((p = tryfindfile(dom, user, f->str[Sfacedir])) != nil)
 		return p;
 	f->unknown = 1;
-	p = tryfindfile(dom, "unknown");
+	p = tryfindfile(dom, "unknown", f->str[Sfacedir]);
 	if(p != nil || strcmp(dom, facedom) == 0)
 		return p;
-	return tryfindfile("unknown", "unknown");
+	return tryfindfile("unknown", "unknown", f->str[Sfacedir]);
 }
 
 static
diff -r e05e4b6c6546 sys/src/cmd/faces/faces.h
--- a/sys/src/cmd/faces/faces.h	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/faces.h	Wed Oct 14 18:35:56 2020 -0500
@@ -4,6 +4,11 @@
 	Sdomain,
 	Sshow,
 	Sdigest,
+	Sdst,
+	Sfacedir,
+	Sattrs,
+	Swdir,
+	Swinid,
 	Nstring
 };
 
@@ -42,9 +47,6 @@
 };
 
 extern char	date[];
-extern char	*maildir;
-extern char	**maildirs;
-extern int	nmaildirs;
 
 Face*	nextface(void);
 void	findbit(Face*);
@@ -54,7 +56,6 @@
 void	showmail(Face*);
 void	delete(char*, char*);
 void	freefacefile(Facefile*);
-Face*	dirface(char*, char*);
 void	resized(void);
 int	alreadyseen(char*);
 ulong	dirlen(char*);
@@ -63,4 +64,3 @@
 void	*erealloc(void*, ulong);
 char	*estrdup(char*);
 char	*findfile(Face*, char*, char*);
-void	addmaildir(char*);
diff -r e05e4b6c6546 sys/src/cmd/faces/main.c
--- a/sys/src/cmd/faces/main.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/main.c	Wed Oct 14 18:35:56 2020 -0500
@@ -7,9 +7,6 @@
 #include <bio.h>
 #include "faces.h"
 
-int	history = 0;	/* use old interface, showing history of mailbox rather than current state */
-int	initload = 0;	/* initialize program with contents of mail box */
-
 enum
 {
 	Facesep = 6,	/* must be even to avoid damaging background stipple */
@@ -68,7 +65,6 @@
 
 char	date[64];
 Face	**faces;
-char	*maildir = "/mail/fs/mbox";
 ulong	now;
 
 Point	datep = { 8, 6 };
@@ -163,7 +159,7 @@
 	Face *f;
 
 	if(!digest)
-		return 0;
+		return 1;
 
 	/* can do accurate check */
 	for(i=0; i<nfaces; i++){
@@ -358,25 +354,6 @@
 }
 
 void
-loadmboxfaces(char *maildir)
-{
-	int dirfd;
-	Dir *d;
-	int i, n;
-
-	dirfd = open(maildir, OREAD);
-	if(dirfd >= 0){
-		chdir(maildir);
-		while((n = dirread(dirfd, &d)) > 0){
-			for(i=0; i<n; i++)
-				addface(dirface(maildir, d[i].name));
-			free(d);
-		}
-		close(dirfd);
-	}
-}
-
-void
 freeface(Face *f)
 {
 	int i;
@@ -435,16 +412,8 @@
 void
 dodelete(int i)
 {
-	Face *f;
-
-	f = faces[i];
-	if(history){
-		free(f->str[Sshow]);
-		f->str[Sshow] = estrdup("");
-	}else{
-		delface(i);
-		flushimage(display, 1);
-	}
+	delface(i);
+	flushimage(display, 1);
 }
 
 void
@@ -586,25 +555,12 @@
 	case 1:
 		if(scroll(1, p))
 			break;
-		if(history){
-			/* click clears display */
-			lockdisplay(display);
-			for(i=0; i<nfaces; i++)
-				freeface(faces[i]);
-			free(faces);
-			faces=nil;
-			nfaces = 0;
-			unlockdisplay(display);
-			eresized(0);
-			return;
-		}else{
-			for(i=first; i<last; i++)	/* clear vwhois faces */
-				if(ptinrect(p, facerect(i-first)) 
-				&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
-					delface(i);
-					flushimage(display, 1);
-				}
-		}
+		for(i=first; i<last; i++)	/* clear vwhois faces */
+			if(ptinrect(p, facerect(i-first)) 
+			&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
+				delface(i);
+				flushimage(display, 1);
+			}
 		break;
 	case 2:
 		scroll(2, p);
@@ -675,26 +631,14 @@
 void
 usage(void)
 {
-	fprint(2, "usage: faces [-hi] [-m maildir]\n");
+	fprint(2, "usage: faces\n");
 	exits("usage");
 }
 
 void
 main(int argc, char *argv[])
 {
-	int i;
-
 	ARGBEGIN{
-	case 'h':
-		history++;
-		break;
-	case 'i':
-		initload++;
-		break;
-	case 'm':
-		addmaildir(EARGF(usage()));
-		maildir = nil;
-		break;
 	default:
 		usage();
 	}ARGEND
@@ -703,8 +647,6 @@
 		fprint(2, "faces: initdraw failed: %r\n");
 		exits("initdraw");
 	}
-	if(maildir)
-		addmaildir(maildir);
 	init();
 	unlockdisplay(display);	/* initdraw leaves it locked */
 	display->locking = 1;	/* tell library we're using the display lock */
@@ -714,9 +656,6 @@
 	pids[Mainp] = getpid();
 	startproc(timeproc, Timep);
 	startproc(mouseproc, Mousep);
-	if(initload)
-		for(i = 0; i < nmaildirs; i++)
-		 loadmboxfaces(maildirs[i]);
 	faceproc();
 	fprint(2, "faces: %s process exits\n", procnames[Mainp]);
 	killall(nil);
diff -r e05e4b6c6546 sys/src/cmd/faces/plumb.c
--- a/sys/src/cmd/faces/plumb.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/faces/plumb.c	Wed Oct 14 18:35:56 2020 -0500
@@ -6,53 +6,56 @@
 #include <bio.h>
 #include "faces.h"
 
-static int	showfd = -1;
-static int	seefd = -1;
+static int		notefd = -1;
+static int		showfd = -1;
 static char	*user;
-
-char		**maildirs;
-int		nmaildirs;
+static char	*logtag;
 
 void
 initplumb(void)
 {
 	if((showfd = plumbopen("send", OWRITE)) == -1)
 		sysfatal("plumbopen send: %r");
-	if((seefd = plumbopen("seemail", OREAD)) == -1)
-		sysfatal("plumbopen seemail: %r");
-}
-
-void
-addmaildir(char *dir)
-{
-	maildirs = erealloc(maildirs, (nmaildirs+1)*sizeof(char*));
-	maildirs[nmaildirs++] = dir;
-}
-
-char*
-attr(Face *f)
-{
-	static char buf[128];
-
-	if(f->str[Sdigest]){
-		snprint(buf, sizeof buf, "digest=%s", f->str[Sdigest]);
-		return buf;
+	if((notefd = plumbopen("notify", OREAD)) == -1){
+		sysfatal("plumbopen notify: %r);
 	}
-	return nil;
 }
 
 void
 showmail(Face *f)
 {
-	char *s;
-	int n;
+	char *s, buf[73], *fields[6];
+	int n, len, wctl;
 
-	if(showfd<0 || f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
+	if(f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
 		return;
-	s = emalloc(128+strlen(f->str[Sshow])+1);
-	n = sprint(s, "faces\nshowmail\n/mail/fs/\ntext\n%s\n%ld\n%s", attr(f), strlen(f->str[Sshow]), f->str[Sshow]);
-	write(showfd, s, n);
-	free(s);
+	if(f->str[Swinid][0] != '0'){
+		snprint(buf, 73, "/dev/wsys/%s/wctl", f->str[Swinid]);
+		wctl = open(buf, ORDWR);
+		if(wctl < 0)
+			return;
+		if(read(wctl, buf, 72) != 72){
+			close(wctl);
+			return;
+		}
+		buf[72] = '\0';
+		if(tokenize(buf, fields, 6) != 6){
+			close(wctl);
+			return;
+		}
+		if(strcmp(fields[5], "hidden") == 0)
+			write(wctl, "unhide", 6);
+		else
+			write(wctl, "current", 7);
+		close(wctl);
+	}
+	else {
+		len = 128+strlen(f->str[Sdst])+strlen(f->str[Swdir])+strlen(f->str[Sattrs])+strlen(f->str[Sshow])+1;
+		s = emalloc(len);
+		n = snprint(s, len, "faces\n%s\n%s\ntext\n%s\n%ld\n%s", f->str[Sdst], f->str[Swdir], f->str[Sattrs], strlen(f->str[Sshow]), f->str[Sshow]);
+		write(showfd, s, n);
+		free(s);
+	}
 }
 
 char*
@@ -69,7 +72,7 @@
 void
 setname(Face *f, char *sender)
 {
-	char *at, *bang;
+	char *at;
 	char *p;
 
 	/* works with UTF-8, although it's written as ASCII */
@@ -82,13 +85,6 @@
 		f->str[Sdomain] = estrdup(at);
 		return;
 	}
-	bang = strchr(sender, '!');
-	if(bang){
-		*bang++ = '\0';
-		f->str[Suser] = estrdup(bang);
-		f->str[Sdomain] = sender;
-		return;
-	}
 }
 
 ulong
@@ -123,117 +119,57 @@
 Face*
 nextface(void)
 {
-	int i;
 	Face *f;
 	Plumbmsg *m;
-	char *t, *senderp, *showmailp, *digestp;
+	char *senderp, *showmailp, *digestp, *dstp, *facep, *winid;
 	ulong xtime;
+	Dir *facedir;
 
 	f = emalloc(sizeof(Face));
 	for(;;){
-		m = plumbrecv(seefd);
+		m = plumbrecv(notefd);
 		if(m == nil)
-			killall("error on seemail plumb port");
-		t = value(m->attr, "mailtype", "");
-		if(strcmp(t, "modify") == 0)
-			goto Ignore;
-		else if(strcmp(t, "delete") == 0)
-			delete(m->data, value(m->attr, "digest", nil));
-		else if(strcmp(t, "new") == 0)
-			for(i=0; i<nmaildirs; i++){
-				if(strncmp(m->data, maildirs[i], strlen(maildirs[i])) == 0)
-					goto Found;
-			}
-		else
-			fprint(2, "faces: unknown plumb message type %s\n", t);
-	Ignore:
-		plumbfree(m);
-		continue;
-
-	Found:
-		xtime = parsedate(value(m->attr, "date", date));
-		digestp = value(m->attr, "digest", nil);
+			killall("error on notify plumb port");
+		digestp = estrdup(value(m->attr, "digest", "inedible"));
 		if(alreadyseen(digestp)){
-			/* duplicate upas/fs can send duplicate messages */
+			/* duplicate programs can send duplicate messages */
 			plumbfree(m);
 			continue;
 		}
-		senderp = estrdup(value(m->attr, "sender", "???"));
+		facep = estrdup(value(m->attr, "facedir", "/lib/face"));
+		if(access(facep, AEXIST) == 0){
+			facedir = dirstat(facep);
+			if(facedir == nil){
+				plumbfree(m);
+				continue;
+			}
+			if(facedir->qid.type != QTDIR){
+				free(facedir);
+				plumbfree(m);
+				continue;
+			}
+			free(facedir);
+		}
+		else {
+			plumbfree(m);
+			continue;
+		}
+		dstp = estrdup(value(m->attr, "dst", "none"));
+		senderp = estrdup(value(m->attr, "sender", "unknown"));
+		winid = estrdup(value(m->attr, "winid", "0"));
+		xtime = parsedate(value(m->attr, "date", date));
 		showmailp = estrdup(m->data);
-		if(digestp)
-			digestp = estrdup(digestp);
+		f->str[Sattrs] = plumbpackattr(m->attr);
+		f->str[Swdir] = estrdup(m->wdir);
 		plumbfree(m);
 		setname(f, senderp);
 		f->time = xtime;
 		f->tm = *localtime(xtime);
 		f->str[Sshow] = showmailp;
 		f->str[Sdigest] = digestp;
+		f->str[Sdst] = dstp;
+		f->str[Sfacedir] = facep;
+		f->str[Swinid] = winid;
 		return f;
 	}
 }
-
-char*
-iline(char *data, char **pp)
-{
-	char *p;
-
-	for(p=data; *p!='\0' && *p!='\n'; p++)
-		;
-	if(*p == '\n')
-		*p++ = '\0';
-	*pp = p;
-	return data;
-}
-
-Face*
-dirface(char *dir, char *num)
-{
-	Face *f;
-	char *from, *date;
-	char buf[1024], pwd[1024], *info, *p, *digest;
-	int n, fd;
-	ulong len;
-
-	/*
-	 * loadmbox leaves us in maildir, so we needn't
-	 * walk /mail/fs/mbox for each face; this makes startup
-	 * a fair bit quicker.
-	 */
-	if(getwd(pwd, sizeof pwd) != nil && strcmp(pwd, dir) == 0)
-		sprint(buf, "%s/info", num);
-	else
-		sprint(buf, "%s/%s/info", dir, num);
-	len = dirlen(buf);
-	if(len <= 0)
-		return nil;
-	fd = open(buf, OREAD);
-	if(fd < 0)
-		return nil;
-	info = emalloc(len+1);
-	n = readn(fd, info, len);
-	close(fd);
-	if(n < 0){
-		free(info);
-		return nil;
-	}
-	info[n] = '\0';
-	f = emalloc(sizeof(Face));
-	from = iline(info, &p);	/* from */
-	iline(p, &p);	/* to */
-	iline(p, &p);	/* cc */
-	iline(p, &p);	/* replyto */
-	date = iline(p, &p);	/* date */
-	setname(f, estrdup(from));
-	f->time = parsedate(date);
-	f->tm = *localtime(f->time);
-	sprint(buf, "%s/%s", dir, num);
-	f->str[Sshow] = estrdup(buf);
-	iline(p, &p);	/* subject */
-	iline(p, &p);	/* mime content type */
-	iline(p, &p);	/* mime disposition */
-	iline(p, &p);	/* filename */
-	digest = iline(p, &p);	/* digest */
-	f->str[Sdigest] = estrdup(digest);
-	free(info);
-	return f;
-}
diff -r e05e4b6c6546 sys/src/cmd/upas/fs/mbox.c
--- a/sys/src/cmd/upas/fs/mbox.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/upas/fs/mbox.c	Wed Oct 14 18:35:56 2020 -0500
@@ -1547,11 +1547,12 @@
 static void
 mailplumb(Mailbox *mb, Message *m)
 {
-	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], *from, *subject;
+	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], addr[320], *from, *subject, *bang, *unixfrom;
 	int ai;
 	Plumbmsg p;
 	Plumbattr a[7];
 	static int fd = -1;
+	int didflip;
 
 	subject = m->subject;
 	if(subject == nil)
@@ -1572,8 +1573,27 @@
 	if(fd < 0)
 		return;
 
+	/* convert uucp address for faces */
+	didflip = 0;
+	if(from == m->unixfrom){
+		unixfrom = strdup(m->unixfrom);
+		if(unixfrom == nil)
+			return;
+		bang = strchr(unixfrom, '!');
+		*bang++ = '\0';
+		strcpy(addr, bang);
+		strcat(addr, "@");
+		strcat(addr, unixfrom);
+		from = strdup(addr);
+		if(from == nil){
+			free(unixfrom);
+			return;
+		}
+		didflip++;
+	}
+
 	p.src = "mailfs";
-	p.dst = "seemail";
+	p.dst = "notify";
 	p.wdir = "/mail/fs";
 	p.type = "text";
 
@@ -1603,12 +1623,18 @@
 	a[ai].value = date;
 	a[ai-1].next = &a[ai];
 
-	if(m->digest){
-		snprint(dbuf, sizeof dbuf, "%A", m->digest);
-		a[++ai].name = "digest";
-		a[ai].value = dbuf;
-		a[ai-1].next = &a[ai];
-	}
+	if(m->digest == nil)
+		digestmessage(mb, m);
+	snprint(dbuf, sizeof dbuf, "%A", m->digest);
+	
+	a[++ai].name = "digest";
+	a[ai].value = dbuf;
+	a[ai-1].next = &a[ai];
+
+	a[++ai].name = "dst";
+	a[ai].value = "showmail";
+	a[ai-1].next = &a[ai];
+	
 	a[ai].next = nil;
 	p.attr = a;
 	snprint(buf, sizeof buf, "%s/%s/%s",
@@ -1617,6 +1643,11 @@
 	p.data = buf;
 
 	myplumbsend(fd, &p);
+
+	if(didflip != 0){
+		free(unixfrom);
+		free(from);
+	}
 }
 
 /*

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9front] make faces generic
  2020-10-14 23:42 [9front] make faces generic covertusername967
  2020-10-15  3:24 ` covertusername967
@ 2020-10-17  0:26 ` Alex Musolino
  2020-10-17  1:07   ` covertusername967
  1 sibling, 1 reply; 7+ messages in thread
From: Alex Musolino @ 2020-10-17  0:26 UTC (permalink / raw)
  To: 9front

I like my faces(1) with -i.  Maybe it would be better just write
a new program?


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9front] make faces generic
  2020-10-17  0:26 ` Alex Musolino
@ 2020-10-17  1:07   ` covertusername967
  2020-10-17  1:14     ` Silas McCroskey
  0 siblings, 1 reply; 7+ messages in thread
From: covertusername967 @ 2020-10-17  1:07 UTC (permalink / raw)
  To: alex, 9front

[-- Attachment #1: Type: text/plain, Size: 5137 bytes --]

I could probably put together an 'finit' control messages for
/mail/fs/ctl that does the same thing.  Also, here's a patch for the
manpage, as well as one that removes /bin/seemail:

diff -r e05e4b6c6546 rc/bin/seemail
--- a/rc/bin/seemail	Mon Oct 12 02:03:52 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-#!/bin/rc
-
-if(~ $1 -i) exec faces -hi
-if not exec faces -h




diff -r e05e4b6c6546 sys/man/1/faces
--- a/sys/man/1/faces	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/man/1/faces	Fri Oct 16 20:06:45 2020 -0500
@@ -1,124 +1,77 @@
 .TH FACES 1
 .SH NAME
-faces, seemail, vwhois \-  mailbox interface
+faces, vwhois \-  notification interface
 .SH SYNOPSIS
 .B faces
-[
-.B -ih
-] [
-.B -m
-.I maildir
-]
-.br
-.B seemail
-.br
+
 .B vwhois
 .I person
 \&...
 .SH DESCRIPTION
 The
 .I faces
-command monitors incoming mail and
-displays in its window a representation of the user's mail box
-using a small image for each message.
+command monitors /mnt/plumb/notify and
+displays faces in its window for each well-formed message recieved
+on this port.
 The image is typically a portrait of the sender. Which image to 
-display is determined by two directories /usr/$user/lib/face 
-and /lib/face. Entries in /usr/$user/lib/face take priority over 
-those in /lib/face. See 
+display is determined by the `sender' and `facedir' attributes
+in the plumb message, with facedir defaulting to /lib/face. Entries in 
+/usr/$user/lib/face take priority over those in facedir. See 
 .IR face (6),
 for how these directories are organised.
-.PP
-If the user is running
-.IR plumber (4),
-.I faces
-reacts to plumb messages to the
-.B seemail
-port,
-typically from
-.BR upas/fs ,
-and is thus notified of message additions and deletions.
+Additionally, the `sender' attribute can optionally be formatted as follows:
+.EX
+	sender@site
+.EE
+This allows further control over which face is shown.
 .PP
 Right-clicking on a message icon causes that message to be `plumbed' to
-.BR showmail .
-A typical plumb action will be to display the message, such as by
-the rule
+the destination port specified in the original plumbing message, in the 
+`dst' attribute.
+Usually, the original generating application is listening on this port,
+but if it is not, a plumbing rule can be specified like
 .EX
     plumb start window mail -s $0
 .EE
-The
-.IR acme (1)
-mail reader listens to the
-.B showmail
-port automatically.
+If not specified, the message is plumbed back to the `none' port.
+All of the attributes specified in the original message are preserved; faces
+simply ignores extraneous ones. The `wdir' field in the original message is
+preserved similarly.
+Programs can also sent a `winid' attribute.  Faces will make the
+window with that id current.
 .PP
-If the user is not running
-.IR plumber ,
-.I faces
-reads the log file
-.F /sys/log/mail
-and right-clicking has no effect.
+An optional attribute is a `date' \- this is used to provide a more
+accurate timestamp. If unset, faces will use the date it received the
+notification, potentially differing from the date of the event that
+generated the notification.
+.PP
+The `data' field of the plumbing message should be something unique that
+allows the originating application to distinguish between notifications.
+It is sent back to the application unaltered when the face is clicked
+as the resulting plumbing message's `data' field.
+The `digest' attribute should be a hash of the `data' field concatenated
+with the application's name, to prevent hash collisions between
+applications that might be using the same hash algorithm and similar
+contents of `data' .
 .PP
 If arrows are visible, clicking on them will scroll the display.
 Middle-clicking on the arrows scrolls to the end.
 .PP
-Starting
-.B faces
-with the
-.B -i
-flag causes
-.B faces
-to read the messages in
-.BR /mail/fs/mbox
-— or the mailboxes specified with the
-.B -m
-flag —
-upon startup.
-.PP
-The
-.B -m
-option directs
-.I faces
-to watch for messages arriving in
-.I maildir
-instead of
-.BR /mail/fs/mbox .
-Multiple
-.B -m
-flags may be used to watch multiple mailboxes.
-.PP
-The
-.B -h
-flag causes a different, venerable behavior in which
-the window displays the history of messages received
-rather than the current state of the mail box.
-In particular, faces are not removed from the screen when messages are deleted.
-Also, in this mode clicking button 1 in the display will clear the window.
-.PP
-.I Seemail
-is an
-.IR rc (1)
-script that invokes
-.B faces
-.BR -h .
-.PP
 .I Vwhois
 tells
 .I faces
 to display the icons of the named
-.IR persons ,
-without sending a message.
+.IR persons .
 .SH FILES
-.BR /mail/fs/mbox   "   mail directory.
+.BR /mnt/plumb/notify   "   the destination port for notifications.
 .SH SOURCE
 .B /sys/src/cmd/faces
 .br
-.B /rc/bin/seemail
-.br
 .B /rc/bin/vwhois
 .SH "SEE ALSO"
-.IR mail (1),
-.IR marshal (1),
-.IR nedmail (1),
 .IR plumber (4),
 .IR face (6),
 .IR plumb (6)
+.SH BUGS
+There is no -i option anymore; instead, programs that wish to re-send old
+notifications should provide their own options to do so.

[-- Attachment #2: Type: message/rfc822, Size: 3389 bytes --]

From: Alex Musolino <alex@musolino.id.au>
To: 9front@9front.org
Subject: Re: [9front] make faces generic
Date: Sat, 17 Oct 2020 10:56:40 +1030
Message-ID: <290B9ACF9C13F61A73FEB935403A46E7@musolino.id.au>

I like my faces(1) with -i.  Maybe it would be better just write
a new program?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9front] make faces generic
  2020-10-17  1:07   ` covertusername967
@ 2020-10-17  1:14     ` Silas McCroskey
  0 siblings, 0 replies; 7+ messages in thread
From: Silas McCroskey @ 2020-10-17  1:14 UTC (permalink / raw)
  To: 9front; +Cc: alex

> I like my faces(1) with -i.  Maybe it would be better just write
> a new program?

I got http://sam-d.org/thumbs/ to a
usable-but-not-really-good-enough-to-share state years ago and have
been dragging my feet on getting it into a releasable state since
then. Someone might be interested in picking up where I left off, or
I'll get around to it when I finally quit my life-force-draining job.

The more annoying bugs:
* should really be a separate client and server, so that the server
can live on after the client disconnects (especially for the IRC
notifier use case)
* no way to scroll when the number of thumbnails exceeds what's
displayable on the window
* sometimes deleted thumbnails stick around

- sam-d

On Fri, Oct 16, 2020 at 6:08 PM <covertusername967@gmail.com> wrote:
>
> I could probably put together an 'finit' control messages for
> /mail/fs/ctl that does the same thing.  Also, here's a patch for the
> manpage, as well as one that removes /bin/seemail:
>
> diff -r e05e4b6c6546 rc/bin/seemail
> --- a/rc/bin/seemail    Mon Oct 12 02:03:52 2020 +0200
> +++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
> @@ -1,4 +0,0 @@
> -#!/bin/rc
> -
> -if(~ $1 -i) exec faces -hi
> -if not exec faces -h
>
>
>
>
> diff -r e05e4b6c6546 sys/man/1/faces
> --- a/sys/man/1/faces   Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/man/1/faces   Fri Oct 16 20:06:45 2020 -0500
> @@ -1,124 +1,77 @@
>  .TH FACES 1
>  .SH NAME
> -faces, seemail, vwhois \-  mailbox interface
> +faces, vwhois \-  notification interface
>  .SH SYNOPSIS
>  .B faces
> -[
> -.B -ih
> -] [
> -.B -m
> -.I maildir
> -]
> -.br
> -.B seemail
> -.br
> +
>  .B vwhois
>  .I person
>  \&...
>  .SH DESCRIPTION
>  The
>  .I faces
> -command monitors incoming mail and
> -displays in its window a representation of the user's mail box
> -using a small image for each message.
> +command monitors /mnt/plumb/notify and
> +displays faces in its window for each well-formed message recieved
> +on this port.
>  The image is typically a portrait of the sender. Which image to
> -display is determined by two directories /usr/$user/lib/face
> -and /lib/face. Entries in /usr/$user/lib/face take priority over
> -those in /lib/face. See
> +display is determined by the `sender' and `facedir' attributes
> +in the plumb message, with facedir defaulting to /lib/face. Entries in
> +/usr/$user/lib/face take priority over those in facedir. See
>  .IR face (6),
>  for how these directories are organised.
> -.PP
> -If the user is running
> -.IR plumber (4),
> -.I faces
> -reacts to plumb messages to the
> -.B seemail
> -port,
> -typically from
> -.BR upas/fs ,
> -and is thus notified of message additions and deletions.
> +Additionally, the `sender' attribute can optionally be formatted as follows:
> +.EX
> +       sender@site
> +.EE
> +This allows further control over which face is shown.
>  .PP
>  Right-clicking on a message icon causes that message to be `plumbed' to
> -.BR showmail .
> -A typical plumb action will be to display the message, such as by
> -the rule
> +the destination port specified in the original plumbing message, in the
> +`dst' attribute.
> +Usually, the original generating application is listening on this port,
> +but if it is not, a plumbing rule can be specified like
>  .EX
>      plumb start window mail -s $0
>  .EE
> -The
> -.IR acme (1)
> -mail reader listens to the
> -.B showmail
> -port automatically.
> +If not specified, the message is plumbed back to the `none' port.
> +All of the attributes specified in the original message are preserved; faces
> +simply ignores extraneous ones. The `wdir' field in the original message is
> +preserved similarly.
> +Programs can also sent a `winid' attribute.  Faces will make the
> +window with that id current.
>  .PP
> -If the user is not running
> -.IR plumber ,
> -.I faces
> -reads the log file
> -.F /sys/log/mail
> -and right-clicking has no effect.
> +An optional attribute is a `date' \- this is used to provide a more
> +accurate timestamp. If unset, faces will use the date it received the
> +notification, potentially differing from the date of the event that
> +generated the notification.
> +.PP
> +The `data' field of the plumbing message should be something unique that
> +allows the originating application to distinguish between notifications.
> +It is sent back to the application unaltered when the face is clicked
> +as the resulting plumbing message's `data' field.
> +The `digest' attribute should be a hash of the `data' field concatenated
> +with the application's name, to prevent hash collisions between
> +applications that might be using the same hash algorithm and similar
> +contents of `data' .
>  .PP
>  If arrows are visible, clicking on them will scroll the display.
>  Middle-clicking on the arrows scrolls to the end.
>  .PP
> -Starting
> -.B faces
> -with the
> -.B -i
> -flag causes
> -.B faces
> -to read the messages in
> -.BR /mail/fs/mbox
> -— or the mailboxes specified with the
> -.B -m
> -flag —
> -upon startup.
> -.PP
> -The
> -.B -m
> -option directs
> -.I faces
> -to watch for messages arriving in
> -.I maildir
> -instead of
> -.BR /mail/fs/mbox .
> -Multiple
> -.B -m
> -flags may be used to watch multiple mailboxes.
> -.PP
> -The
> -.B -h
> -flag causes a different, venerable behavior in which
> -the window displays the history of messages received
> -rather than the current state of the mail box.
> -In particular, faces are not removed from the screen when messages are deleted.
> -Also, in this mode clicking button 1 in the display will clear the window.
> -.PP
> -.I Seemail
> -is an
> -.IR rc (1)
> -script that invokes
> -.B faces
> -.BR -h .
> -.PP
>  .I Vwhois
>  tells
>  .I faces
>  to display the icons of the named
> -.IR persons ,
> -without sending a message.
> +.IR persons .
>  .SH FILES
> -.BR /mail/fs/mbox   "   mail directory.
> +.BR /mnt/plumb/notify   "   the destination port for notifications.
>  .SH SOURCE
>  .B /sys/src/cmd/faces
>  .br
> -.B /rc/bin/seemail
> -.br
>  .B /rc/bin/vwhois
>  .SH "SEE ALSO"
> -.IR mail (1),
> -.IR marshal (1),
> -.IR nedmail (1),
>  .IR plumber (4),
>  .IR face (6),
>  .IR plumb (6)
> +.SH BUGS
> +There is no -i option anymore; instead, programs that wish to re-send old
> +notifications should provide their own options to do so.
>
>
>
> ---------- Forwarded message ----------
> From: Alex Musolino <alex@musolino.id.au>
> To: 9front@9front.org
> Cc:
> Bcc:
> Date: Sat, 17 Oct 2020 10:56:40 +1030
> Subject: Re: [9front] make faces generic
> I like my faces(1) with -i.  Maybe it would be better just write
> a new program?


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9front] make faces generic
  2020-10-15  3:24 ` covertusername967
@ 2020-10-17  2:04   ` ori
  2020-10-18  3:26     ` covertusername967
  0 siblings, 1 reply; 7+ messages in thread
From: ori @ 2020-10-17  2:04 UTC (permalink / raw)
  To: covertusername967, 9front

I like the idea of a generic faces. I'm going
to look pretty closely at this.

Breaking compatibility is a pain, so if this
goes in, we'll probably want to make sure its
something that gets used.

> Hello,
> 
> When sending the previous email I found a bug in acme mail related to this patch (I only use acme mail to send mail.) The below patch is the same as the previous one and also fixes acme mail.
> 
> diff -r e05e4b6c6546 rc/bin/ircrc
> --- a/rc/bin/ircrc	Mon Oct 12 02:03:52 2020 +0200
> +++ b/rc/bin/ircrc	Wed Oct 14 19:02:10 2020 -0500
> @@ -169,6 +169,14 @@
>  		switch ($line) {
>  		case *PRIVMSG*
>  			line = `{echo -n $line | privmsg}
> +			switch($line) {
> +			case *^$nick^*
> +				digest = ircrc.$pid.`{date -n}
> +				sender = `{echo -n $line | sed 'y/«»/  /' | awk '{print $2}'}
> +				data = `{echo -n $line | sed 'y/()/  /' | awk '{print $1}'}
> +				winid = `{cat /dev/winid}
> +				plumb -dnotify -a 'digest='^$digest^' dst=irc sender='^$sender^'@'^$server^' winid='^$winid^' date='''^`"{date}^'''' -s ircrc $data
> +			}
>  		case *JOIN* *QUIT* *PART* *NICK*
>  			line = `{echo -n $line | misc}
>  		case *NOTICE*
> diff -r e05e4b6c6546 rc/bin/vwhois
> --- a/rc/bin/vwhois	Mon Oct 12 02:03:52 2020 +0200
> +++ b/rc/bin/vwhois	Wed Oct 14 19:02:10 2020 -0500
> @@ -2,16 +2,5 @@
>  
>  rfork e
>  
> -box=mbox
> -if(! test -d /mail/fs/$box)
> -	box=`{ls -p /mail/fs | grep -v ctl | sed 1q}
> -if(~ $#box 0)
> -	box=mbox	# we tried
> -
> -if(~ $#box 1 && test -f /mnt/plumb/seemail || test -f /mnt/term/mnt/plumb/seemail){
> -	for(i)
> -		plumb -dseemail -a 'filetype=vwhois digest='$i.$pid' mailtype=new sender='$i /mail/fs/$box/XXXvwhois
> -}
> -if not for (i){
> -	echo vwhois: vwhois: vwhois: delivered `{cat /dev/user} From $i '(vwho)' >> /sys/log/mail
> -}
> +for(i)
> +	plumb -dnotify -a 'digest='$i.$pid' sender='$i /XXXvwhois
> diff -r e05e4b6c6546 sys/lib/plumb/basic
> --- a/sys/lib/plumb/basic	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/lib/plumb/basic	Wed Oct 14 19:02:10 2020 -0500
> @@ -4,8 +4,8 @@
>  include fileaddr
>  
>  # declarations of ports without rules
> -plumb to seemail
>  plumb to showmail
> +plumb to notify
>  
>  # open urls with web browser
>  type is text
> diff -r e05e4b6c6546 sys/src/cmd/faces/facedb.c
> --- a/sys/src/cmd/faces/facedb.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/faces/facedb.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -315,14 +315,14 @@
>  }
>  
>  static char*
> -tryfindfile(char *dom, char *user)
> +tryfindfile(char *dom, char *user, char *facedir)
>  {
>  	char *p;
>  
>  	while(dom && *dom){
>  		if(homeface && (p = tryfindfiledir(dom, user, homeface)) != nil)
>  			return p;
> -		if((p = tryfindfiledir(dom, user, "/lib/face")) != nil)
> +		if((p = tryfindfiledir(dom, user, facedir)) != nil)
>  			return p;
>  		if((dom = strchr(dom, '.')) == nil)
>  			break;
> @@ -351,13 +351,13 @@
>  	}
>  
>  	f->unknown = 0;
> -	if((p = tryfindfile(dom, user)) != nil)
> +	if((p = tryfindfile(dom, user, f->str[Sfacedir])) != nil)
>  		return p;
>  	f->unknown = 1;
> -	p = tryfindfile(dom, "unknown");
> +	p = tryfindfile(dom, "unknown", f->str[Sfacedir]);
>  	if(p != nil || strcmp(dom, facedom) == 0)
>  		return p;
> -	return tryfindfile("unknown", "unknown");
> +	return tryfindfile("unknown", "unknown", f->str[Sfacedir]);
>  }
>  
>  static
> diff -r e05e4b6c6546 sys/src/cmd/faces/faces.h
> --- a/sys/src/cmd/faces/faces.h	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/faces/faces.h	Wed Oct 14 19:02:10 2020 -0500
> @@ -4,6 +4,11 @@
>  	Sdomain,
>  	Sshow,
>  	Sdigest,
> +	Sdst,
> +	Sfacedir,
> +	Sattrs,
> +	Swdir,
> +	Swinid,
>  	Nstring
>  };
>  
> @@ -42,9 +47,6 @@
>  };
>  
>  extern char	date[];
> -extern char	*maildir;
> -extern char	**maildirs;
> -extern int	nmaildirs;
>  
>  Face*	nextface(void);
>  void	findbit(Face*);
> @@ -54,7 +56,6 @@
>  void	showmail(Face*);
>  void	delete(char*, char*);
>  void	freefacefile(Facefile*);
> -Face*	dirface(char*, char*);
>  void	resized(void);
>  int	alreadyseen(char*);
>  ulong	dirlen(char*);
> @@ -63,4 +64,3 @@
>  void	*erealloc(void*, ulong);
>  char	*estrdup(char*);
>  char	*findfile(Face*, char*, char*);
> -void	addmaildir(char*);
> diff -r e05e4b6c6546 sys/src/cmd/faces/main.c
> --- a/sys/src/cmd/faces/main.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/faces/main.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -7,9 +7,6 @@
>  #include <bio.h>
>  #include "faces.h"
>  
> -int	history = 0;	/* use old interface, showing history of mailbox rather than current state */
> -int	initload = 0;	/* initialize program with contents of mail box */
> -
>  enum
>  {
>  	Facesep = 6,	/* must be even to avoid damaging background stipple */
> @@ -68,7 +65,6 @@
>  
>  char	date[64];
>  Face	**faces;
> -char	*maildir = "/mail/fs/mbox";
>  ulong	now;
>  
>  Point	datep = { 8, 6 };
> @@ -163,7 +159,7 @@
>  	Face *f;
>  
>  	if(!digest)
> -		return 0;
> +		return 1;
>  
>  	/* can do accurate check */
>  	for(i=0; i<nfaces; i++){
> @@ -358,25 +354,6 @@
>  }
>  
>  void
> -loadmboxfaces(char *maildir)
> -{
> -	int dirfd;
> -	Dir *d;
> -	int i, n;
> -
> -	dirfd = open(maildir, OREAD);
> -	if(dirfd >= 0){
> -		chdir(maildir);
> -		while((n = dirread(dirfd, &d)) > 0){
> -			for(i=0; i<n; i++)
> -				addface(dirface(maildir, d[i].name));
> -			free(d);
> -		}
> -		close(dirfd);
> -	}
> -}
> -
> -void
>  freeface(Face *f)
>  {
>  	int i;
> @@ -435,16 +412,8 @@
>  void
>  dodelete(int i)
>  {
> -	Face *f;
> -
> -	f = faces[i];
> -	if(history){
> -		free(f->str[Sshow]);
> -		f->str[Sshow] = estrdup("");
> -	}else{
> -		delface(i);
> -		flushimage(display, 1);
> -	}
> +	delface(i);
> +	flushimage(display, 1);
>  }
>  
>  void
> @@ -586,25 +555,12 @@
>  	case 1:
>  		if(scroll(1, p))
>  			break;
> -		if(history){
> -			/* click clears display */
> -			lockdisplay(display);
> -			for(i=0; i<nfaces; i++)
> -				freeface(faces[i]);
> -			free(faces);
> -			faces=nil;
> -			nfaces = 0;
> -			unlockdisplay(display);
> -			eresized(0);
> -			return;
> -		}else{
> -			for(i=first; i<last; i++)	/* clear vwhois faces */
> -				if(ptinrect(p, facerect(i-first)) 
> -				&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
> -					delface(i);
> -					flushimage(display, 1);
> -				}
> -		}
> +		for(i=first; i<last; i++)	/* clear vwhois faces */
> +			if(ptinrect(p, facerect(i-first)) 
> +			&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
> +				delface(i);
> +				flushimage(display, 1);
> +			}
>  		break;
>  	case 2:
>  		scroll(2, p);
> @@ -675,26 +631,14 @@
>  void
>  usage(void)
>  {
> -	fprint(2, "usage: faces [-hi] [-m maildir]\n");
> +	fprint(2, "usage: faces\n");
>  	exits("usage");
>  }
>  
>  void
>  main(int argc, char *argv[])
>  {
> -	int i;
> -
>  	ARGBEGIN{
> -	case 'h':
> -		history++;
> -		break;
> -	case 'i':
> -		initload++;
> -		break;
> -	case 'm':
> -		addmaildir(EARGF(usage()));
> -		maildir = nil;
> -		break;
>  	default:
>  		usage();
>  	}ARGEND
> @@ -703,8 +647,6 @@
>  		fprint(2, "faces: initdraw failed: %r\n");
>  		exits("initdraw");
>  	}
> -	if(maildir)
> -		addmaildir(maildir);
>  	init();
>  	unlockdisplay(display);	/* initdraw leaves it locked */
>  	display->locking = 1;	/* tell library we're using the display lock */
> @@ -714,9 +656,6 @@
>  	pids[Mainp] = getpid();
>  	startproc(timeproc, Timep);
>  	startproc(mouseproc, Mousep);
> -	if(initload)
> -		for(i = 0; i < nmaildirs; i++)
> -		 loadmboxfaces(maildirs[i]);
>  	faceproc();
>  	fprint(2, "faces: %s process exits\n", procnames[Mainp]);
>  	killall(nil);
> diff -r e05e4b6c6546 sys/src/cmd/faces/plumb.c
> --- a/sys/src/cmd/faces/plumb.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/faces/plumb.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -6,53 +6,56 @@
>  #include <bio.h>
>  #include "faces.h"
>  
> -static int	showfd = -1;
> -static int	seefd = -1;
> +static int		notefd = -1;
> +static int		showfd = -1;
>  static char	*user;
> -
> -char		**maildirs;
> -int		nmaildirs;
> +static char	*logtag;
>  
>  void
>  initplumb(void)
>  {
>  	if((showfd = plumbopen("send", OWRITE)) == -1)
>  		sysfatal("plumbopen send: %r");
> -	if((seefd = plumbopen("seemail", OREAD)) == -1)
> -		sysfatal("plumbopen seemail: %r");
> -}
> -
> -void
> -addmaildir(char *dir)
> -{
> -	maildirs = erealloc(maildirs, (nmaildirs+1)*sizeof(char*));
> -	maildirs[nmaildirs++] = dir;
> -}
> -
> -char*
> -attr(Face *f)
> -{
> -	static char buf[128];
> -
> -	if(f->str[Sdigest]){
> -		snprint(buf, sizeof buf, "digest=%s", f->str[Sdigest]);
> -		return buf;
> +	if((notefd = plumbopen("notify", OREAD)) == -1){
> +		sysfatal("plumbopen notify: %r);
>  	}
> -	return nil;
>  }
>  
>  void
>  showmail(Face *f)
>  {
> -	char *s;
> -	int n;
> +	char *s, buf[73], *fields[6];
> +	int n, len, wctl;
>  
> -	if(showfd<0 || f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
> +	if(f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
>  		return;
> -	s = emalloc(128+strlen(f->str[Sshow])+1);
> -	n = sprint(s, "faces\nshowmail\n/mail/fs/\ntext\n%s\n%ld\n%s", attr(f), strlen(f->str[Sshow]), f->str[Sshow]);
> -	write(showfd, s, n);
> -	free(s);
> +	if(f->str[Swinid][0] != '0'){
> +		snprint(buf, 73, "/dev/wsys/%s/wctl", f->str[Swinid]);
> +		wctl = open(buf, ORDWR);
> +		if(wctl < 0)
> +			return;
> +		if(read(wctl, buf, 72) != 72){
> +			close(wctl);
> +			return;
> +		}
> +		buf[72] = '\0';
> +		if(tokenize(buf, fields, 6) != 6){
> +			close(wctl);
> +			return;
> +		}
> +		if(strcmp(fields[5], "hidden") == 0)
> +			write(wctl, "unhide", 6);
> +		else
> +			write(wctl, "current", 7);
> +		close(wctl);
> +	}
> +	else {
> +		len = 128+strlen(f->str[Sdst])+strlen(f->str[Swdir])+strlen(f->str[Sattrs])+strlen(f->str[Sshow])+1;
> +		s = emalloc(len);
> +		n = snprint(s, len, "faces\n%s\n%s\ntext\n%s\n%ld\n%s", f->str[Sdst], f->str[Swdir], f->str[Sattrs], strlen(f->str[Sshow]), f->str[Sshow]);
> +		write(showfd, s, n);
> +		free(s);
> +	}
>  }
>  
>  char*
> @@ -69,7 +72,7 @@
>  void
>  setname(Face *f, char *sender)
>  {
> -	char *at, *bang;
> +	char *at;
>  	char *p;
>  
>  	/* works with UTF-8, although it's written as ASCII */
> @@ -82,13 +85,6 @@
>  		f->str[Sdomain] = estrdup(at);
>  		return;
>  	}
> -	bang = strchr(sender, '!');
> -	if(bang){
> -		*bang++ = '\0';
> -		f->str[Suser] = estrdup(bang);
> -		f->str[Sdomain] = sender;
> -		return;
> -	}
>  }
>  
>  ulong
> @@ -123,117 +119,57 @@
>  Face*
>  nextface(void)
>  {
> -	int i;
>  	Face *f;
>  	Plumbmsg *m;
> -	char *t, *senderp, *showmailp, *digestp;
> +	char *senderp, *showmailp, *digestp, *dstp, *facep, *winid;
>  	ulong xtime;
> +	Dir *facedir;
>  
>  	f = emalloc(sizeof(Face));
>  	for(;;){
> -		m = plumbrecv(seefd);
> +		m = plumbrecv(notefd);
>  		if(m == nil)
> -			killall("error on seemail plumb port");
> -		t = value(m->attr, "mailtype", "");
> -		if(strcmp(t, "modify") == 0)
> -			goto Ignore;
> -		else if(strcmp(t, "delete") == 0)
> -			delete(m->data, value(m->attr, "digest", nil));
> -		else if(strcmp(t, "new") == 0)
> -			for(i=0; i<nmaildirs; i++){
> -				if(strncmp(m->data, maildirs[i], strlen(maildirs[i])) == 0)
> -					goto Found;
> -			}
> -		else
> -			fprint(2, "faces: unknown plumb message type %s\n", t);
> -	Ignore:
> -		plumbfree(m);
> -		continue;
> -
> -	Found:
> -		xtime = parsedate(value(m->attr, "date", date));
> -		digestp = value(m->attr, "digest", nil);
> +			killall("error on notify plumb port");
> +		digestp = estrdup(value(m->attr, "digest", "inedible"));
>  		if(alreadyseen(digestp)){
> -			/* duplicate upas/fs can send duplicate messages */
> +			/* duplicate programs can send duplicate messages */
>  			plumbfree(m);
>  			continue;
>  		}
> -		senderp = estrdup(value(m->attr, "sender", "???"));
> +		facep = estrdup(value(m->attr, "facedir", "/lib/face"));
> +		if(access(facep, AEXIST) == 0){
> +			facedir = dirstat(facep);
> +			if(facedir == nil){
> +				plumbfree(m);
> +				continue;
> +			}
> +			if(facedir->qid.type != QTDIR){
> +				free(facedir);
> +				plumbfree(m);
> +				continue;
> +			}
> +			free(facedir);
> +		}
> +		else {
> +			plumbfree(m);
> +			continue;
> +		}
> +		dstp = estrdup(value(m->attr, "dst", "none"));
> +		senderp = estrdup(value(m->attr, "sender", "unknown"));
> +		winid = estrdup(value(m->attr, "winid", "0"));
> +		xtime = parsedate(value(m->attr, "date", date));
>  		showmailp = estrdup(m->data);
> -		if(digestp)
> -			digestp = estrdup(digestp);
> +		f->str[Sattrs] = plumbpackattr(m->attr);
> +		f->str[Swdir] = estrdup(m->wdir);
>  		plumbfree(m);
>  		setname(f, senderp);
>  		f->time = xtime;
>  		f->tm = *localtime(xtime);
>  		f->str[Sshow] = showmailp;
>  		f->str[Sdigest] = digestp;
> +		f->str[Sdst] = dstp;
> +		f->str[Sfacedir] = facep;
> +		f->str[Swinid] = winid;
>  		return f;
>  	}
>  }
> -
> -char*
> -iline(char *data, char **pp)
> -{
> -	char *p;
> -
> -	for(p=data; *p!='\0' && *p!='\n'; p++)
> -		;
> -	if(*p == '\n')
> -		*p++ = '\0';
> -	*pp = p;
> -	return data;
> -}
> -
> -Face*
> -dirface(char *dir, char *num)
> -{
> -	Face *f;
> -	char *from, *date;
> -	char buf[1024], pwd[1024], *info, *p, *digest;
> -	int n, fd;
> -	ulong len;
> -
> -	/*
> -	 * loadmbox leaves us in maildir, so we needn't
> -	 * walk /mail/fs/mbox for each face; this makes startup
> -	 * a fair bit quicker.
> -	 */
> -	if(getwd(pwd, sizeof pwd) != nil && strcmp(pwd, dir) == 0)
> -		sprint(buf, "%s/info", num);
> -	else
> -		sprint(buf, "%s/%s/info", dir, num);
> -	len = dirlen(buf);
> -	if(len <= 0)
> -		return nil;
> -	fd = open(buf, OREAD);
> -	if(fd < 0)
> -		return nil;
> -	info = emalloc(len+1);
> -	n = readn(fd, info, len);
> -	close(fd);
> -	if(n < 0){
> -		free(info);
> -		return nil;
> -	}
> -	info[n] = '\0';
> -	f = emalloc(sizeof(Face));
> -	from = iline(info, &p);	/* from */
> -	iline(p, &p);	/* to */
> -	iline(p, &p);	/* cc */
> -	iline(p, &p);	/* replyto */
> -	date = iline(p, &p);	/* date */
> -	setname(f, estrdup(from));
> -	f->time = parsedate(date);
> -	f->tm = *localtime(f->time);
> -	sprint(buf, "%s/%s", dir, num);
> -	f->str[Sshow] = estrdup(buf);
> -	iline(p, &p);	/* subject */
> -	iline(p, &p);	/* mime content type */
> -	iline(p, &p);	/* mime disposition */
> -	iline(p, &p);	/* filename */
> -	digest = iline(p, &p);	/* digest */
> -	f->str[Sdigest] = estrdup(digest);
> -	free(info);
> -	return f;
> -}
> diff -r e05e4b6c6546 sys/src/cmd/upas/Mail/mail.c
> --- a/sys/src/cmd/upas/Mail/mail.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/upas/Mail/mail.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -86,7 +86,7 @@
>  
>  	/* open these early so we won't miss notification of new mail messages while we read mbox */
>  	plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
> -	plumbseemailfd = plumbopen("seemail", OREAD|OCEXEC);
> +	plumbseemailfd = plumbopen("notify", OREAD|OCEXEC);
>  	plumbshowmailfd = plumbopen("showmail", OREAD|OCEXEC);
>  
>  	shortmenu = 0;
> diff -r e05e4b6c6546 sys/src/cmd/upas/fs/mbox.c
> --- a/sys/src/cmd/upas/fs/mbox.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/upas/fs/mbox.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -1547,11 +1547,12 @@
>  static void
>  mailplumb(Mailbox *mb, Message *m)
>  {
> -	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], *from, *subject;
> +	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], addr[320], *from, *subject, *bang, *unixfrom;
>  	int ai;
>  	Plumbmsg p;
>  	Plumbattr a[7];
>  	static int fd = -1;
> +	int didflip;
>  
>  	subject = m->subject;
>  	if(subject == nil)
> @@ -1572,8 +1573,27 @@
>  	if(fd < 0)
>  		return;
>  
> +	/* convert uucp address for faces */
> +	didflip = 0;
> +	if(from == m->unixfrom){
> +		unixfrom = strdup(m->unixfrom);
> +		if(unixfrom == nil)
> +			return;
> +		bang = strchr(unixfrom, '!');
> +		*bang++ = '\0';
> +		strcpy(addr, bang);
> +		strcat(addr, "@");
> +		strcat(addr, unixfrom);
> +		from = strdup(addr);
> +		if(from == nil){
> +			free(unixfrom);
> +			return;
> +		}
> +		didflip++;
> +	}
> +
>  	p.src = "mailfs";
> -	p.dst = "seemail";
> +	p.dst = "notify";
>  	p.wdir = "/mail/fs";
>  	p.type = "text";
>  
> @@ -1603,12 +1623,18 @@
>  	a[ai].value = date;
>  	a[ai-1].next = &a[ai];
>  
> -	if(m->digest){
> -		snprint(dbuf, sizeof dbuf, "%A", m->digest);
> -		a[++ai].name = "digest";
> -		a[ai].value = dbuf;
> -		a[ai-1].next = &a[ai];
> -	}
> +	if(m->digest == nil)
> +		digestmessage(mb, m);
> +	snprint(dbuf, sizeof dbuf, "%A", m->digest);
> +	
> +	a[++ai].name = "digest";
> +	a[ai].value = dbuf;
> +	a[ai-1].next = &a[ai];
> +
> +	a[++ai].name = "dst";
> +	a[ai].value = "showmail";
> +	a[ai-1].next = &a[ai];
> +	
>  	a[ai].next = nil;
>  	p.attr = a;
>  	snprint(buf, sizeof buf, "%s/%s/%s",
> @@ -1617,6 +1643,11 @@
>  	p.data = buf;
>  
>  	myplumbsend(fd, &p);
> +
> +	if(didflip != 0){
> +		free(unixfrom);
> +		free(from);
> +	}
>  }
>  
>  /*



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [9front] make faces generic
  2020-10-17  2:04   ` ori
@ 2020-10-18  3:26     ` covertusername967
  0 siblings, 0 replies; 7+ messages in thread
From: covertusername967 @ 2020-10-18  3:26 UTC (permalink / raw)
  To: ori, covertusername967, 9front

[-- Attachment #1: Type: text/plain, Size: 4006 bytes --]

Hello,

Here is an adjusted patch for upas/fs (and its manpage) that adds an
'finit' control mesage to the mailbox ctl file.  When 'finit' is
written to said file, upas/fs will plumb all the messages back to
faces, resulting in identical behavior to the old faces -i.

diff -r e05e4b6c6546 sys/man/4/upasfs
--- a/sys/man/4/upasfs	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/man/4/upasfs	Sat Oct 17 22:21:13 2020 -0500
@@ -194,6 +194,12 @@
 Deleting message directories causes the message to be removed from
 the mailbox.
 .PP
+Each mailbox, if the underlying protocol supports it, has a `ctl' file
+under the mailbox directory as well.  For now, the only documented
+message is `finit', which will plumb all existing messages in the
+mailbox to
+.IR faces(1).
+.PP
 The mailbox is scanned and the structure updated
 whenever the mailbox changes.  Message directories are
 not renumbered. The results of the scan are
diff -r e05e4b6c6546 sys/src/cmd/upas/fs/dat.h
--- a/sys/src/cmd/upas/fs/dat.h	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/upas/fs/dat.h	Sat Oct 17 22:21:13 2020 -0500
@@ -241,6 +241,8 @@
 void		parsebody(Message*, Mailbox*);
 int		strtotm(char*, Tm*);
 char*		lowercase(char*);
+void 		mailplumb(Mailbox*, Message*);
+
 
 char*		sputc(char*, char*, int);
 char*		seappend(char*, char*, char*, int);
diff -r e05e4b6c6546 sys/src/cmd/upas/fs/fs.c
--- a/sys/src/cmd/upas/fs/fs.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/upas/fs/fs.c	Sat Oct 17 22:21:13 2020 -0500
@@ -1194,6 +1194,7 @@
 {
 	char *argvbuf[1024], **argv, file[Pathlen], *err, *v0;
 	int i, t, argc, flags;
+	Message *m;
 
 	t = FILE(f->qid.path);
 	rhdr.count = thdr.count;
@@ -1288,6 +1289,11 @@
 		argc = tokenize(thdr.data, argv, nelem(argvbuf));
 		if(argc == 0)
 			return Ebadctl;
+		if(strcmp(argv[0], "finit") == 0){
+			for(m = f->mb->root->part; m != nil; m = m->next)
+				mailplumb(f->mb, m);
+			return nil;
+		}
 		return f->mb->ctl(f->mb, argc, argv);
 	case Qflags:
 		/*
diff -r e05e4b6c6546 sys/src/cmd/upas/fs/mbox.c
--- a/sys/src/cmd/upas/fs/mbox.c	Mon Oct 12 02:03:52 2020 +0200
+++ b/sys/src/cmd/upas/fs/mbox.c	Sat Oct 17 22:21:13 2020 -0500
@@ -56,7 +56,6 @@
 };
 
 static void delmessage(Mailbox*, Message*);
-static void mailplumb(Mailbox*, Message*);
 
 char*
 syncmbox(Mailbox *mb, int doplumb)
@@ -1544,14 +1543,20 @@
 	return n;
 }
 
-static void
+void
 mailplumb(Mailbox *mb, Message *m)
 {
-	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], *from, *subject;
+	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], addr[320], *from, *subject, *bang, *unixfrom;
 	int ai;
 	Plumbmsg p;
 	Plumbattr a[7];
 	static int fd = -1;
+	int didflip;
+
+	if(m == nil){
+		fprint(2, "upasfs mailplumb: nil message\n");
+		return;
+	}
 
 	subject = m->subject;
 	if(subject == nil)
@@ -1572,8 +1577,27 @@
 	if(fd < 0)
 		return;
 
+	/* convert uucp address for faces */
+	didflip = 0;
+	if(from == m->unixfrom){
+		unixfrom = strdup(m->unixfrom);
+		if(unixfrom == nil)
+			return;
+		bang = strchr(unixfrom, '!');
+		*bang++ = '\0';
+		strcpy(addr, bang);
+		strcat(addr, "@");
+		strcat(addr, unixfrom);
+		from = strdup(addr);
+		if(from == nil){
+			free(unixfrom);
+			return;
+		}
+		didflip++;
+	}
+
 	p.src = "mailfs";
-	p.dst = "seemail";
+	p.dst = "notify";
 	p.wdir = "/mail/fs";
 	p.type = "text";
 
@@ -1603,12 +1627,18 @@
 	a[ai].value = date;
 	a[ai-1].next = &a[ai];
 
-	if(m->digest){
-		snprint(dbuf, sizeof dbuf, "%A", m->digest);
-		a[++ai].name = "digest";
-		a[ai].value = dbuf;
-		a[ai-1].next = &a[ai];
-	}
+	if(m->digest == nil)
+		digestmessage(mb, m);
+	snprint(dbuf, sizeof dbuf, "%A", m->digest);
+	
+	a[++ai].name = "digest";
+	a[ai].value = dbuf;
+	a[ai-1].next = &a[ai];
+
+	a[++ai].name = "dst";
+	a[ai].value = "showmail";
+	a[ai-1].next = &a[ai];
+	
 	a[ai].next = nil;
 	p.attr = a;
 	snprint(buf, sizeof buf, "%s/%s/%s",
@@ -1617,6 +1647,11 @@
 	p.data = buf;
 
 	myplumbsend(fd, &p);
+
+	if(didflip != 0){
+		free(unixfrom);
+		free(from);
+	}
 }
 
 /*

[-- Attachment #2: Type: message/rfc822, Size: 19898 bytes --]

From: ori@eigenstate.org
To: covertusername967@gmail.com, 9front@9front.org
Subject: Re: [9front] make faces generic
Date: Fri, 16 Oct 2020 19:04:21 -0700
Message-ID: <21FA850C486AC2F4103171E32619B5BE@eigenstate.org>

I like the idea of a generic faces. I'm going
to look pretty closely at this.

Breaking compatibility is a pain, so if this
goes in, we'll probably want to make sure its
something that gets used.

> Hello,
> 
> When sending the previous email I found a bug in acme mail related to this patch (I only use acme mail to send mail.) The below patch is the same as the previous one and also fixes acme mail.
> 
> diff -r e05e4b6c6546 rc/bin/ircrc
> --- a/rc/bin/ircrc	Mon Oct 12 02:03:52 2020 +0200
> +++ b/rc/bin/ircrc	Wed Oct 14 19:02:10 2020 -0500
> @@ -169,6 +169,14 @@
>  		switch ($line) {
>  		case *PRIVMSG*
>  			line = `{echo -n $line | privmsg}
> +			switch($line) {
> +			case *^$nick^*
> +				digest = ircrc.$pid.`{date -n}
> +				sender = `{echo -n $line | sed 'y/«»/  /' | awk '{print $2}'}
> +				data = `{echo -n $line | sed 'y/()/  /' | awk '{print $1}'}
> +				winid = `{cat /dev/winid}
> +				plumb -dnotify -a 'digest='^$digest^' dst=irc sender='^$sender^'@'^$server^' winid='^$winid^' date='''^`"{date}^'''' -s ircrc $data
> +			}
>  		case *JOIN* *QUIT* *PART* *NICK*
>  			line = `{echo -n $line | misc}
>  		case *NOTICE*
> diff -r e05e4b6c6546 rc/bin/vwhois
> --- a/rc/bin/vwhois	Mon Oct 12 02:03:52 2020 +0200
> +++ b/rc/bin/vwhois	Wed Oct 14 19:02:10 2020 -0500
> @@ -2,16 +2,5 @@
>  
>  rfork e
>  
> -box=mbox
> -if(! test -d /mail/fs/$box)
> -	box=`{ls -p /mail/fs | grep -v ctl | sed 1q}
> -if(~ $#box 0)
> -	box=mbox	# we tried
> -
> -if(~ $#box 1 && test -f /mnt/plumb/seemail || test -f /mnt/term/mnt/plumb/seemail){
> -	for(i)
> -		plumb -dseemail -a 'filetype=vwhois digest='$i.$pid' mailtype=new sender='$i /mail/fs/$box/XXXvwhois
> -}
> -if not for (i){
> -	echo vwhois: vwhois: vwhois: delivered `{cat /dev/user} From $i '(vwho)' >> /sys/log/mail
> -}
> +for(i)
> +	plumb -dnotify -a 'digest='$i.$pid' sender='$i /XXXvwhois
> diff -r e05e4b6c6546 sys/lib/plumb/basic
> --- a/sys/lib/plumb/basic	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/lib/plumb/basic	Wed Oct 14 19:02:10 2020 -0500
> @@ -4,8 +4,8 @@
>  include fileaddr
>  
>  # declarations of ports without rules
> -plumb to seemail
>  plumb to showmail
> +plumb to notify
>  
>  # open urls with web browser
>  type is text
> diff -r e05e4b6c6546 sys/src/cmd/faces/facedb.c
> --- a/sys/src/cmd/faces/facedb.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/faces/facedb.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -315,14 +315,14 @@
>  }
>  
>  static char*
> -tryfindfile(char *dom, char *user)
> +tryfindfile(char *dom, char *user, char *facedir)
>  {
>  	char *p;
>  
>  	while(dom && *dom){
>  		if(homeface && (p = tryfindfiledir(dom, user, homeface)) != nil)
>  			return p;
> -		if((p = tryfindfiledir(dom, user, "/lib/face")) != nil)
> +		if((p = tryfindfiledir(dom, user, facedir)) != nil)
>  			return p;
>  		if((dom = strchr(dom, '.')) == nil)
>  			break;
> @@ -351,13 +351,13 @@
>  	}
>  
>  	f->unknown = 0;
> -	if((p = tryfindfile(dom, user)) != nil)
> +	if((p = tryfindfile(dom, user, f->str[Sfacedir])) != nil)
>  		return p;
>  	f->unknown = 1;
> -	p = tryfindfile(dom, "unknown");
> +	p = tryfindfile(dom, "unknown", f->str[Sfacedir]);
>  	if(p != nil || strcmp(dom, facedom) == 0)
>  		return p;
> -	return tryfindfile("unknown", "unknown");
> +	return tryfindfile("unknown", "unknown", f->str[Sfacedir]);
>  }
>  
>  static
> diff -r e05e4b6c6546 sys/src/cmd/faces/faces.h
> --- a/sys/src/cmd/faces/faces.h	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/faces/faces.h	Wed Oct 14 19:02:10 2020 -0500
> @@ -4,6 +4,11 @@
>  	Sdomain,
>  	Sshow,
>  	Sdigest,
> +	Sdst,
> +	Sfacedir,
> +	Sattrs,
> +	Swdir,
> +	Swinid,
>  	Nstring
>  };
>  
> @@ -42,9 +47,6 @@
>  };
>  
>  extern char	date[];
> -extern char	*maildir;
> -extern char	**maildirs;
> -extern int	nmaildirs;
>  
>  Face*	nextface(void);
>  void	findbit(Face*);
> @@ -54,7 +56,6 @@
>  void	showmail(Face*);
>  void	delete(char*, char*);
>  void	freefacefile(Facefile*);
> -Face*	dirface(char*, char*);
>  void	resized(void);
>  int	alreadyseen(char*);
>  ulong	dirlen(char*);
> @@ -63,4 +64,3 @@
>  void	*erealloc(void*, ulong);
>  char	*estrdup(char*);
>  char	*findfile(Face*, char*, char*);
> -void	addmaildir(char*);
> diff -r e05e4b6c6546 sys/src/cmd/faces/main.c
> --- a/sys/src/cmd/faces/main.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/faces/main.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -7,9 +7,6 @@
>  #include <bio.h>
>  #include "faces.h"
>  
> -int	history = 0;	/* use old interface, showing history of mailbox rather than current state */
> -int	initload = 0;	/* initialize program with contents of mail box */
> -
>  enum
>  {
>  	Facesep = 6,	/* must be even to avoid damaging background stipple */
> @@ -68,7 +65,6 @@
>  
>  char	date[64];
>  Face	**faces;
> -char	*maildir = "/mail/fs/mbox";
>  ulong	now;
>  
>  Point	datep = { 8, 6 };
> @@ -163,7 +159,7 @@
>  	Face *f;
>  
>  	if(!digest)
> -		return 0;
> +		return 1;
>  
>  	/* can do accurate check */
>  	for(i=0; i<nfaces; i++){
> @@ -358,25 +354,6 @@
>  }
>  
>  void
> -loadmboxfaces(char *maildir)
> -{
> -	int dirfd;
> -	Dir *d;
> -	int i, n;
> -
> -	dirfd = open(maildir, OREAD);
> -	if(dirfd >= 0){
> -		chdir(maildir);
> -		while((n = dirread(dirfd, &d)) > 0){
> -			for(i=0; i<n; i++)
> -				addface(dirface(maildir, d[i].name));
> -			free(d);
> -		}
> -		close(dirfd);
> -	}
> -}
> -
> -void
>  freeface(Face *f)
>  {
>  	int i;
> @@ -435,16 +412,8 @@
>  void
>  dodelete(int i)
>  {
> -	Face *f;
> -
> -	f = faces[i];
> -	if(history){
> -		free(f->str[Sshow]);
> -		f->str[Sshow] = estrdup("");
> -	}else{
> -		delface(i);
> -		flushimage(display, 1);
> -	}
> +	delface(i);
> +	flushimage(display, 1);
>  }
>  
>  void
> @@ -586,25 +555,12 @@
>  	case 1:
>  		if(scroll(1, p))
>  			break;
> -		if(history){
> -			/* click clears display */
> -			lockdisplay(display);
> -			for(i=0; i<nfaces; i++)
> -				freeface(faces[i]);
> -			free(faces);
> -			faces=nil;
> -			nfaces = 0;
> -			unlockdisplay(display);
> -			eresized(0);
> -			return;
> -		}else{
> -			for(i=first; i<last; i++)	/* clear vwhois faces */
> -				if(ptinrect(p, facerect(i-first)) 
> -				&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
> -					delface(i);
> -					flushimage(display, 1);
> -				}
> -		}
> +		for(i=first; i<last; i++)	/* clear vwhois faces */
> +			if(ptinrect(p, facerect(i-first)) 
> +			&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
> +				delface(i);
> +				flushimage(display, 1);
> +			}
>  		break;
>  	case 2:
>  		scroll(2, p);
> @@ -675,26 +631,14 @@
>  void
>  usage(void)
>  {
> -	fprint(2, "usage: faces [-hi] [-m maildir]\n");
> +	fprint(2, "usage: faces\n");
>  	exits("usage");
>  }
>  
>  void
>  main(int argc, char *argv[])
>  {
> -	int i;
> -
>  	ARGBEGIN{
> -	case 'h':
> -		history++;
> -		break;
> -	case 'i':
> -		initload++;
> -		break;
> -	case 'm':
> -		addmaildir(EARGF(usage()));
> -		maildir = nil;
> -		break;
>  	default:
>  		usage();
>  	}ARGEND
> @@ -703,8 +647,6 @@
>  		fprint(2, "faces: initdraw failed: %r\n");
>  		exits("initdraw");
>  	}
> -	if(maildir)
> -		addmaildir(maildir);
>  	init();
>  	unlockdisplay(display);	/* initdraw leaves it locked */
>  	display->locking = 1;	/* tell library we're using the display lock */
> @@ -714,9 +656,6 @@
>  	pids[Mainp] = getpid();
>  	startproc(timeproc, Timep);
>  	startproc(mouseproc, Mousep);
> -	if(initload)
> -		for(i = 0; i < nmaildirs; i++)
> -		 loadmboxfaces(maildirs[i]);
>  	faceproc();
>  	fprint(2, "faces: %s process exits\n", procnames[Mainp]);
>  	killall(nil);
> diff -r e05e4b6c6546 sys/src/cmd/faces/plumb.c
> --- a/sys/src/cmd/faces/plumb.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/faces/plumb.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -6,53 +6,56 @@
>  #include <bio.h>
>  #include "faces.h"
>  
> -static int	showfd = -1;
> -static int	seefd = -1;
> +static int		notefd = -1;
> +static int		showfd = -1;
>  static char	*user;
> -
> -char		**maildirs;
> -int		nmaildirs;
> +static char	*logtag;
>  
>  void
>  initplumb(void)
>  {
>  	if((showfd = plumbopen("send", OWRITE)) == -1)
>  		sysfatal("plumbopen send: %r");
> -	if((seefd = plumbopen("seemail", OREAD)) == -1)
> -		sysfatal("plumbopen seemail: %r");
> -}
> -
> -void
> -addmaildir(char *dir)
> -{
> -	maildirs = erealloc(maildirs, (nmaildirs+1)*sizeof(char*));
> -	maildirs[nmaildirs++] = dir;
> -}
> -
> -char*
> -attr(Face *f)
> -{
> -	static char buf[128];
> -
> -	if(f->str[Sdigest]){
> -		snprint(buf, sizeof buf, "digest=%s", f->str[Sdigest]);
> -		return buf;
> +	if((notefd = plumbopen("notify", OREAD)) == -1){
> +		sysfatal("plumbopen notify: %r);
>  	}
> -	return nil;
>  }
>  
>  void
>  showmail(Face *f)
>  {
> -	char *s;
> -	int n;
> +	char *s, buf[73], *fields[6];
> +	int n, len, wctl;
>  
> -	if(showfd<0 || f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
> +	if(f->str[Sshow]==nil || f->str[Sshow][0]=='\0')
>  		return;
> -	s = emalloc(128+strlen(f->str[Sshow])+1);
> -	n = sprint(s, "faces\nshowmail\n/mail/fs/\ntext\n%s\n%ld\n%s", attr(f), strlen(f->str[Sshow]), f->str[Sshow]);
> -	write(showfd, s, n);
> -	free(s);
> +	if(f->str[Swinid][0] != '0'){
> +		snprint(buf, 73, "/dev/wsys/%s/wctl", f->str[Swinid]);
> +		wctl = open(buf, ORDWR);
> +		if(wctl < 0)
> +			return;
> +		if(read(wctl, buf, 72) != 72){
> +			close(wctl);
> +			return;
> +		}
> +		buf[72] = '\0';
> +		if(tokenize(buf, fields, 6) != 6){
> +			close(wctl);
> +			return;
> +		}
> +		if(strcmp(fields[5], "hidden") == 0)
> +			write(wctl, "unhide", 6);
> +		else
> +			write(wctl, "current", 7);
> +		close(wctl);
> +	}
> +	else {
> +		len = 128+strlen(f->str[Sdst])+strlen(f->str[Swdir])+strlen(f->str[Sattrs])+strlen(f->str[Sshow])+1;
> +		s = emalloc(len);
> +		n = snprint(s, len, "faces\n%s\n%s\ntext\n%s\n%ld\n%s", f->str[Sdst], f->str[Swdir], f->str[Sattrs], strlen(f->str[Sshow]), f->str[Sshow]);
> +		write(showfd, s, n);
> +		free(s);
> +	}
>  }
>  
>  char*
> @@ -69,7 +72,7 @@
>  void
>  setname(Face *f, char *sender)
>  {
> -	char *at, *bang;
> +	char *at;
>  	char *p;
>  
>  	/* works with UTF-8, although it's written as ASCII */
> @@ -82,13 +85,6 @@
>  		f->str[Sdomain] = estrdup(at);
>  		return;
>  	}
> -	bang = strchr(sender, '!');
> -	if(bang){
> -		*bang++ = '\0';
> -		f->str[Suser] = estrdup(bang);
> -		f->str[Sdomain] = sender;
> -		return;
> -	}
>  }
>  
>  ulong
> @@ -123,117 +119,57 @@
>  Face*
>  nextface(void)
>  {
> -	int i;
>  	Face *f;
>  	Plumbmsg *m;
> -	char *t, *senderp, *showmailp, *digestp;
> +	char *senderp, *showmailp, *digestp, *dstp, *facep, *winid;
>  	ulong xtime;
> +	Dir *facedir;
>  
>  	f = emalloc(sizeof(Face));
>  	for(;;){
> -		m = plumbrecv(seefd);
> +		m = plumbrecv(notefd);
>  		if(m == nil)
> -			killall("error on seemail plumb port");
> -		t = value(m->attr, "mailtype", "");
> -		if(strcmp(t, "modify") == 0)
> -			goto Ignore;
> -		else if(strcmp(t, "delete") == 0)
> -			delete(m->data, value(m->attr, "digest", nil));
> -		else if(strcmp(t, "new") == 0)
> -			for(i=0; i<nmaildirs; i++){
> -				if(strncmp(m->data, maildirs[i], strlen(maildirs[i])) == 0)
> -					goto Found;
> -			}
> -		else
> -			fprint(2, "faces: unknown plumb message type %s\n", t);
> -	Ignore:
> -		plumbfree(m);
> -		continue;
> -
> -	Found:
> -		xtime = parsedate(value(m->attr, "date", date));
> -		digestp = value(m->attr, "digest", nil);
> +			killall("error on notify plumb port");
> +		digestp = estrdup(value(m->attr, "digest", "inedible"));
>  		if(alreadyseen(digestp)){
> -			/* duplicate upas/fs can send duplicate messages */
> +			/* duplicate programs can send duplicate messages */
>  			plumbfree(m);
>  			continue;
>  		}
> -		senderp = estrdup(value(m->attr, "sender", "???"));
> +		facep = estrdup(value(m->attr, "facedir", "/lib/face"));
> +		if(access(facep, AEXIST) == 0){
> +			facedir = dirstat(facep);
> +			if(facedir == nil){
> +				plumbfree(m);
> +				continue;
> +			}
> +			if(facedir->qid.type != QTDIR){
> +				free(facedir);
> +				plumbfree(m);
> +				continue;
> +			}
> +			free(facedir);
> +		}
> +		else {
> +			plumbfree(m);
> +			continue;
> +		}
> +		dstp = estrdup(value(m->attr, "dst", "none"));
> +		senderp = estrdup(value(m->attr, "sender", "unknown"));
> +		winid = estrdup(value(m->attr, "winid", "0"));
> +		xtime = parsedate(value(m->attr, "date", date));
>  		showmailp = estrdup(m->data);
> -		if(digestp)
> -			digestp = estrdup(digestp);
> +		f->str[Sattrs] = plumbpackattr(m->attr);
> +		f->str[Swdir] = estrdup(m->wdir);
>  		plumbfree(m);
>  		setname(f, senderp);
>  		f->time = xtime;
>  		f->tm = *localtime(xtime);
>  		f->str[Sshow] = showmailp;
>  		f->str[Sdigest] = digestp;
> +		f->str[Sdst] = dstp;
> +		f->str[Sfacedir] = facep;
> +		f->str[Swinid] = winid;
>  		return f;
>  	}
>  }
> -
> -char*
> -iline(char *data, char **pp)
> -{
> -	char *p;
> -
> -	for(p=data; *p!='\0' && *p!='\n'; p++)
> -		;
> -	if(*p == '\n')
> -		*p++ = '\0';
> -	*pp = p;
> -	return data;
> -}
> -
> -Face*
> -dirface(char *dir, char *num)
> -{
> -	Face *f;
> -	char *from, *date;
> -	char buf[1024], pwd[1024], *info, *p, *digest;
> -	int n, fd;
> -	ulong len;
> -
> -	/*
> -	 * loadmbox leaves us in maildir, so we needn't
> -	 * walk /mail/fs/mbox for each face; this makes startup
> -	 * a fair bit quicker.
> -	 */
> -	if(getwd(pwd, sizeof pwd) != nil && strcmp(pwd, dir) == 0)
> -		sprint(buf, "%s/info", num);
> -	else
> -		sprint(buf, "%s/%s/info", dir, num);
> -	len = dirlen(buf);
> -	if(len <= 0)
> -		return nil;
> -	fd = open(buf, OREAD);
> -	if(fd < 0)
> -		return nil;
> -	info = emalloc(len+1);
> -	n = readn(fd, info, len);
> -	close(fd);
> -	if(n < 0){
> -		free(info);
> -		return nil;
> -	}
> -	info[n] = '\0';
> -	f = emalloc(sizeof(Face));
> -	from = iline(info, &p);	/* from */
> -	iline(p, &p);	/* to */
> -	iline(p, &p);	/* cc */
> -	iline(p, &p);	/* replyto */
> -	date = iline(p, &p);	/* date */
> -	setname(f, estrdup(from));
> -	f->time = parsedate(date);
> -	f->tm = *localtime(f->time);
> -	sprint(buf, "%s/%s", dir, num);
> -	f->str[Sshow] = estrdup(buf);
> -	iline(p, &p);	/* subject */
> -	iline(p, &p);	/* mime content type */
> -	iline(p, &p);	/* mime disposition */
> -	iline(p, &p);	/* filename */
> -	digest = iline(p, &p);	/* digest */
> -	f->str[Sdigest] = estrdup(digest);
> -	free(info);
> -	return f;
> -}
> diff -r e05e4b6c6546 sys/src/cmd/upas/Mail/mail.c
> --- a/sys/src/cmd/upas/Mail/mail.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/upas/Mail/mail.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -86,7 +86,7 @@
>  
>  	/* open these early so we won't miss notification of new mail messages while we read mbox */
>  	plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
> -	plumbseemailfd = plumbopen("seemail", OREAD|OCEXEC);
> +	plumbseemailfd = plumbopen("notify", OREAD|OCEXEC);
>  	plumbshowmailfd = plumbopen("showmail", OREAD|OCEXEC);
>  
>  	shortmenu = 0;
> diff -r e05e4b6c6546 sys/src/cmd/upas/fs/mbox.c
> --- a/sys/src/cmd/upas/fs/mbox.c	Mon Oct 12 02:03:52 2020 +0200
> +++ b/sys/src/cmd/upas/fs/mbox.c	Wed Oct 14 19:02:10 2020 -0500
> @@ -1547,11 +1547,12 @@
>  static void
>  mailplumb(Mailbox *mb, Message *m)
>  {
> -	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], *from, *subject;
> +	char buf[256], dbuf[SHA1dlen*2 + 1], len[10], date[32], addr[320], *from, *subject, *bang, *unixfrom;
>  	int ai;
>  	Plumbmsg p;
>  	Plumbattr a[7];
>  	static int fd = -1;
> +	int didflip;
>  
>  	subject = m->subject;
>  	if(subject == nil)
> @@ -1572,8 +1573,27 @@
>  	if(fd < 0)
>  		return;
>  
> +	/* convert uucp address for faces */
> +	didflip = 0;
> +	if(from == m->unixfrom){
> +		unixfrom = strdup(m->unixfrom);
> +		if(unixfrom == nil)
> +			return;
> +		bang = strchr(unixfrom, '!');
> +		*bang++ = '\0';
> +		strcpy(addr, bang);
> +		strcat(addr, "@");
> +		strcat(addr, unixfrom);
> +		from = strdup(addr);
> +		if(from == nil){
> +			free(unixfrom);
> +			return;
> +		}
> +		didflip++;
> +	}
> +
>  	p.src = "mailfs";
> -	p.dst = "seemail";
> +	p.dst = "notify";
>  	p.wdir = "/mail/fs";
>  	p.type = "text";
>  
> @@ -1603,12 +1623,18 @@
>  	a[ai].value = date;
>  	a[ai-1].next = &a[ai];
>  
> -	if(m->digest){
> -		snprint(dbuf, sizeof dbuf, "%A", m->digest);
> -		a[++ai].name = "digest";
> -		a[ai].value = dbuf;
> -		a[ai-1].next = &a[ai];
> -	}
> +	if(m->digest == nil)
> +		digestmessage(mb, m);
> +	snprint(dbuf, sizeof dbuf, "%A", m->digest);
> +	
> +	a[++ai].name = "digest";
> +	a[ai].value = dbuf;
> +	a[ai-1].next = &a[ai];
> +
> +	a[++ai].name = "dst";
> +	a[ai].value = "showmail";
> +	a[ai-1].next = &a[ai];
> +	
>  	a[ai].next = nil;
>  	p.attr = a;
>  	snprint(buf, sizeof buf, "%s/%s/%s",
> @@ -1617,6 +1643,11 @@
>  	p.data = buf;
>  
>  	myplumbsend(fd, &p);
> +
> +	if(didflip != 0){
> +		free(unixfrom);
> +		free(from);
> +	}
>  }
>  
>  /*

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-10-18  3:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-14 23:42 [9front] make faces generic covertusername967
2020-10-15  3:24 ` covertusername967
2020-10-17  2:04   ` ori
2020-10-18  3:26     ` covertusername967
2020-10-17  0:26 ` Alex Musolino
2020-10-17  1:07   ` covertusername967
2020-10-17  1:14     ` Silas McCroskey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).