tmore fixes - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
commit 7ce2007ce514e427bfd0b37bc79013d3425f4033
parent 34049f27b8f8974dd2ff368c959914afffaaa162
Author: rsc 
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(-)
---
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";
 
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 
+#include <9pclient.h>
 #include 
 
+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;
+}
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);
                         }
                 }
-
         }
 
         /*
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;