From 7ce2007ce514e427bfd0b37bc79013d3425f4033 Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 12 Feb 2006 22:23:45 +0000 Subject: more fixes --- src/cmd/upas/common/config.c | 2 +- src/cmd/upas/marshal/marshal.c | 236 +++++++++++++++++++++-------------------- src/cmd/upas/send/message.c | 3 +- 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 index cde9e986..8d1e7a02 100644 --- a/src/cmd/upas/common/config.c +++ b/src/cmd/upas/common/config.c @@ -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 index 2df5a987..d4685000 100644 --- a/src/cmd/upas/marshal/marshal.c +++ b/src/cmd/upas/marshal/marshal.c @@ -1,6 +1,13 @@ #include "common.h" +#include +#include <9pclient.h> #include +enum +{ + STACK = 32768 +}; + #define inline _inline typedef struct Attach Attach; @@ -11,6 +18,7 @@ typedef struct Ctype Ctype; struct Attach { Attach *next; char *path; + int fd; char *type; int inline; Ctype *ctype; @@ -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; @@ -134,6 +144,8 @@ int rfc822syntaxerror; char lastchar; char *replymsg; +CFsys *mailfs; + enum { Ok = 0, @@ -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 @@ -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; @@ -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; @@ -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; @@ -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 @@ -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: @@ -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; } } @@ -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) @@ -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 @@ -411,7 +422,7 @@ main(int argc, char **argv) Bterm(&out); close(fd); - exits(waitforsubprocs()); + threadexitsall(waitforsubprocs()); } // evaluate pgp option string @@ -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 ... @@ -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'); @@ -713,6 +713,7 @@ attachment(Attach *a, Biobuf *out) body64(f, out); } Bterm(f); + free(f); } char *ascwday[] = @@ -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); } @@ -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; @@ -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){ @@ -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) @@ -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; @@ -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. @@ -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; } @@ -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 index afd93e3b..34393a96 100644 --- a/src/cmd/upas/send/message.c +++ b/src/cmd/upas/send/message.c @@ -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 index 9d908150..bc8a7960 100644 --- a/src/cmd/upas/vf/vf.c +++ b/src/cmd/upas/vf/vf.c @@ -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; -- cgit v1.2.3