URI: 
       tchanges - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 3f8c36d6dc30334bbff4f90e182812e9bd94153c
   DIR parent 330e487a1d3e2c65fc1132e8752f95e4fa4857df
  HTML Author: rsc <devnull@localhost>
       Date:   Thu,  9 Feb 2006 20:52:31 +0000
       
       changes
       
       Diffstat:
         M src/cmd/acme/mail/dat.h             |      16 ++++++----------
         M src/cmd/acme/mail/html.c            |       5 ++---
         M src/cmd/acme/mail/mail.c            |      94 +++++++++++++++----------------
         M src/cmd/acme/mail/mesg.c            |     352 +++++++++++++------------------
         M src/cmd/acme/mail/reply.c           |     124 +++++--------------------------
         M src/cmd/acme/mail/util.c            |      67 +------------------------------
         M src/cmd/acme/mail/win.c             |      79 +++++--------------------------
       
       7 files changed, 238 insertions(+), 499 deletions(-)
       ---
   DIR diff --git a/src/cmd/acme/mail/dat.h b/src/cmd/acme/mail/dat.h
       t@@ -26,11 +26,6 @@ struct Event
        struct Window
        {
                /* file descriptors */
       -/* jpc        int                ctl;
       -        int                event;
       -        int                addr;
       -        int                data; 
       -        Biobuf        *body; jpc */
                CFid*                ctl;
                CFid*                event;
                CFid*                addr;
       t@@ -51,7 +46,7 @@ struct Window
        struct Message
        {
                Window        *w;
       -        int                ctlfd;
       +        CFid*        ctlfd;
                char                *name;
                char                *replyname;
                uchar        opened;
       t@@ -64,7 +59,6 @@ struct Message
                uchar        level;
        
                /* header info */
       -        char                *fromcolon;        /* from header file; all rest are from info file */
                char                *from;
                char                *to;
                char                *cc;
       t@@ -99,8 +93,7 @@ struct Exec
        };
        
        extern        Window*        newwindow(void);
       -extern        int                winopenfile(Window*, char*);
       -extern        CFid*        winopenfid(Window*, char*);
       +extern        CFid*        winopenfile(Window*, char*);
        extern        void                winopenbody(Window*, int);
        extern        void                winclosebody(Window*);
        extern        void                wintagwrite(Window*, char*, int);
       t@@ -141,7 +134,6 @@ extern        void                mesgfreeparts(Message*);
        
        extern        char*        readfile(char*, char*, int*);
        extern        char*        readbody(char*, char*, int*);
       -// jpc extern        void                ctlprint(int, char*, ...);
        extern        void                ctlprint(CFid*, char*, ...);
        extern        void*        emalloc(uint);
        extern        void*        erealloc(void*, uint);
       t@@ -170,3 +162,7 @@ extern        char                *user;
        extern        char                deleted[];
        extern        int                wctlfd;
        extern        int                shortmenu;
       +
       +extern        CFsys        *mailfs;
       +extern        CFsys        *acmefs;
       +
   DIR diff --git a/src/cmd/acme/mail/html.c b/src/cmd/acme/mail/html.c
       t@@ -7,7 +7,6 @@
        #include <9pclient.h>
        #include "dat.h"
        
       -
        char*
        formathtml(char *body, int *np)
        {
       t@@ -28,12 +27,12 @@ formathtml(char *body, int *np)
                e->argv[0] = estrdup("htmlfmt");
                e->argv[1] = estrdup("-cutf-8");
                e->argv[2] = nil;
       -        e->prog = unsharp("#9/bin/htmlfmt");
       +        e->prog = "htmlfmt";
                sync = chancreate(sizeof(int), 0);
                e->sync = sync;
                proccreate(execproc, e, EXECSTACK);
                recvul(sync);
       -        // close(p[0]);
       +        close(p[0]);
                close(q[1]);
        
                if((i=write(p[1], body, *np)) != *np){
   DIR diff --git a/src/cmd/acme/mail/mail.c b/src/cmd/acme/mail/mail.c
       t@@ -4,12 +4,11 @@
        #include <thread.h>
        #include <plumb.h>
        #include <ctype.h>
       -#include <9pclient.h> /* jpc */
       +#include <9pclient.h>
        #include "dat.h"
        
       -char        *maildir = "/mail/fs/";                        /* mountpoint of mail file system */
       -char        *mailtermdir = "/mnt/term/mail/fs/";        /* alternate mountpoint */
       -char *mboxname = "mbox";                        /* mailboxdir/mboxname is mail spool file */
       +char        *maildir = "/mail/";                        /* mountpoint of mail file system */
       +char *mboxname = "INBOX";                        /* mailboxdir/mboxname is mail spool file */
        char        *mailboxdir = nil;                                /* nil == /mail/box/$user */
        char *fsname;                                                /* filesystem for mailboxdir/mboxname is at maildir/fsname */
        char        *user;
       t@@ -37,8 +36,8 @@ void                plumbsendthread(void*);
        
        int                        shortmenu;
        
       -CFsys *upasfs;  /*jpc */
       -CFsys *acmefs; /*jpc */
       +CFsys *mailfs;
       +CFsys *acmefs;
        
        void
        usage(void)
       t@@ -55,7 +54,7 @@ removeupasfs(void)
                if(strcmp(mboxname, "mbox") == 0)
                        return;
                snprint(buf, sizeof buf, "close %s", mboxname);
       -        write(mbox.ctlfd, buf, strlen(buf));
       +        fswrite(mbox.ctlfd, buf, strlen(buf));
        }
        
        int
       t@@ -90,11 +89,6 @@ threadmain(int argc, char *argv[])
                plumbseemailfd = plumbopen("seemail", OREAD|OCEXEC);
                plumbshowmailfd = plumbopen("showmail", OREAD|OCEXEC);
        
       -        /* jpc */
       -        acmefs = nsmount("acme",nil);
       -        upasfs = nsmount("upasfs", nil);
       -        /* jpc end */
       -
                shortmenu = 0;
                ARGBEGIN{
                case 's':
       t@@ -113,13 +107,14 @@ threadmain(int argc, char *argv[])
                        usage();
                }ARGEND
        
       -        name = "mbox";
       +        acmefs = nsmount("acme",nil);
       +        if(acmefs == nil)
       +                error("cannot mount acme: %r");
       +        mailfs = nsmount("mail", nil);
       +        if(mailfs == nil)
       +                error("cannot mount mail: %r");
        
       -        /* bind the terminal /mail/fs directory over the local one */
       -        if(access(maildir, 0)<0 && access(mailtermdir, 0)==0) {
       -                /* jpc - bind(mailtermdir, maildir, MAFTER); */
       -                fprint(2,"jpc: trying to bind(mailtermdir, maildir, MAFTER)\n");
       -        }
       +        name = "INBOX";
        
                newdir = 1;
                if(argc > 0){
       t@@ -154,27 +149,31 @@ threadmain(int argc, char *argv[])
                user = getenv("user");
                if(user == nil)
                        user = "none";
       +        home = getenv("home");
       +        if(home == nil)
       +                home = getenv("HOME");
       +        if(home == nil)
       +                error("can't find $home");
                if(mailboxdir == nil)
       -                mailboxdir = estrstrdup(unsharp("#9/mail/box/"), user);
       +                mailboxdir = estrstrdup(home, "/mail");
                if(outgoing == nil)
                        outgoing = estrstrdup(mailboxdir, "/outgoing");
        
       -        // s = estrstrdup(maildir, "ctl");
       -        mbox.ctlfd = fsopenfd(upasfs,"ctl", ORDWR|OCEXEC);
       -        if(mbox.ctlfd < 0)
       -                error("can't open %s: %r\n", s);
       +        mbox.ctlfd = fsopen(mailfs, "INBOX/ctl", OWRITE);
       +        if(mbox.ctlfd == nil)
       +                error("can't open %s: %r", "INBOX/ctl");
        
                fsname = estrdup(name);
                if(newdir && argc > 0){
                        s = emalloc(5+strlen(mailboxdir)+strlen(mboxname)+strlen(name)+10+1);
                        for(i=0; i<10; i++){
                                sprint(s, "open %s/%s %s", mailboxdir, mboxname, fsname);
       -                        if(write(mbox.ctlfd, s, strlen(s)) >= 0)
       +                        if(fswrite(mbox.ctlfd, s, strlen(s)) >= 0)
                                        break;
                                err[0] = '\0';
                                errstr(err, sizeof err);
                                if(strstr(err, "mbox name in use") == nil)
       -                                error("can't create directory %s for mail: %s\n", name, err);
       +                                error("can't create directory %s for mail: %s", name, err);
                                free(fsname);
                                fsname = emalloc(strlen(name)+10);
                                sprint(fsname, "%s-%d", name, i);
       t@@ -186,7 +185,6 @@ threadmain(int argc, char *argv[])
        
                s = estrstrdup(fsname, "/");
                mbox.name = estrstrdup(maildir, s);
       -        // mbox.name = "/mail/fs/mbox/";
                mbox.level= 0;
                readmbox(&mbox, maildir, s);
                home = getenv("home");
       t@@ -212,13 +210,13 @@ threadmain(int argc, char *argv[])
                mbox.w = wbox;
        
                mesgmenu(wbox, &mbox);
       -        // sleep(100);
                winclean(wbox);
        
       -        wctlfd = open("/dev/wctl", OWRITE|OCEXEC);        /* for acme window */
       +/*        wctlfd = open("/dev/wctl", OWRITE|OCEXEC);        /* for acme window */
       +        wctlfd = -1;
                cplumb = chancreate(sizeof(Plumbmsg*), 0);
                cplumbshow = chancreate(sizeof(Plumbmsg*), 0);
       -        if(strcmp(name, "mbox") == 0){
       +        if(strcmp(name, "INBOX") == 0){
                        /*
                         * Avoid creating multiple windows to send mail by only accepting
                         * sendmail plumb messages if we're reading the main mailbox.
       t@@ -282,24 +280,18 @@ void
        newmesg(char *name, char *digest)
        {
                Dir *d;
       -        char* tmp;
        
       -        if(strncmp(name, mbox.name, strlen(mbox.name)) != 0) {
       +        if(strncmp(name, mbox.name, strlen(mbox.name)) != 0)
                        return;        /* message is about another mailbox */
       -        }
       -        if(mesglookupfile(&mbox, name, digest) != nil) {
       +        if(mesglookupfile(&mbox, name, digest) != nil)
                        return;
       -        }
       -        if (strncmp(name,"/mail/fs/",strlen("/mail/fs/"))==0) {
       -                tmp = name+strlen("/mail/fs/");
       -        }
       -        d = fsdirstat(upasfs,tmp);
       -        if(d == nil) {
       +        if(strncmp(name, "/mail/", 6) == 0)
       +                name += 6;
       +        d = fsdirstat(mailfs, name);
       +        if(d == nil)
                        return;
       -        }
       -        if(mesgadd(&mbox, mbox.name, d, digest)) {
       +        if(mesgadd(&mbox, mbox.name, d, digest))
                        mesgmenunew(wbox, &mbox);
       -        }
                free(d);
        }
        
       t@@ -307,13 +299,17 @@ void
        showmesg(char *name, char *digest)
        {
                char *n;
       -
       -        if(strncmp(name, mbox.name, strlen(mbox.name)) != 0)
       +        char *mb;
       +        
       +        mb = mbox.name;
       +        if(strncmp(mb, "/mail/", 6) == 0)
       +                mb += 6;
       +        if(strncmp(name, mb, strlen(mb)) != 0)
                        return;        /* message is about another mailbox */
       -        n = estrdup(name+strlen(mbox.name));
       +        n = estrdup(name+strlen(mb));
                if(n[strlen(n)-1] != '/')
                        n = egrow(n, "/", nil);
       -        mesgopen(&mbox, mbox.name, name+strlen(mbox.name), nil, 1, digest);
       +        mesgopen(&mbox, mbox.name, name+strlen(mb), nil, 1, digest);
                free(n);
        }
        
       t@@ -356,10 +352,11 @@ plumbthread(void)
        }
        
        void
       -plumbshowthread(void* v)
       +plumbshowthread(void *v)
        {
                Plumbmsg *m;
        
       +        USED(v);
                threadsetname("plumbshowthread");
                while((m = recvp(cplumbshow)) != nil){
                        showmesg(m->data, plumblookup(m->attr, "digest"));
       t@@ -369,10 +366,11 @@ plumbshowthread(void* v)
        }
        
        void
       -plumbsendthread(void* v)
       +plumbsendthread(void *v)
        {
                Plumbmsg *m;
        
       +        USED(v);
                threadsetname("plumbsendthread");
                while((m = recvp(cplumbsend)) != nil){
                        mkreply(nil, "Mail", m->data, m->attr, nil);
   DIR diff --git a/src/cmd/acme/mail/mesg.c b/src/cmd/acme/mail/mesg.c
       t@@ -4,11 +4,9 @@
        #include <thread.h>
        #include <ctype.h>
        #include <plumb.h>
       -#include <9pclient.h> /* jpc */
       +#include <9pclient.h>
        #include "dat.h"
        
       -extern CFsys *upasfs; /* jpc */
       -
        enum
        {
                DIRCHUNK = 32*sizeof(Dir)
       t@@ -90,56 +88,101 @@ line(char *data, char **pp)
                return q;
        }
        
       -void
       -scanheaders(Message *m, char *dir)
       +static char*
       +mkaddrs(char *t)
        {
       -        char *s, *t, *u, *f;
       -
       -        s = f = readfile(dir, "header", nil);
       -        if(s != nil)
       -                while(*s){
       -                        t = line(s, &s);
       -                        if(strncmp(t, "From: ", 6) == 0){
       -                                m->fromcolon = estrdup(t+6);
       -                                /* remove all quotes; they're ugly and irregular */
       -                                for(u=m->fromcolon; *u; u++)
       -                                        if(*u == '"')
       -                                                memmove(u, u+1, strlen(u));
       -                        }
       -                        if(strncmp(t, "Subject: ", 9) == 0)
       -                                m->subject = estrdup(t+9);
       -                        free(t);
       -                }
       -        if(m->fromcolon == nil)
       -                m->fromcolon = estrdup(m->from);
       +        int i, nf, inquote;
       +        char **f, *s;
       +        Fmt fmt;
       +        
       +        inquote = 0;
       +        nf = 2;
       +        for(s=t; *s; s++){
       +                if(*s == '\'')
       +                        inquote = !inquote;
       +                if(*s == ' ' && !inquote)
       +                        nf++;
       +        }
       +        f = emalloc(nf*sizeof f[0]);
       +        nf = tokenize(t, f, nf);
       +        fmtstrinit(&fmt);
       +        for(i=0; i+1<nf; i+=2){
       +                if(i > 0)
       +                        fmtprint(&fmt, ", ");
       +                if(f[i][0] == 0 || strcmp(f[i], f[i+1]) == 0)
       +                        fmtprint(&fmt, "%s", f[i+1]);
       +                else
       +                        fmtprint(&fmt, "%s <%s>", f[i], f[i+1]);
       +        }
                free(f);
       +        return fmtstrflush(&fmt);
        }
        
        int
        loadinfo(Message *m, char *dir)
        {
                int n;
       -        char *data, *p, *s;
       +        char *data, *p, *s, *t;
        
                data = readfile(dir, "info", &n);
                if(data == nil)
                        return 0;
       -        m->from = line(data, &p);
       -        scanheaders(m, dir);        /* depends on m->from being set */
       -        m->to = line(p, &p);
       -        m->cc = line(p, &p);
       -        m->replyto = line(p, &p);
       -        m->date = line(p, &p);
       -        s = line(p, &p);
       -        if(m->subject == nil)
       -                m->subject = s;
       -        else
       +        
       +        p = data;
       +        while((s = line(p, &p)) != nil && *s != 0){
       +                t = strchr(s, ' ');
       +                if(t == nil)
       +                        continue;
       +                *t++ = 0;
       +                if(strcmp(s, "from") == 0){
       +                        free(m->from);
       +                        m->from = mkaddrs(t);
       +                }else if(strcmp(s, "to") == 0){
       +                        free(m->to);
       +                        m->from = mkaddrs(t);
       +                }else if(strcmp(s, "cc") == 0){
       +                        free(m->cc);
       +                        m->from = mkaddrs(t);
       +                }else if(strcmp(s, "replyto") == 0){
       +                        free(m->replyto);
       +                        m->from = mkaddrs(t);
       +                }else if(strcmp(s, "subject") == 0){
       +                        free(m->subject);
       +                        m->subject = estrdup(t);
       +                }else if(strcmp(s, "type") == 0){
       +                        free(m->type);
       +                        m->type = estrdup(t);
       +                }else if(strcmp(s, "unixdate") == 0 && (t=strchr(t, ' ')) != nil){
       +                        free(m->date);
       +                        m->date = estrdup(t+1);
       +                }else if(strcmp(s, "messageid") == 0){
       +                        free(m->digest);
       +                        m->digest = estrdup(t);
       +                }
                        free(s);
       -        m->type = line(p, &p);
       -        m->disposition = line(p, &p);
       -        m->filename = line(p, &p);
       -        m->digest = line(p, &p);
       +        }
       +        free(s);
                free(data);
       +        if(m->from == nil)
       +                m->from = estrdup("");
       +        if(m->to == nil)
       +                m->to = estrdup("");
       +        if(m->cc == nil)
       +                m->cc = estrdup("");
       +        if(m->replyto == nil)
       +                m->replyto = estrdup("");
       +        if(m->subject == nil)
       +                m->subject = estrdup("");
       +        if(m->type == nil)
       +                m->type = estrdup("");
       +        if(m->date == nil)
       +                m->date = estrdup("");
       +        if(m->disposition == nil)
       +                m->disposition = estrdup("");
       +        if(m->filename == nil)
       +                m->filename = estrdup("");
       +        if(m->digest == nil)
       +                m->digest = estrdup("");
                return 1;
        }
        
       t@@ -154,22 +197,25 @@ isnumeric(char *s)
                return 1;
        }
        
       +CFid*
       +mailopen(char *name, int mode)
       +{
       +        if(strncmp(name, "/mail/", 6) != 0)
       +                return nil;
       +        return fsopen(mailfs, name+6, mode);
       +}
       +
        Dir*
        loaddir(char *name, int *np)
        {
                CFid *fid;
                Dir *dp;
       -        char *tmp;
        
       -        if (strncmp(name,"/mail/fs/",strlen("/mail/fs/"))==0) {
       -                tmp = name+strlen("/mail/fs/");
       -        }
       -        fid = fsopen(upasfs,tmp,OREAD);
       +        fid = mailopen(name, OREAD);
                if(fid == nil)
                        return nil;
                *np = fsdirreadall(fid, &dp);
                fsclose(fid);
       -
                return dp;
        }
        
       t@@ -275,38 +321,33 @@ char*
        readfile(char *dir, char *name, int *np)
        {
                char *file, *data;
       -/*        int fd, len;        jpc */
                int len;
                Dir *d;
                CFid *fid;
       -        char *tmp;
       +        char buf[1];
        
                if(np != nil)
                        *np = 0;
                file = estrstrdup(dir, name);
       -/*        fd = open(file, OREAD);
       -        if(fd < 0)
       -                return nil;
       -        d = dirfstat(fd); jpc */
       -        if (strncmp(file,"/mail/fs/",strlen("/mail/fs/"))==0) {
       -                tmp = file+strlen("/mail/fs/");
       -        }
       -        fid = fsopen(upasfs,tmp, OREAD);
       +        fid = mailopen(file, OREAD);
                if(fid == nil)
                        return nil;
                d = fsdirfstat(fid);
       -/* jpc end */
       +        if(d && d->length == 0){
       +                /* some files, e.g. body, are not loaded until we read them */
       +                fsread(fid, buf, 1);
       +                fsseek(fid, 0, 0);
       +                free(d);
       +                d = fsdirfstat(fid);
       +        }        
                free(file);
                len = 0;
                if(d != nil)
                        len = d->length;
                free(d);
                data = emalloc(len+1);
       -/*        read(fd, data, len);
       -        close(fd);        jpc */
                fsread(fid, data, len);
                fsclose(fid);
       -/*        jpc */
                if(np != nil)
                        *np = len;
                return data;
       t@@ -323,7 +364,7 @@ info(Message *m, int ind, int ogf)
                if (ogf)
                        p=m->to;
                else
       -                p=m->fromcolon;
       +                p=m->from;
        
                if(ind==0 && shortmenu){
                        len = 30;
       t@@ -362,52 +403,12 @@ info(Message *m, int ind, int ogf)
                return i;
        }
        
       -#if 0 /* jpc */
       -void
       -mesgmenu0(Window *w, Message *mbox, char *realdir, char *dir, int ind, Biobuf *fd, int onlyone, int dotail)
       -{
       -        int i;
       -        Message *m;
       -        char *name, *tmp;
       -        int ogf=0;
       -
       -        if(strstr(realdir, "outgoing") != nil)
       -                ogf=1;
       -
       -        /* show mail box in reverse order, pieces in forward order */
       -        if(ind > 0)
       -                m = mbox->head;
       -        else
       -                m = mbox->tail;
       -        while(m != nil){
       -                for(i=0; i<ind; i++)
       -                        Bprint(fd, "\t");
       -                if(ind != 0)
       -                        Bprint(fd, "  ");
       -                name = estrstrdup(dir, m->name);
       -                tmp = info(m, ind, ogf);
       -                Bprint(fd, "%s%s\n", name, tmp);
       -                free(tmp);
       -                if(dotail && m->tail)
       -                        mesgmenu0(w, m, realdir, name, ind+1, fd, 0, dotail);
       -                free(name);
       -                if(ind)
       -                        m = m->next;
       -                else
       -                        m = m->prev;
       -                if(onlyone)
       -                        m = nil;
       -        }
       -}
       -#endif
       -
        void
        mesgmenu0(Window *w, Message *mbox, char *realdir, char *dir, int ind, CFid *fd, int onlyone, int dotail)
        {
                int i;
                Message *m;
                char *name, *tmp;
       -        //1 char ntmp[250];
                int ogf=0;
        
                if(strstr(realdir, "outgoing") != nil)
       t@@ -420,16 +421,11 @@ mesgmenu0(Window *w, Message *mbox, char *realdir, char *dir, int ind, CFid *fd,
                        m = mbox->tail;
                while(m != nil){
                        for(i=0; i<ind; i++)
       -                        fswrite(fd, "\t", strlen("\t"));
       -                        /* Bprint(fd, "\t"); jpc */
       +                        fsprint(fd, "\t");
                        if(ind != 0)
       -                        fswrite(fd, "  ", strlen("  "));
       -                        /* Bprint(fd, "  "); jpc */
       +                        fsprint(fd, "  ");
                        name = estrstrdup(dir, m->name);
                        tmp = info(m, ind, ogf);
       -                /* Bprint(fd, "%s%s\n", name, tmp); jpc */
       -                // snprint(ntmp,250, "%s%s\n", name, tmp);
       -                // fswrite(fd, ntmp, strlen(ntmp));
                        fsprint(fd, "%s%s\n", name, tmp);
                        free(tmp);
                        if(dotail && m->tail)
       t@@ -459,12 +455,8 @@ mesgmenunew(Window *w, Message *mbox)
                Biobuf *b;
        
                winselect(w, "0", 0);
       -        w->data = winopenfid(w, "data");
       +        w->data = winopenfile(w, "data");
                b = emalloc(sizeof(Biobuf));
       -/*        Binit(b, w->data, OWRITE);
       -        mesgmenu0(w, mbox, mbox->name, "", 0, b, 1, !shortmenu);
       -        Bterm(b);
       -jpc */
                mesgmenu0(w, mbox, mbox->name, "", 0, w->data, 1, !shortmenu);
                free(b);
                if(!mbox->dirty)
       t@@ -509,12 +501,11 @@ mesgmenumarkdel(Window *w, Message *mbox, Message *m, int writeback)
                        return;
                m->writebackdel = writeback;
                if(w->data == nil)
       -                w->data = winopenfid(w, "data");
       +                w->data = winopenfile(w, "data");
                buf = name2regexp("", m->name);
                strcat(buf, "-#0");
       -        if(winselect(w, buf, 1)) {
       +        if(winselect(w, buf, 1))
                        fswrite(w->data, deleted, 10);
       -        }
                free(buf);
                fsclose(w->data);
                fsclose(w->addr);
       t@@ -525,21 +516,19 @@ mesgmenumarkdel(Window *w, Message *mbox, Message *m, int writeback)
        }
        
        void
       -mesgmenumarkundel(Window *w, Message* v, Message *m)
       +mesgmenumarkundel(Window *w, Message *v, Message *m)
        {
                char *buf;
        
       +        USED(v);
                if(m->deleted == 0)
                        return;
                if(w->data == nil)
       -                w->data = winopenfid(w, "data");
       +                w->data = winopenfile(w, "data");
                buf = name2regexp(deletedrx, m->name);
       -        if(winselect(w, buf, 1)) {
       -                if(winsetaddr(w, deletedaddr, 1)) {
       +        if(winselect(w, buf, 1))
       +                if(winsetaddr(w, deletedaddr, 1))
                                fswrite(w->data, "", 0);
       -                        // fsync(w->data);
       -                }
       -        }
                free(buf);
                fsclose(w->data);
                fsclose(w->addr);
       t@@ -554,12 +543,10 @@ mesgmenudel(Window *w, Message *mbox, Message *m)
                char *buf;
        
                if(w->data ==nil)
       -                w->data = winopenfid(w, "data");
       +                w->data = winopenfile(w, "data");
                buf = name2regexp(deletedrx, m->name);
       -        if(winsetaddr(w, buf, 1) && winsetaddr(w, ".,./.*\\n(\t.*\\n)*/", 1)) {
       +        if(winsetaddr(w, buf, 1) && winsetaddr(w, ".,./.*\\n(\t.*\\n)*/", 1))
                        fswrite(w->data, "", 0);
       -                // fsync(w->data);
       -        }
                free(buf);
                fsclose(w->data);
                fsclose(w->addr);
       t@@ -575,12 +562,10 @@ mesgmenumark(Window *w, char *which, char *mark)
                char *buf;
        
                if(w->data == nil)
       -                w->data = winopenfid(w, "data");
       +                w->data = winopenfile(w, "data");
                buf = name2regexp(deletedrx01, which);
       -        if(winsetaddr(w, buf, 1) && winsetaddr(w, "+0-#1", 1)) {        /* go to end of line */
       +        if(winsetaddr(w, buf, 1) && winsetaddr(w, "+0-#1", 1))        /* go to end of line */
                        fswrite(w->data, mark, strlen(mark));
       -                // fsync(w->data);
       -        }
                free(buf);
                fsclose(w->data);
                fsclose(w->addr);
       t@@ -595,7 +580,6 @@ mesgfreeparts(Message *m)
        {
                free(m->name);
                free(m->replyname);
       -        free(m->fromcolon);
                free(m->from);
                free(m->to);
                free(m->cc);
       t@@ -634,11 +618,19 @@ mesgdel(Message *mbox, Message *m)
        }
        
        int
       -mesgsave(Message *m, char *s)
       +mesgsave(Message *m, char *s, int save)
        {
                int ofd, n, k, ret;
                char *t, *raw, *unixheader, *all;
        
       +        if(save){
       +                if(fsprint(mbox.ctlfd, "save %q %q", m->name, s) < 0){
       +                        fprint(2, "Mail: can't save %s to %s: %r\n", m->name, s);
       +                        return 0;
       +                }
       +                return 1;
       +        }
       +                
                t = estrstrdup(mbox.name, m->name);
                raw = readfile(t, "raw", &n);
                unixheader = readfile(t, "unixheader", &k);
       t@@ -679,7 +671,7 @@ mesgcommand(Message *m, char *cmd)
        {
                char *s;
                char *args[10];
       -        int ok, ret, nargs;
       +        int save, ok, ret, nargs;
        
                s = cmd;
                ret = 1;
       t@@ -690,14 +682,18 @@ mesgcommand(Message *m, char *cmd)
                        mesgsend(m);
                        goto Return;
                }
       -        if(strncmp(args[0], "Save", 4) == 0){
       +        if(strncmp(args[0], "Save", 4) == 0 || strncmp(args[0], "Write", 5) == 0){
                        if(m->isreply)
                                goto Return;
       -                s = estrdup("\t[saved");
       +                save = args[0][0]=='S';
       +                if(save)
       +                        s = estrdup("\t[saved");
       +                else
       +                        s = estrdup("\t[wrote");
                        if(nargs==1 || strcmp(args[1], "")==0){
       -                        ok = mesgsave(m, "stored");
       +                        ok = mesgsave(m, "stored", save);
                        }else{
       -                        ok = mesgsave(m, args[1]);
       +                        ok = mesgsave(m, args[1], save);
                                s = eappend(s, " ", args[1]);
                        }
                        if(ok){
       t@@ -789,7 +785,6 @@ eval(Window *w, char *s, ...)
                if(winsetaddr(w, buf, 1)==0)
                        return -1;
        
       -//        if(pread(w->addr, buf, 24, 0) != 24)
                if(fspread(w->addr, buf, 24, 0) != 24)
                        return -1;
                return strtol(buf, 0, 10);
       t@@ -999,13 +994,8 @@ mesgctl(void *v)
        void
        mesgline(Message *m, char *header, char *value)
        {
       -        //1 char *tmp;
       -        //1 tmp = emalloc(strlen(header)+2+strlen(value)+1);
       -
       -        if(strlen(value) > 0) {
       -                // jpc Bprint(m->w->body, "%s: %s\n", header, value);
       +        if(strlen(value) > 0)
                        fsprint(m->w->body, "%s: %s\n", header, value);
       -        }
        }
        
        int
       t@@ -1034,48 +1024,20 @@ void
        mimedisplay(Message *m, char *name, char *rootdir, Window *w, int fileonly)
        {
                char *dest;
       -        char* tmp;
        
       -        if(strcmp(m->disposition, "file")==0 || strlen(m->filename)!=0){
       -                if(strlen(m->filename) == 0){
       -                        dest = estrdup(m->name);
       -                        dest[strlen(dest)-1] = '\0';
       -                }else
       +        if(strcmp(m->disposition, "file")==0 || strlen(m->filename)!=0 || !fileonly){
       +                if(strlen(m->filename) == 0)
       +                        dest = estrstrdup("a.", ext(m->type));
       +                else
                                dest = estrdup(m->filename);
                        if(m->filename[0] != '/')
                                dest = egrow(estrdup(home), "/", dest);
       -                // jpc Bprint(w->body, "\tcp %s%sbody%s %q\n", rootdir, name, ext(m->type), dest);
       -                if( strncmp(rootdir,"/mail/fs/",strlen("/mail/fs/"))==0) {
       -                        tmp = rootdir+strlen("/mail/fs/");
       -                }
       -                fsprint(w->body, "\t9p read upasfs/%s%sbody%s > %s\n", tmp, name, ext(m->type), dest);
       +                fsprint(w->body, "\t9p read mail/%sbody%s > %s\n",
       +                        name, ext(m->type), dest);
                        free(dest);
       -        }else if(!fileonly) {
       -                // jpc Bprint(w->body, "\tfile is %s%sbody%s\n", rootdir, name, ext(m->type));
       -                fsprint(w->body, "\tfile is %s%sbody%s\n", rootdir, name, ext(m->type));
                }
        }
        
       -#if 0 /* jpc */
       -void
       -printheader(char *dir, Biobuf *b, char **okheaders)
       -{
       -        char *s;
       -        char *lines[100];
       -        int i, j, n;
       -
       -        s = readfile(dir, "header", nil);
       -        if(s == nil)
       -                return;
       -        n = getfields(s, lines, nelem(lines), 0, "\n");
       -        for(i=0; i<n; i++)
       -                for(j=0; okheaders[j]; j++)
       -                        if(cistrncmp(lines[i], okheaders[j], strlen(okheaders[j])) == 0)
       -                                Bprint(b, "%s\n", lines[i]);
       -        free(s);
       -}
       -#endif
       -
        void
        printheader(char *dir, CFid *fid, char **okheaders)
        {
       t@@ -1089,11 +1051,8 @@ printheader(char *dir, CFid *fid, char **okheaders)
                n = getfields(s, lines, nelem(lines), 0, "\n");
                for(i=0; i<n; i++)
                        for(j=0; okheaders[j]; j++)
       -                        if(cistrncmp(lines[i], okheaders[j], strlen(okheaders[j])) == 0) {
       -                                // jpc Bprint(b, "%s\n", lines[i]);
       -                                fswrite(fid,lines[i],strlen(lines[i]));
       -                                fswrite(fid,"\n",strlen("\n"));
       -                        }
       +                        if(cistrncmp(lines[i], okheaders[j], strlen(okheaders[j])) == 0)
       +                                fsprint(fid, "%s\n", lines[i]);
                free(s);
        }
        
       t@@ -1108,7 +1067,6 @@ mesgload(Message *m, char *rootdir, char *file, Window *w)
        
                if(strcmp(m->type, "message/rfc822") != 0){        /* suppress headers of envelopes */
                        if(strlen(m->from) > 0){
       -                        // Bprint(w->body, "From: %s\n", m->from);
                                fsprint(w->body, "From: %s\n", m->from);
                                mesgline(m, "Date", m->date);
                                mesgline(m, "To", m->to);
       t@@ -1119,8 +1077,7 @@ mesgload(Message *m, char *rootdir, char *file, Window *w)
                                printheader(dir, w->body, okheaders);
                                printheader(dir, w->body, extraheaders);
                        }
       -                // Bprint(w->body, "\n");
       -                fswrite(w->body,"\n",strlen("\n"));
       +                fsprint(w->body, "\n");
                }
        
                if(m->level == 1 && m->recursed == 0){
       t@@ -1133,9 +1090,8 @@ mesgload(Message *m, char *rootdir, char *file, Window *w)
                                s = readbody(m->type, dir, &n);
                                winwritebody(w, s, n);
                                free(s);
       -                }else{
       +                }else
                                mimedisplay(m, m->name, rootdir, w, 0);
       -                }
                }else{
                        /* multi-part message, either multipart/* or message/rfc822 */
                        thisone = nil;
       t@@ -1153,10 +1109,8 @@ mesgload(Message *m, char *rootdir, char *file, Window *w)
                                subdir = estrstrdup(dir, mp->name);
                                name = estrstrdup(file, mp->name);
                                /* skip first element in name because it's already in window name */
       -                        if(mp != m->head) {
       -                                // jpc Bprint(w->body, "\n===> %s (%s) [%s]\n", strchr(name, '/')+1, mp->type, mp->disposition);
       +                        if(mp != m->head)
                                        fsprint(w->body, "\n===> %s (%s) [%s]\n", strchr(name, '/')+1, mp->type, mp->disposition);
       -                        }
                                if(strcmp(mp->type, "text")==0 || strncmp(mp->type, "text/", 5)==0){
                                        mimedisplay(mp, name, rootdir, w, 1);
                                        printheader(subdir, w->body, okheaders);
       t@@ -1214,7 +1168,7 @@ mesglookup(Message *mbox, char *name, char *digest)
                Message *m;
                char *t;
        
       -        if(digest){
       +        if(digest && digest[0]){
                        /* can find exactly */
                        for(m=mbox->head; m!=nil; m=m->next)
                                if(strcmp(digest, m->digest) == 0)
       t@@ -1325,11 +1279,10 @@ mesgopen(Message *mbox, char *dir, char *s, Message *mesg, int plumbed, char *di
                        free(u);
                        return 0;
                }
       -        if(plumbed){
       -                fprint(2,"mesg.c:1229 fixme\n");
       -                write(wctlfd, "top", 3);
       -                write(wctlfd, "current", 7);
       -        }
       +        /*XXX
       +        if(plumbed)
       +                drawtopwindow();
       +        */
                /* open window for message */
                m = mesglookup(mbox, direlem[0], digest);
                if(m == nil)
       t@@ -1345,9 +1298,8 @@ mesgopen(Message *mbox, char *dir, char *s, Message *mesg, int plumbed, char *di
                                /* re-use existing window */
                                if(winsetaddr(m->w, "0,$", 1)){
                                        if(m->w->data == nil)
       -                                        m->w->data = winopenfid(m->w, "data");
       +                                        m->w->data = winopenfile(m->w, "data");
                                        fswrite(m->w->data, "", 0);
       -                                // fsync(m->w->data);
                                }
                        }
                        v = estrstrdup(mbox->name, m->name);
       t@@ -1419,7 +1371,7 @@ rewritembox(Window *w, Message *mbox)
                        mesgmenudel(w, mbox, m);
                        mesgdel(mbox, m);
                }
       -        if(write(mbox->ctlfd, deletestr, strlen(deletestr)) < 0)
       +        if(fswrite(mbox->ctlfd, deletestr, strlen(deletestr)) < 0)
                        fprint(2, "Mail: warning: error removing mail message files: %r\n");
                free(deletestr);
                winselect(w, "0", 0);
   DIR diff --git a/src/cmd/acme/mail/reply.c b/src/cmd/acme/mail/reply.c
       t@@ -67,66 +67,6 @@ quote(Message *m, CFid *fid, char *dir, char *quotetext)
                return 1;
        }
        
       -#if 0 /* jpc */
       -int
       -quote(Message *m, Biobuf *b, char *dir, char *quotetext)
       -{
       -        char *body, *type;
       -        int i, n, nlines;
       -        char **lines;
       -
       -        if(quotetext){
       -                body = quotetext;
       -                n = strlen(body);
       -                type = nil;
       -        }else{
       -                /* look for first textual component to quote */
       -                type = readfile(dir, "type", &n);
       -                if(type == nil){
       -                        print("no type in %s\n", dir);
       -                        return 0;
       -                }
       -                if(strncmp(type, "multipart/", 10)==0 || strncmp(type, "message/", 8)==0){
       -                        dir = estrstrdup(dir, "1/");
       -                        if(quote(m, b, dir, nil)){
       -                                free(type);
       -                                free(dir);
       -                                return 1;
       -                        }
       -                        free(dir);
       -                }
       -                if(strncmp(type, "text", 4) != 0){
       -                        free(type);
       -                        return 0;
       -                }
       -                body = readbody(m->type, dir, &n);
       -                if(body == nil)
       -                        return 0;
       -        }
       -        nlines = 0;
       -        for(i=0; i<n; i++)
       -                if(body[i] == '\n')
       -                        nlines++;
       -        nlines++;
       -        lines = emalloc(nlines*sizeof(char*));
       -        nlines = getfields(body, lines, nlines, 0, "\n");
       -        /* delete leading and trailing blank lines */
       -        i = 0;
       -        while(i<nlines && lines[i][0]=='\0')
       -                i++;
       -        while(i<nlines && lines[nlines-1][0]=='\0')
       -                nlines--;
       -        while(i < nlines){
       -                Bprint(b, ">%s%s\n", lines[i][0]=='>'? "" : " ", lines[i]);
       -                i++;
       -        }
       -        free(lines);
       -        free(body);        /* will free quotetext if non-nil */
       -        free(type);
       -        return 1;
       -}
       -#endif 
       -
        void
        mkreply(Message *m, char *label, char *to, Plumbattr *attr, char *quotetext)
        {
       t@@ -156,36 +96,24 @@ mkreply(Message *m, char *label, char *to, Plumbattr *attr, char *quotetext)
                r->tagposted = 1;
                threadcreate(mesgctl, r, STACK);
                winopenbody(r->w, OWRITE);
       -        if(to!=nil && to[0]!='\0') {
       -                // Bprint(r->w->body, "%s\n", to);
       +        if(to!=nil && to[0]!='\0')
                        fsprint(r->w->body, "%s\n", to);
       -        }
       -        for(a=attr; a; a=a->next) {
       -                // Bprint(r->w->body, "%s: %s\n", a->name, a->value);
       +        for(a=attr; a; a=a->next)
                        fsprint(r->w->body, "%s: %s\n", a->name, a->value);
       -        }
                dir = nil;
                if(m != nil){
                        dir = estrstrdup(mbox.name, m->name);
                        if(to == nil && attr == nil){
                                /* Reply goes to replyto; Reply all goes to From and To and CC */
       -                        if(strstr(label, "all") == nil) {
       -                                // jpc Bprint(r->w->body, "To: %s\n", m->replyto);
       +                        if(strstr(label, "all") == nil)
                                        fsprint(r->w->body, "To: %s\n", m->replyto);
       -                        }
                                else{        /* Replyall */
       -                                if(strlen(m->from) > 0) {
       -                                        // Bprint(r->w->body, "To: %s\n", m->from);
       +                                if(strlen(m->from) > 0)
                                                fsprint(r->w->body, "To: %s\n", m->from);
       -                                }
       -                                if(strlen(m->to) > 0) {
       -                                        // Bprint(r->w->body, "To: %s\n", m->to);
       +                                if(strlen(m->to) > 0)
                                                fsprint(r->w->body, "To: %s\n", m->to);
       -                                }
       -                                if(strlen(m->cc) > 0) {
       -                                        // Bprint(r->w->body, "CC: %s\n", m->cc);
       +                                if(strlen(m->cc) > 0)
                                                fsprint(r->w->body, "CC: %s\n", m->cc);
       -                                }
                                }
                        }
                        if(strlen(m->subject) > 0){
       t@@ -193,21 +121,16 @@ mkreply(Message *m, char *label, char *to, Plumbattr *attr, char *quotetext)
                                if(strlen(m->subject) >= 3)
                                        if(tolower(m->subject[0])=='r' && tolower(m->subject[1])=='e' && m->subject[2]==':')
                                                t = "Subject: ";
       -                        // Bprint(r->w->body, "%s%s\n", t, m->subject);
                                fsprint(r->w->body, "%s%s\n", t, m->subject);
                        }
                        if(!quotereply){
       -                        // Bprint(r->w->body, "Include: %sraw\n", dir);
                                fsprint(r->w->body, "Include: %sraw\n", dir);
                                free(dir);
                        }
                }
       -        // Bprint(r->w->body, "\n");
                fsprint(r->w->body, "\n");
       -        if(m == nil) {
       -                // Bprint(r->w->body, "\n");
       +        if(m == nil)
                        fsprint(r->w->body, "\n");
       -        }
                else if(quotereply){
                        quote(m, r->w->body, dir, quotetext);
                        free(dir);
       t@@ -274,37 +197,24 @@ execproc(void *v)
                q[0] = e->q[0];
                q[1] = e->q[1];
                prog = e->prog;        /* known not to be malloc'ed */
       -        rfork(RFFDG);
       +        
       +        fd[0] = dup(p[0], -1);
       +        if(q[0])
       +                fd[1] = dup(q[1], -1);
       +        else
       +                fd[1] = dup(1, -1);
       +        fd[2] = dup(2, -2);
                sendul(e->sync, 1);
                buildargv(e->argv, argv, args);
                free(e->argv);
                chanfree(e->sync);
                free(e);
       -        dup(p[0], 0);
       -        close(p[0]);
       -        close(p[1]);
       -        if(q[0]){
       -                dup(q[1], 1);
       -                close(q[0]);
       -                close(q[1]);
       -        }
       -
       -        // jpc - start
       -        fd[0] = dup(0, -1);
       -        fd[1] = dup(1, -1);
       +        
                threadexec(nil, fd, prog, argv);
                close(fd[0]);
                close(fd[1]);
       -        /* jpc - procexec(nil, prog, argv); */
       -        // jpc end
       -//fprint(2, "exec: %s", e->prog);
       -//{int i;
       -//for(i=0; argv[i]; i++) print(" '%s'", argv[i]);
       -//print("\n");
       -//}
       -//argv[0] = "cat";
       -//argv[1] = nil;
       -//procexec(nil, "/bin/cat", argv);
       +        close(fd[2]);
       +
                fprint(2, "Mail: can't exec %s: %r\n", prog);
                threadexits("can't exec");
        }
   DIR diff --git a/src/cmd/acme/mail/util.c b/src/cmd/acme/mail/util.c
       t@@ -92,79 +92,16 @@ error(char *fmt, ...)
                threadexitsall(fmt);
        }
        
       -#if 0 /* jpc */
        void
       -ctlprint(int fd, char *fmt, ...)
       +ctlprint(CFid *fd, char *fmt, ...)
        {
                int n;
                va_list arg;
        
                va_start(arg, fmt);
       -        n = vfprint(fd, fmt, arg);
       +        n = fsvprint(fd, fmt, arg);
                va_end(arg);
       -        fsync(fd);
                if(n <= 0)
                        error("control file write error: %r");
        }
       -#endif
        
       -void
       -ctlprint(CFid* fd, char *fmt, ...)
       -{
       -        int n;
       -        va_list arg;
       -        char tmp[250];
       -
       -        va_start(arg, fmt);
       -        n = vsnprint(tmp, 250, fmt, arg);
       -        va_end(arg);
       -        n = fswrite(fd, tmp, strlen(tmp));
       -        if(n <= 0)
       -                error("control file write error: %r");
       -}
       -
       -int fsprint(CFid *fid, char* fmt, ...) {
       -        // example call this replaces:  Bprint(b, ">%s%s\n", lines[i][0]=='>'? "" : " ", lines[i]);
       -        char *tmp;
       -        va_list arg;
       -        int n, tlen;
       -
       -        tmp = emalloc( tlen=(strlen(fmt)+250) );  // leave room for interpolated text
       -        va_start(arg, fmt);
       -        n = vsnprint(tmp, tlen, fmt, arg);
       -        va_end(arg);
       -        if(n == tlen)
       -                error("fsprint formatting error");
       -        n = fswrite(fid, tmp, strlen(tmp));
       -        if(n <= 0)
       -                error("fsprint write error: %r");
       -        free(tmp);
       -
       -        return n;
       -
       -}
       -#if 0 /* jpc */
       -/*
       -here's a read construct (from winselection) that may be useful in fsprint - think about it.
       -*/
       -        int m, n;
       -        char *buf;
       -        char tmp[256];
       -        CFid* fid;
       -
       -        fid = winopenfid1(w, "rdsel", OREAD);
       -        if(fid == nil)
       -                error("can't open rdsel: %r");
       -        n = 0;
       -        buf = nil;
       -
       -        for(;;){
       -                m = fsread(fid, tmp, sizeof tmp);
       -                if(m <= 0)
       -                        break;
       -                buf = erealloc(buf, n+m+1);
       -                memmove(buf+n, tmp, m);
       -                n += m;
       -                buf[n] = '\0';
       -        }
       -#endif
   DIR diff --git a/src/cmd/acme/mail/win.c b/src/cmd/acme/mail/win.c
       t@@ -3,39 +3,23 @@
        #include <bio.h>
        #include <thread.h>
        #include <plumb.h>
       -#include <9pclient.h> /* jpc */
       +#include <9pclient.h>
        #include "dat.h"
        
       -extern CFsys *acmefs; /* jpc */
       -
        Window*
        newwindow(void)
        {
                char buf[12];
                Window *w;
       -        int n = 0;
        
                w = emalloc(sizeof(Window));
       -/* jpc
       -        w->ctl = open("/mnt/wsys/new/ctl", ORDWR|OCEXEC);
       -        if(w->ctl<0 || read(w->ctl, buf, 12)!=12)
       -                error("can't open window ctl file: %r");
       -*/
       -/*        w->ctl = fsopenfd(acmefs, "new/ctl", ORDWR|OCEXEC);
       -        if(w->ctl<0 || (n = read(w->ctl, buf, 12))!=12) {
       -                fprint(2,"%d bytes read from %d\n",n,w->ctl);
       -                error("can't open window ctl file: %r");
       -        }
       -  jpc end */
                w->ctl = fsopen(acmefs, "new/ctl", ORDWR|OCEXEC);
       -        if(w->ctl == nil || (n = fsread(w->ctl, buf, 12))!=12) {
       -                fprint(2,"%d bytes read from %d\n",n,w->ctl);
       +        if(w->ctl == nil || fsread(w->ctl, buf, 12)!=12)
                        error("can't open window ctl file: %r");
       -        }
        
                ctlprint(w->ctl, "noscroll\n");
                w->id = atoi(buf);
       -        w->event = winopenfid(w, "event");
       +        w->event = winopenfile(w, "event");
                w->addr = nil;        /* will be opened when needed */
                w->body = nil;
                w->data = nil;
       t@@ -68,7 +52,7 @@ wineventproc(void *v)
        }
        
        static CFid*
       -winopenfid1(Window *w, char *f, int m)
       +winopenfile1(Window *w, char *f, int m)
        {
                char buf[64];
                CFid* fd;
       t@@ -80,30 +64,7 @@ winopenfid1(Window *w, char *f, int m)
                return fd;
        }
        
       -static int
       -winopenfile1(Window *w, char *f, int m)
       -{
       -        char buf[64];
       -        int fd;
       -
       -/* jpc
       -        sprint(buf, "/mnt/wsys/%d/%s", w->id, f);
       -        fd = open(buf, m|OCEXEC);
       -*/
       -        sprint(buf, "%d/%s", w->id, f);
       -        fd = fsopenfd(acmefs, buf, m|OCEXEC);
       -        if(fd < 0)
       -                error("can't open window file %s: %r", f);
       -        return fd;
       -}
       -
        CFid*
       -winopenfid(Window *w, char *f)
       -{
       -        return winopenfid1(w, f, ORDWR);
       -}
       -
       -int
        winopenfile(Window *w, char *f)
        {
                return winopenfile1(w, f, ORDWR);
       t@@ -114,7 +75,7 @@ wintagwrite(Window *w, char *s, int n)
        {
                CFid* fid;
        
       -        fid = winopenfid(w, "tag");
       +        fid = winopenfile(w, "tag");
                if(fswrite(fid, s, n) != n)
                        error("tag write: %r");
                fsclose(fid);
       t@@ -132,13 +93,9 @@ winopenbody(Window *w, int mode)
                char buf[256];
                CFid* fid;
        
       -/* jpc
       -        sprint(buf, "/mnt/wsys/%d/body", w->id);
       -        w->body = Bopen(buf, mode|OCEXEC);
       -*/
                sprint(buf, "%d/body", w->id);
       -        fid = fsopen(acmefs,buf, mode|OCEXEC);
       -        w->body = fid; // jpcBfdopen(id, mode|OCEXEC);
       +        fid = fsopen(acmefs, buf, mode|OCEXEC);
       +        w->body = fid;
                if(w->body == nil)
                        error("can't open window body file: %r");
        }
       t@@ -147,7 +104,6 @@ void
        winclosebody(Window *w)
        {
                if(w->body != nil){
       -                // jpc Bterm(w->body);
                        fsclose(w->body);
                        w->body = nil;
                }
       t@@ -158,7 +114,6 @@ winwritebody(Window *w, char *s, int n)
        {
                if(w->body == nil)
                        winopenbody(w, OWRITE);
       -        // jpc if(Bwrite(w->body, s, n) != n)
                if(fswrite(w->body, s, n) != n)
                        error("write error to window: %r");
        }
       t@@ -246,9 +201,9 @@ winread(Window *w, uint q0, uint q1, char *data)
                char buf[256];
        
                if(w->addr == nil)
       -                w->addr = winopenfid(w, "addr");
       +                w->addr = winopenfile(w, "addr");
                if(w->data == nil)
       -                w->data = winopenfid(w, "data");
       +                w->data = winopenfile(w, "data");
                m = q0;
                while(m < q1){
                        n = sprint(buf, "#%d", m);
       t@@ -292,14 +247,10 @@ windormant(Window *w)
        int
        windel(Window *w, int sure)
        {
       -        if(sure) {
       +        if(sure)
                        fswrite(w->ctl, "delete\n", 7);
       -                // fsync(w->ctl);
       -        }
       -        else if(fswrite(w->ctl, "del\n", 4) != 4) {
       -                // fsync(w->ctl);
       +        else if(fswrite(w->ctl, "del\n", 4) != 4)
                        return 0;
       -        }
                /* event proc will die due to read error from event file */
                windormant(w);
                fsclose(w->ctl);
       t@@ -312,9 +263,6 @@ windel(Window *w, int sure)
        void
        winclean(Window *w)
        {
       -        // int fd;
       -        // if(w->body)
       -        //         Bflush(w->body);
                ctlprint(w->ctl, "clean\n");
        }
        
       t@@ -322,7 +270,7 @@ int
        winsetaddr(Window *w, char *addr, int errok)
        {
                if(w->addr == nil)
       -                w->addr = winopenfid(w, "addr");
       +                w->addr = winopenfile(w, "addr");
                if(fswrite(w->addr, addr, strlen(addr)) < 0){
                        if(!errok)
                                error("error writing addr(%s): %r", addr);
       t@@ -358,7 +306,6 @@ winreadbody(Window *w, int *np)        /* can't use readfile because acme doesn't repor
                                na += 1024;
                                s = realloc(s, na+1);
                        }
       -                // jpc m = Bread(w->body, s+n, na-n);
                        m = fsread(w->body, s+n, na-n);
                        if(m <= 0)
                                break;
       t@@ -378,7 +325,7 @@ winselection(Window *w)
                char tmp[256];
                CFid* fid;
        
       -        fid = winopenfid1(w, "rdsel", OREAD);
       +        fid = winopenfile1(w, "rdsel", OREAD);
                if(fid == nil)
                        error("can't open rdsel: %r");
                n = 0;