shithub: Nail

Download patch

ref: 2fbe0aa0d0416035e94b39c5099877edb55754af
parent: aff5e269a3630965eced11d9f0a53619e0d89d31
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Nov 4 21:50:13 EST 2020

close all messages when quitting.

--- a/comp.c
+++ b/comp.c
@@ -87,11 +87,13 @@
 	char *a, *f[32];
 	int nf;
 	Event ev;
-	Comp *c;
+	Comp *c, **pc;
 	Fn *p;
 
 	c = cp;
 	c->quitting = 0;
+	c->qnext = mbox.opencomp;
+	mbox.opencomp = c;
 	fprint(c->ctl, "clean\n");
 	mbox.nopen++;
 	while(!c->quitting){
@@ -125,6 +127,9 @@
 		break;
 		}
 	}
+	for(pc = &mbox.opencomp; *pc != nil; *pc = (*pc)->qnext)
+		if(*pc == c)
+			*pc = c->qnext;
 	mbox.nopen--;
 	winclose(c);
 	free(c->replyto);
--- a/mail.h
+++ b/mail.h
@@ -62,14 +62,8 @@
 	char	*rname;
 	char	*rdigest;
 
-	char	**to;
-	int	nto;
-	char	**cc;
-	int	ncc;
-	char	**bcc;
-	int	nbcc;
-
 	int	quitting;
+	Comp	*qnext;
 };
 
 /*
@@ -82,8 +76,8 @@
 	char	*name;
 	int	flags;
 	u32int	hash;
-	Mesg	*hnext;
 	char	quitting;
+	Mesg	*qnext;
 
 	/* exec setup */
 	Channel *sync;
@@ -122,7 +116,6 @@
 struct Mbox {
 	Win;
 
-	/* lock protects mesg, hash */
 	Mesg	**mesg;
 	Mesg	**hash;
 	int	mesgsz;
@@ -129,6 +122,10 @@
 	int	hashsz;
 	int	nmesg;
 	int	ndead;
+
+	Mesg	*openmesg;
+	Comp	*opencomp;
+	int	canquit;
 
 	Channel	*see;
 	Channel	*show;
--- a/mbox.c
+++ b/mbox.c
@@ -544,9 +544,9 @@
 		removeid(m);
 		for(j = 0; j < m->nchild; j++)
 			mbredraw(m->child[j], 1, 1);
-		mesgfree(m);
 		memmove(&mbox.mesg[i], &mbox.mesg[i+1], (mbox.nmesg - i)*sizeof(Mesg*));
 		mbox.nmesg--;
+		mesgfree(m);
 	}
 	close(fd);
 
@@ -553,12 +553,18 @@
 }
 
 static void
-mbdelmesg(char **f, int nf)
+delmesg(char **f, int nf)
 {
 	mark(f, nf, Ftodel, 1);
 }
 
 static void
+undelmesg(char **f, int nf)
+{
+	mark(f, nf, Ftodel, 0);
+}
+
+static void
 mbmarkmesg(char **f, int nf)
 {
 	int flg, add;
@@ -595,7 +601,7 @@
 }
 
 static void
-mbshow(void)
+showlist(void)
 {
 	Biobuf *bfd;
 	Mesg *m;
@@ -611,12 +617,20 @@
 }
 
 static void
-mbquit(char **, int)
+quitall(char **, int)
 {
-	if(mbox.nopen > 0){
+	Mesg *m;
+	Comp *c;
+
+	if(mbox.nopen > 0 && !mbox.canquit){
 		fprint(2, "Del: %d open messages\n", mbox.nopen);
+		mbox.canquit = 1;
 		return;
 	}
+	for(m = mbox.openmesg; m != nil; m = m->qnext)
+		fprint(m->ctl, "del\n");
+	for(c = mbox.opencomp; c != nil; c = c->qnext)
+		fprint(c->ctl, "del\n");
 	fprint(mbox.ctl, "del\n");
 	threadexitsall(nil);
 }
@@ -633,7 +647,7 @@
 
 	digest = plumblookup(pm->attr, "digest");
 	action = plumblookup(pm->attr, "mailtype");
-	fprint(2, "changing message %s, %s %s\n", action, pm->data, digest);
+//	fprint(2, "changing message %s, %s %s\n", action, pm->data, digest);
 	if(strcmp(action, "new") == 0){
 		m = load(pm->data, digest, 1);
 		add = 1;
@@ -659,14 +673,15 @@
 
 Fn mboxfn[] = {
 	{"Put",	mbflush},
-	{"Delmesg", mbdelmesg},
+	{"Delmesg", delmesg},
+	{"Delmesg", undelmesg},
 	{"Mark", mbmarkmesg},
-	{"Del", mbquit},
+	{"Del", quitall},
 #ifdef NOTYET
+	{"Next", nextunread},
 	{"Redisplay", redisplay},
 	{"Filter", filter},
 	{"Get", mbrefresh},
-	{"Next", mboxnext},
 #endif
 	{nil}
 };
@@ -680,7 +695,6 @@
 
 	if(ev->action != 'M')
 		return;
-	print("event %c %s\n", ev->type, ev->text);
 	switch(ev->type){
 	case 'l':
 	case 'L':
@@ -703,25 +717,29 @@
 			}
 		if(p->fn == nil)
 			winreturn(&mbox, ev);
+		else if(p->fn != quitall)
+			mbox.canquit = 0;
 		break;
 	}
 }
 
 static void
-mbmain(void)
+mbmain(void*)
 {
 	Event *ev;
-	Plumbmsg *pm;
+	Plumbmsg *psee, *pshow;
+
 	Alt a[] = {
 	[Cevent]	= {mbox.event, &ev, CHANRCV},
-	[Cseemail]	= {mbox.see, &pm, CHANRCV},
-	[Cshowmail]	= {mbox.show, &pm, CHANRCV},
+	[Cseemail]	= {mbox.see, &psee, CHANRCV},
+	[Cshowmail]	= {mbox.show, &pshow, CHANRCV},
 	[Nchan]		= {nil,	nil, CHANEND},
 	};
 
+	threadsetname("mbox %s", mbox.path);
 	wininit(&mbox, mbox.path);
 	wintagwrite(&mbox, "Put Mail Delmesg Save Next ");
-	mbshow();
+	showlist();
 	fprint(mbox.ctl, "clean\n");
 	proccreate(eventread, nil, Stack);
 	while(1){
@@ -731,12 +749,12 @@
 			free(ev);
 			break;
 		case Cseemail:
-			changemesg(pm);
-			plumbfree(pm);
+			changemesg(psee);
+			plumbfree(psee);
 			break;
 		case Cshowmail:
-			viewmesg(pm);
-			plumbfree(pm);
+			viewmesg(pshow);
+			plumbfree(pshow);
 			break;
 		}
 	}
@@ -788,6 +806,6 @@
 	mbload();
 	proccreate(plumbsee, nil, Stack);
 	proccreate(plumbshow, nil, Stack);
-	threadsetname("mbox %s", mbox.path);
-	mbmain();
+	threadcreate(mbmain, nil, Stack);
+	threadexits(nil);
 }
--- a/mesg.c
+++ b/mesg.c
@@ -339,12 +339,14 @@
 {
 	char *a, *path, *f[32];
 	Event ev;
-	Mesg *m;
+	Mesg *m, **pm;
 	Fn *p;
 	int nf;
 
 	m = mp;
 	m->quitting = 0;
+	m->qnext = mbox.openmesg;
+	mbox.openmesg = m;
 
 	path = estrjoin(mbox.path, m->name, nil);
 	wininit(m, path);
@@ -385,6 +387,9 @@
 			break;
 		}
 	}
+	for(pm = &mbox.openmesg; *pm != nil; *pm = (*pm)->qnext)
+		if(*pm == m)
+			*pm = m->qnext;
 	mbox.nopen--;
 	m->flags &= ~Fopen;
 	winclose(m);