Acme/Mail displays the date from the last Received: header, which can be considerably different from the date when the message was first sent. The format of the acme/mail date is by its nature local time, which is helpful. This is a stab at displaying a more useful date, as in my particular case messages are batched together and the date of delivery conveys a false impression. I have not felt a need to convert the date to localtime, although no doubt that would appeal to many users. It is also not a trivial operation, of course, what with all the formats in use. I'm submitting this more for discussion than for actual incorporation, although it would be nice not to have to treat this module as a special case on replication. Lucio De Re. Notes: Sun Nov 6 09:48:26 EST 2005 rsc As I'm sure you expected, I'm not going to apply this. You have correctly listed all the reasons that we use the received: line - it's local time, it reflects actual delivery, it's standardized and easy to parse (since we generated it), and so on. It's also consistent with upas/fs. As far as parsing the RFC822 date goes, you can just copy /sys/src/cmd/upas/fs/strtotm.c. The error() changes are just wrong - the Mail: prefix is added by error and need not be in the string. A (clumsy) alternative is to read your mail via POP3, so that the Unix from line is dropped completely anyway. In this case upas/fs will use the RFC822 date because that is the only choice it has. Russ Reference: /n/sources/patch/sorry/rfc822date Date: Sat Nov 5 17:58:02 CET 2005 Reviewed-by: rsc --- /acme/mail/src/mesg.c Sat Nov 5 17:49:58 2005 +++ /acme/mail/src/mesg.c Sat Nov 5 17:49:17 2005 @@ -136,6 +136,9 @@ m->disposition = line(p, &p); m->filename = line(p, &p); m->digest = line(p, &p); + line(p, &p); + line(p, &p); + m->rfc822date = line(p, &p); free(data); return 1; } @@ -264,6 +267,34 @@ } char* +rfc822date(char *as) +{ + int n; + char *s, *fld[10]; + + as = estrdup(as); + s = estrdup(as); + n = tokenize(s, fld, 10); + if(n > 5){ + sprint(as, "%.3s ", fld[0]); /* day */ + /* some dates have 19 Apr, some Apr 19 */ + if(strlen(fld[1])<4 && isnumeric(fld[1])) + sprint(as+strlen(as), "%.3s %.3s ", fld[1], fld[2]); /* day, month */ + else + sprint(as+strlen(as), "%.3s %.3s ", fld[2], fld[1]); /* month, day */ + /* do we use time or year? depends on whether year matches this one */ + if(thisyear(fld[3])){ + if(strchr(fld[4], ':') != nil) + sprint(as+strlen(as), "%.5s ", fld[4]); /* time */ + }else + sprint(as+strlen(as), "%.4s ", fld[3]); /* year */ + sprint(as+strlen(as), "%.5s", fld[5]); /* timezone */ + } + free(s); + return as; +} + +char* readfile(char *dir, char *name, int *np) { char *file, *data; @@ -324,7 +355,7 @@ i = estrdup(""); i = eappend(i, "\t", p); - i = egrow(i, "\t", stripdate(m->date)); + i = egrow(i, "\t", rfc822date(m->rfc822date)); if(ind == 0){ if(strcmp(m->type, "text")!=0 && strncmp(m->type, "text/", 5)!=0 && strncmp(m->type, "multipart/", 10)!=0) @@ -525,6 +556,7 @@ free(m->disposition); free(m->filename); free(m->digest); + free(m->rfc822date); } void @@ -533,7 +565,7 @@ Message *n, *next; if(m->opened) - error("internal error: deleted message still open in mesgdel"); + error("Mail: internal error: deleted message still open in mesgdel\n"); /* delete subparts */ for(n=m->head; n!=nil; n=next){ next = n->next;