ref: 3889b249d4b18acc2ec85e0a88e0f1c306b4dd29
parent: 84c4c81ceecfa8f51949787fc2dbe7b14164a353
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Dec 1 12:14:13 EST 2019
show and update flags in acme mail now, it's possible to tell whether you've read or replied to a message.
--- a/sys/src/cmd/upas/Mail/dat.h
+++ b/sys/src/cmd/upas/Mail/dat.h
@@ -49,6 +49,7 @@
int ctlfd;
char *name;
char *replyname;
+ char *replydigest;
uchar opened;
uchar dirty;
uchar isreply;
@@ -70,11 +71,12 @@
char *disposition;
char *filename;
char *digest;
+ char *flags;
Message *next; /* next in this mailbox */
Message *prev; /* prev in this mailbox */
Message *head; /* first subpart */
- Message *tail; /* last subpart */
+ Message *tail; /* last subpart */
};
enum
@@ -123,6 +125,7 @@
extern int mesgadd(Message*, char*, Dir*, char*);
extern void mesgmenu(Window*, Message*);
extern void mesgmenunew(Window*, Message*);
+extern void mesgmenureflag(Window*, Message*);
extern int mesgopen(Message*, char*, char*, Message*, int, char*);
extern void mesgctl(void*);
extern void mesgsend(Message*);
@@ -146,6 +149,7 @@
extern void error(char*, ...);
extern int tokenizec(char*, char**, int, char*);
extern void execproc(void*);
+extern void setflags(Message*, char *);
#pragma varargck argpos error 1
#pragma varargck argpos ctlprint 2
--- a/sys/src/cmd/upas/Mail/mesg.c
+++ b/sys/src/cmd/upas/Mail/mesg.c
@@ -132,7 +132,7 @@
/* m->messageid = */ free(line(p, &p));
/* m->lines = */ free(line(p, &p));
/* m->size = */ free(line(p, &p));
- /* m->flags = */ free(line(p, &p));
+ m->flags = line(p, &p);
/* m->fileid = */ free(line(p, &p));
m->fromcolon = fc(m, line(p, &p));
@@ -308,16 +308,38 @@
return s == e? 0: -1;
}
+
void
setflags(Message *m, char *f)
{
- char *t;
+ char *flgchar = "aDdfrsS";
+ char *t, *p;
+ int rm;
t = smprint("%s/%s", mbox.name, m->name);
writefile(t, "flags", f);
free(t);
+ for(; *f; f++){
+ rm = 0;
+ if(*f == '-'){
+ rm = 1;
+ f++;
+ }
+ if((p = strchr(flgchar, *f)) != nil)
+ m->flags[p - flgchar] = rm ? '-' : *f;
+ }
}
+void
+fmtflags(char *b, char *flg)
+{
+ *b++ = '[';
+ *b++ = (strchr(flg, 's') == nil) ? '*' : ' '; /* unread */
+ *b++ = (strchr(flg, 'a') == nil) ? ' ' : 'R'; /* answered */
+ *b++ = ']';
+ *b = '\0';
+}
+
char*
info(Message *m, int ind, int ogf)
{
@@ -324,7 +346,7 @@
char *i;
int j, len, lens;
char *p;
- char fmt[80], s[80];
+ char fmt[80], s[80], flg[16];
if (ogf)
p=m->to;
@@ -331,6 +353,7 @@
else
p=m->fromcolon;
+ fmtflags(flg, m->flags);
if(ind==0 && altmenu){
len = 12;
lens = 20;
@@ -369,6 +392,7 @@
}
i = estrdup("");
+ i = eappend(i, " ", flg);
i = eappend(i, "\t", p);
i = egrow(i, "\t", stripdate(m->date));
if(ind == 0){
@@ -538,6 +562,24 @@
}
void
+mesgmenureflag(Window *w, Message *m)
+{
+ char *buf, flg[16];
+
+ fmtflags(flg, m->flags);
+ buf = name2regexp(deletedrx01, m->name);
+ strcat(buf, "+/\\[[^\\]]*\\]/");
+ if(w->data < 0)
+ w->data = winopenfile(w, "data");
+ if(winselect(w, buf, 1))
+ write(w->data, flg, strlen(flg));
+ free(buf);
+
+ close(w->data);
+ w->data = -1;
+}
+
+void
mesgmenumark(Window *w, char *which, char *mark)
{
char *buf;
@@ -570,6 +612,7 @@
free(m->type);
free(m->disposition);
free(m->filename);
+ free(m->flags);
free(m->digest);
}
@@ -1312,6 +1355,7 @@
winclean(m->w);
m->opened = 1;
setflags(m, "s");
+ mesgmenureflag(mbox->w, m);
if(ndirelem == 1){
free(u);
return 1;
--- a/sys/src/cmd/upas/Mail/reply.c
+++ b/sys/src/cmd/upas/Mail/reply.c
@@ -77,8 +77,10 @@
quotereply = (label[0] == 'Q');
r = emalloc(sizeof(Message));
r->isreply = 1;
- if(m != nil)
+ if(m != nil){
r->replyname = estrdup(m->name);
+ r->replydigest = estrdup(m->digest);
+ }
r->next = replies.head;
r->prev = nil;
if(replies.head != nil)
@@ -184,7 +186,7 @@
void
execproc(void *v)
{
- struct Exec *e;
+ Exec *e;
int p[2], q[2];
char *prog;
char *argv[NARGS+1], args[NARGCHAR];
@@ -382,8 +384,9 @@
{
char *s, *body, *to;
int i, j, h, n, natt, p[2];
- struct Exec *e;
+ Exec *e;
Channel *sync;
+ Message *r;
int first, nfld, delit, ofd;
char *copy, *fld[100], *now;
@@ -479,7 +482,7 @@
fprint(ofd, "Content-Transfer-Encoding: 8bit\n");
}
- e = emalloc(sizeof(struct Exec));
+ e = emalloc(sizeof(Exec));
if(pipe(p) < 0)
error("can't create pipe: %r");
e->p[0] = p[0];
@@ -553,8 +556,13 @@
close(p[1]);
free(body);
- if(m->replyname != nil)
- mesgmenumark(mbox.w, m->replyname, "\t[replied]");
+ print("replyname: %s, replydigest=%s\n", m->replyname, m->replydigest);
+ if(m->replyname){
+ if((r = mesglookup(&mbox, m->replyname, m->replydigest)) != nil){
+ setflags(r, "a");
+ mesgmenureflag(mbox.w, r);
+ }
+ }
if(m->name[0] == '/')
s = estrdup(m->name);
else