tmore fixes - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 7ce2007ce514e427bfd0b37bc79013d3425f4033
 (DIR) parent 34049f27b8f8974dd2ff368c959914afffaaa162
 (HTM) Author: rsc <devnull@localhost>
       Date:   Sun, 12 Feb 2006 22:23:45 +0000
       
       more fixes
       
       Diffstat:
         M src/cmd/upas/common/config.c        |       2 +-
         M src/cmd/upas/marshal/marshal.c      |     236 ++++++++++++++++---------------
         M src/cmd/upas/send/message.c         |       3 +--
         M src/cmd/upas/vf/vf.c                |       2 +-
       
       4 files changed, 123 insertions(+), 120 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/upas/common/config.c b/src/cmd/upas/common/config.c
       t@@ -4,7 +4,7 @@ char *_MAILROOT =        "#9/mail";
        char *_UPASLOG =                "#9/sys/log";
        char *_UPASLIB =         "#9/mail/lib";
        char *_UPASBIN=                "#9/bin/upas";
       -char *_UPASTMP =         "#9/mail/tmp";
       +char *_UPASTMP =         "/var/tmp";
        char *_SHELL =                 "#9/bin/rc";
        char *_POST =                "#9/sys/lib/post/dispatch";
        
 (DIR) diff --git a/src/cmd/upas/marshal/marshal.c b/src/cmd/upas/marshal/marshal.c
       t@@ -1,6 +1,13 @@
        #include "common.h"
       +#include <thread.h>
       +#include <9pclient.h>
        #include <ctype.h>
        
       +enum
       +{
       +        STACK = 32768
       +};
       +
        #define inline _inline
        
        typedef struct Attach Attach;
       t@@ -11,6 +18,7 @@ typedef struct Ctype Ctype;
        struct Attach {
                Attach        *next;
                char        *path;
       +        int        fd;
                char        *type;
                int        inline;
                Ctype        *ctype;
       t@@ -124,6 +132,8 @@ void        freeaddrs(Addr*);
        void        freealias(Alias*);
        void        freealiases(Alias*);
        int        doublequote(Fmt*);
       +int        mountmail(void);
       +int        nprocexec;
        
        int rflag, lbflag, xflag, holding, nflag, Fflag, eightflag, dflag;
        int pgpflag = 0;
       t@@ -134,6 +144,8 @@ int rfc822syntaxerror;
        char lastchar;
        char *replymsg;
        
       +CFsys *mailfs;
       +
        enum
        {
                Ok = 0,
       t@@ -149,7 +161,7 @@ usage(void)
        {
                fprint(2, "usage: %s [-Fr#xn] [-s subject] [-c ccrecipient] [-t type] [-aA attachment] [-p[es]] [-R replymsg] -8 | recipient-list\n",
                        argv0);
       -        exits("usage");
       +        threadexitsall("usage");
        }
        
        void
       t@@ -168,11 +180,11 @@ fatal(char *fmt, ...)
                va_end(arg);
                fprint(2, "%s: %s\n", argv0, buf);
                holdoff(holding);
       -        exits(buf);
       +        threadexitsall(buf);
        }
        
        void
       -main(int argc, char **argv)
       +threadmain(int argc, char **argv)
        {
                Attach *first, **l, *a;
                char *subject, *type, *boundary;
       t@@ -195,12 +207,11 @@ main(int argc, char **argv)
        
                quotefmtinstall();
                fmtinstall('Z', doublequote);
       +        threadwaitchan();
        
                ARGBEGIN{
                case 't':
       -                type = ARGF();
       -                if(type == nil)
       -                        usage();
       +                type = EARGF(usage());
                        break;
                case 'a':
                        flags = 0;
       t@@ -208,9 +219,9 @@ main(int argc, char **argv)
                case 'A':
                        flags = 1;
                aflag:
       -                a = mkattach(ARGF(), type, flags);
       +                a = mkattach(EARGF(usage()), type, flags);
                        if(a == nil)
       -                        exits("bad args");
       +                        threadexitsall("bad args");
                        type = nil;
                        *l = a;
                        l = &a->next;
       t@@ -224,10 +235,10 @@ main(int argc, char **argv)
                        ccargc++;
                        break;
                case 'R':
       -                replymsg = ARGF();
       +                replymsg = EARGF(usage());
                        break;
                case 's':
       -                subject = ARGF();
       +                subject = EARGF(usage());
                        break;
                case 'F':
                        Fflag = 1;                // file message
       t@@ -251,7 +262,7 @@ main(int argc, char **argv)
                        eightflag = 1;
                        break;
                case 'p':                        // pgp flag: encrypt, sign, or both
       -                if(pgpopts(ARGF()) < 0)
       +                if(pgpopts(EARGF(usage())) < 0)
                                sysfatal("bad pgp options");
                        break;
                default:
       t@@ -308,7 +319,7 @@ main(int argc, char **argv)
                        case Nomessage:                // no message, just exit mimicking old behavior
                                noinput = 1;
                                if(first == nil)
       -                                exits(0);
       +                                threadexitsall(0);
                                break;
                        }
                }
       t@@ -316,9 +327,10 @@ main(int argc, char **argv)
                fd = sendmail(to, cc, &pid, Fflag ? argv[0] : nil);
                if(fd < 0)
                        sysfatal("execing sendmail: %r\n:");
       +fprint(2, "sendmail fd %d\n", fd);
                if(xflag || lbflag || dflag){
                        close(fd);
       -                exits(waitforsubprocs());
       +                threadexitsall(waitforsubprocs());
                }
                
                if(Binit(&out, fd, OWRITE) < 0)
       t@@ -364,8 +376,7 @@ main(int argc, char **argv)
                        if(printsubject(&out, subject) < 0)
                                fatal("writing");
                if(replymsg != nil)
       -                if(printinreplyto(&out, replymsg) < 0)
       -                        fatal("writing");
       +                printinreplyto(&out, replymsg);        /* ignore errors */
                Bprint(&out, "MIME-Version: 1.0\n");
        
                if(pgpflag){        // interpose pgp process between us and sendmail to handle body
       t@@ -411,7 +422,7 @@ main(int argc, char **argv)
        
                Bterm(&out);
                close(fd);
       -        exits(waitforsubprocs());
       +        threadexitsall(waitforsubprocs());
        }
        
        // evaluate pgp option string
       t@@ -664,17 +675,14 @@ attachment(Attach *a, Biobuf *out)
                Biobuf *f;
                char *p;
        
       +        f = emalloc(sizeof *f);
       +        Binit(f, a->fd, OREAD);
                // if it's already mime encoded, just copy
                if(strcmp(a->type, "mime") == 0){
       -                f = Bopen(a->path, OREAD);
       -                if(f == nil){
       -                        /* hack: give marshal time to stdin, before we kill it (for dead.letter) */
       -                        sleep(500);
       -                        postnote(PNPROC, pid, "interrupt");
       -                        sysfatal("opening %s: %r", a->path);
       -                }
                        copy(f, out);
                        Bterm(f);
       +                free(f);
       +                return;
                }
                
                // if it's not already mime encoded ...
       t@@ -692,14 +700,6 @@ attachment(Attach *a, Biobuf *out)
                        Bprint(out, "Content-Disposition: attachment; filename=%Z\n", p);
                }
        
       -        f = Bopen(a->path, OREAD);
       -        if(f == nil){
       -                /* hack: give marshal time to stdin, before we kill it (for dead.letter) */
       -                sleep(500);
       -                postnote(PNPROC, pid, "interrupt");
       -                sysfatal("opening %s: %r", a->path);
       -        }
       -
                /* dump our local 'From ' line when passing along mail messages */
                if(strcmp(a->type, "message/rfc822") == 0){
                        p = Brdline(f, '\n');
       t@@ -713,6 +713,7 @@ attachment(Attach *a, Biobuf *out)
                        body64(f, out);
                }
                Bterm(f);
       +        free(f);
        }
        
        char *ascwday[] =
       t@@ -789,20 +790,25 @@ printsubject(Biobuf *b, char *subject)
        int
        printinreplyto(Biobuf *out, char *dir)
        {
       -        String *s = s_copy(dir);
       +        String *s;
                char buf[256];
                int fd;
                int n;
        
       +        if(mountmail() < 0)
       +                return -1;
       +        if(strncmp(dir, "Mail/", 5) != 0)
       +                return -1;
       +        s = s_copy(dir+5);
                s_append(s, "/messageid");
       -        fd = open(s_to_c(s), OREAD);
       +        fd = fsopenfd(mailfs, s_to_c(s), OREAD);
                s_free(s);
                if(fd < 0)
       -                return 0;
       -        n = read(fd, buf, sizeof(buf)-1);
       +                return -1;
       +        n = readn(fd, buf, sizeof(buf)-1);
                close(fd);
                if(n <= 0)
       -                return 0;
       +                return -1;
                buf[n] = 0;
                return Bprint(out, "In-Reply-To: %s\n", buf);
        }
       t@@ -814,15 +820,17 @@ mkattach(char *file, char *type, int inline)
                Attach *a;
                char ftype[64];
                char *p;
       -        int n, pfd[2];
       +        int fd, n, pfd[2], xfd[3];
        
                if(file == nil)
                        return nil;
       -        if(access(file, 4) == -1){
       +        if((fd = open(file, OREAD)) < 0)
       +        if(strncmp(file, "Mail/", 5) != 0 || mountmail() < 0 || (fd = fsopenfd(mailfs, file+5, OREAD)) < 0){
                        fprint(2, "%s: %s can't read file\n", argv0, file);
                        return nil;
                }
                a = emalloc(sizeof(*a));
       +        a->fd = fd;
                a->path = file;
                a->next = nil;
                a->type = type;
       t@@ -868,28 +876,24 @@ mkattach(char *file, char *type, int inline)
                a->type = "application/octet-stream";                // safest default
                if(pipe(pfd) < 0)
                        return a;
       -        switch(fork()){
       -        case -1:
       -                break;
       -        case 0:
       -                close(pfd[1]);
       -                close(0);
       -                dup(pfd[0], 0);
       -                close(1);
       -                dup(pfd[0], 1);
       -                execl(unsharp("#9/bin/file"), "file", "-m", file, nil);
       -                exits(0);
       -        default:
       -                close(pfd[0]);
       -                n = read(pfd[1], ftype, sizeof(ftype));
       -                if(n > 0){
       -                        ftype[n-1] = 0;
       -                        a->type = estrdup(ftype);
       -                }
       -                close(pfd[1]);
       -                waitpid();
       -                break;
       +        
       +        xfd[0] = pfd[0];
       +        xfd[1] = pfd[0];
       +        xfd[2] = dup(2, -1);
       +        if((pid=threadspawnl(xfd, unsharp("#9/bin/file"), "file", "-m", file, nil)) < 0){
       +                close(xfd[0]);
       +                close(xfd[2]);
       +                return a;
       +        }
       +        /* threadspawnl closed pfd[0] */
       +
       +        n = readn(pfd[1], ftype, sizeof(ftype));
       +        if(n > 0){
       +                ftype[n-1] = 0;
       +                a->type = estrdup(ftype);
                }
       +        close(pfd[1]);
       +        procwait(pid);
        
                for(c = ctype; ; c++)
                        if(strncmp(a->type, c->type, strlen(c->type)) == 0){
       t@@ -932,6 +936,16 @@ tee(int in, int out1, int out2)
                }
        }
        
       +static void
       +teeproc(void *v)
       +{
       +        int *a;
       +        
       +        a = v;
       +        tee(a[0], a[1], a[2]);
       +        write(a[2], "\n", 1);
       +}
       +
        // print the unix from line
        int
        printunixfrom(int fd)
       t@@ -1031,9 +1045,10 @@ int
        sendmail(Addr *to, Addr *cc, int *pid, char *rcvr)
        {
                char **av, **v;
       -        int ac, fd;
       -        int pfd[2];
       +        int ac, fd, *targ;
       +        int pfd[2], sfd, xfd[3];
                String *cmd;
       +        char *x;
                Addr *a;
        
                fd = -1;
       t@@ -1063,56 +1078,40 @@ sendmail(Addr *to, Addr *cc, int *pid, char *rcvr)
                v[ac] = 0;
        
                if(pipe(pfd) < 0)
       -                fatal("%r");
       -        switch(*pid = fork()){
       -        case -1:
       -                fatal("%r");
       -                break;
       -        case 0:
       -                if(holding)
       -                        close(holding);
       -                close(pfd[1]);
       -                dup(pfd[0], 0);
       -                close(pfd[0]);
       -
       -                if(rcvr != nil){
       -                        if(pipe(pfd) < 0)
       -                                fatal("%r");
       -                        switch(fork()){
       -                        case -1:
       -                                fatal("%r");
       -                                break;
       -                        case 0:
       -                                close(pfd[0]);
       -                                seek(fd, 0, 2);
       -                                printunixfrom(fd);
       -                                tee(0, pfd[1], fd);
       -                                write(fd, "\n", 1);
       -                                exits(0);
       -                        default:
       -                                close(fd);
       -                                close(pfd[1]);
       -                                dup(pfd[0], 0);
       -                                break;
       -                        }
       -                }
       +                fatal("pipe: %r");
       +        
       +        xfd[0] = pfd[0];
       +        xfd[1] = dup(1, -1);
       +        xfd[2] = dup(2, -1);
        
       -                if(replymsg != nil)
       -                        putenv("replymsg", replymsg);
       +        if(replymsg != nil)
       +                putenv("replymsg", replymsg);
       +        cmd = mboxpath("pipefrom", login, s_new(), 0);
        
       -                cmd = mboxpath("pipefrom", login, s_new(), 0);
       -                exec(s_to_c(cmd), av);
       -                exec("myupassend", av);
       -                exec(unsharp("#9/bin/upas/send"), av);
       +        if((*pid = threadspawn(xfd, x=s_to_c(cmd), av)) < 0
       +        && (*pid = threadspawn(xfd, x="myupassend", av)) < 0
       +        && (*pid = threadspawn(xfd, x=unsharp("#9/bin/upas/send"), av)) < 0)
                        fatal("exec: %r");
       -                break;
       -        default:
       -                if(rcvr != nil)
       -                        close(fd);
       -                close(pfd[0]);
       -                break;
       +        /* threadspawn closed pfd[0] (== xfd[0]) */
       +        sfd = pfd[1];
       +
       +fprint(2, "exec'ed %s\n", x);
       +
       +        if(rcvr != nil){
       +fprint(2, "rcvr\n");
       +                if(pipe(pfd) < 0)
       +                        fatal("pipe: %r");
       +                seek(fd, 0, 2);
       +                printunixfrom(fd);
       +                targ = emalloc(3*sizeof targ[0]);
       +                targ[0] = sfd;
       +                targ[1] = pfd[0];
       +                targ[2] = fd;
       +                proccreate(teeproc, targ, STACK);
       +                sfd = pfd[1];
                }
       -        return pfd[1];
       +        
       +        return sfd;
        }
        
        // start up pgp process and return an fd to talk to it with.
       t@@ -1168,15 +1167,10 @@ waitforsubprocs(void)
                char *err;
        
                err = nil;
       -        while((w = wait()) != nil){
       -                if(w->pid == pid || w->pid == pgppid){
       -                        if(w->msg[0] != 0)
       -                                err = estrdup(w->msg);
       -                }
       -                free(w);
       -        }
       -        if(err)
       -                exits(err);
       +        if(pgppid >= 0 && (w=procwait(pgppid)) && w->msg[0])
       +                err = w->msg;
       +        if(pid >= 0 && (w=procwait(pid)) && w->msg[0])
       +                err = w->msg;
                return nil;
        }
        
       t@@ -1854,3 +1848,13 @@ doublequote(Fmt *f)
                }
                return fmtrune(f, '"');
        }
       +
       +int
       +mountmail(void)
       +{
       +        if(mailfs != nil)
       +                return 0;
       +        if((mailfs = nsmount("mail", nil)) == nil)
       +                return -1;
       +        return 0;
       +}
 (DIR) diff --git a/src/cmd/upas/send/message.c b/src/cmd/upas/send/message.c
       t@@ -335,11 +335,10 @@ m_read(Biobuf *fp, int rmail, int interactive)
                        mp->size += n;
                        if(n == VMLIMIT){
                                if(m_read_to_file(fp, mp) < 0){
       -                                perror("m_read");
       +                                perror("m_read_to_file");
                                        exit(1);
                                }
                        }
       -
                }
        
                /*
 (DIR) diff --git a/src/cmd/upas/vf/vf.c b/src/cmd/upas/vf/vf.c
       t@@ -806,7 +806,7 @@ readmtypes(void)
                Mtype *m;
                Mtype **l;
        
       -        b = Bopen(unsharp("#9/sys/lib/mimetype"), OREAD);
       +        b = Bopen(unsharp("#9/lib/mimetype"), OREAD);
                if(b == nil)
                        return;