more fixes

This commit is contained in:
rsc 2006-02-12 22:23:45 +00:00
parent 34049f27b8
commit 7ce2007ce5
4 changed files with 123 additions and 120 deletions

View file

@ -4,7 +4,7 @@ char *_MAILROOT = "#9/mail";
char *_UPASLOG = "#9/sys/log"; char *_UPASLOG = "#9/sys/log";
char *_UPASLIB = "#9/mail/lib"; char *_UPASLIB = "#9/mail/lib";
char *_UPASBIN= "#9/bin/upas"; char *_UPASBIN= "#9/bin/upas";
char *_UPASTMP = "#9/mail/tmp"; char *_UPASTMP = "/var/tmp";
char *_SHELL = "#9/bin/rc"; char *_SHELL = "#9/bin/rc";
char *_POST = "#9/sys/lib/post/dispatch"; char *_POST = "#9/sys/lib/post/dispatch";

View file

@ -1,6 +1,13 @@
#include "common.h" #include "common.h"
#include <thread.h>
#include <9pclient.h>
#include <ctype.h> #include <ctype.h>
enum
{
STACK = 32768
};
#define inline _inline #define inline _inline
typedef struct Attach Attach; typedef struct Attach Attach;
@ -11,6 +18,7 @@ typedef struct Ctype Ctype;
struct Attach { struct Attach {
Attach *next; Attach *next;
char *path; char *path;
int fd;
char *type; char *type;
int inline; int inline;
Ctype *ctype; Ctype *ctype;
@ -124,6 +132,8 @@ void freeaddrs(Addr*);
void freealias(Alias*); void freealias(Alias*);
void freealiases(Alias*); void freealiases(Alias*);
int doublequote(Fmt*); int doublequote(Fmt*);
int mountmail(void);
int nprocexec;
int rflag, lbflag, xflag, holding, nflag, Fflag, eightflag, dflag; int rflag, lbflag, xflag, holding, nflag, Fflag, eightflag, dflag;
int pgpflag = 0; int pgpflag = 0;
@ -134,6 +144,8 @@ int rfc822syntaxerror;
char lastchar; char lastchar;
char *replymsg; char *replymsg;
CFsys *mailfs;
enum enum
{ {
Ok = 0, 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", fprint(2, "usage: %s [-Fr#xn] [-s subject] [-c ccrecipient] [-t type] [-aA attachment] [-p[es]] [-R replymsg] -8 | recipient-list\n",
argv0); argv0);
exits("usage"); threadexitsall("usage");
} }
void void
@ -168,11 +180,11 @@ fatal(char *fmt, ...)
va_end(arg); va_end(arg);
fprint(2, "%s: %s\n", argv0, buf); fprint(2, "%s: %s\n", argv0, buf);
holdoff(holding); holdoff(holding);
exits(buf); threadexitsall(buf);
} }
void void
main(int argc, char **argv) threadmain(int argc, char **argv)
{ {
Attach *first, **l, *a; Attach *first, **l, *a;
char *subject, *type, *boundary; char *subject, *type, *boundary;
@ -195,12 +207,11 @@ main(int argc, char **argv)
quotefmtinstall(); quotefmtinstall();
fmtinstall('Z', doublequote); fmtinstall('Z', doublequote);
threadwaitchan();
ARGBEGIN{ ARGBEGIN{
case 't': case 't':
type = ARGF(); type = EARGF(usage());
if(type == nil)
usage();
break; break;
case 'a': case 'a':
flags = 0; flags = 0;
@ -208,9 +219,9 @@ main(int argc, char **argv)
case 'A': case 'A':
flags = 1; flags = 1;
aflag: aflag:
a = mkattach(ARGF(), type, flags); a = mkattach(EARGF(usage()), type, flags);
if(a == nil) if(a == nil)
exits("bad args"); threadexitsall("bad args");
type = nil; type = nil;
*l = a; *l = a;
l = &a->next; l = &a->next;
@ -224,10 +235,10 @@ main(int argc, char **argv)
ccargc++; ccargc++;
break; break;
case 'R': case 'R':
replymsg = ARGF(); replymsg = EARGF(usage());
break; break;
case 's': case 's':
subject = ARGF(); subject = EARGF(usage());
break; break;
case 'F': case 'F':
Fflag = 1; // file message Fflag = 1; // file message
@ -251,7 +262,7 @@ main(int argc, char **argv)
eightflag = 1; eightflag = 1;
break; break;
case 'p': // pgp flag: encrypt, sign, or both case 'p': // pgp flag: encrypt, sign, or both
if(pgpopts(ARGF()) < 0) if(pgpopts(EARGF(usage())) < 0)
sysfatal("bad pgp options"); sysfatal("bad pgp options");
break; break;
default: default:
@ -308,7 +319,7 @@ main(int argc, char **argv)
case Nomessage: // no message, just exit mimicking old behavior case Nomessage: // no message, just exit mimicking old behavior
noinput = 1; noinput = 1;
if(first == nil) if(first == nil)
exits(0); threadexitsall(0);
break; break;
} }
} }
@ -316,9 +327,10 @@ main(int argc, char **argv)
fd = sendmail(to, cc, &pid, Fflag ? argv[0] : nil); fd = sendmail(to, cc, &pid, Fflag ? argv[0] : nil);
if(fd < 0) if(fd < 0)
sysfatal("execing sendmail: %r\n:"); sysfatal("execing sendmail: %r\n:");
fprint(2, "sendmail fd %d\n", fd);
if(xflag || lbflag || dflag){ if(xflag || lbflag || dflag){
close(fd); close(fd);
exits(waitforsubprocs()); threadexitsall(waitforsubprocs());
} }
if(Binit(&out, fd, OWRITE) < 0) if(Binit(&out, fd, OWRITE) < 0)
@ -364,8 +376,7 @@ main(int argc, char **argv)
if(printsubject(&out, subject) < 0) if(printsubject(&out, subject) < 0)
fatal("writing"); fatal("writing");
if(replymsg != nil) if(replymsg != nil)
if(printinreplyto(&out, replymsg) < 0) printinreplyto(&out, replymsg); /* ignore errors */
fatal("writing");
Bprint(&out, "MIME-Version: 1.0\n"); Bprint(&out, "MIME-Version: 1.0\n");
if(pgpflag){ // interpose pgp process between us and sendmail to handle body if(pgpflag){ // interpose pgp process between us and sendmail to handle body
@ -411,7 +422,7 @@ main(int argc, char **argv)
Bterm(&out); Bterm(&out);
close(fd); close(fd);
exits(waitforsubprocs()); threadexitsall(waitforsubprocs());
} }
// evaluate pgp option string // evaluate pgp option string
@ -664,17 +675,14 @@ attachment(Attach *a, Biobuf *out)
Biobuf *f; Biobuf *f;
char *p; char *p;
f = emalloc(sizeof *f);
Binit(f, a->fd, OREAD);
// if it's already mime encoded, just copy // if it's already mime encoded, just copy
if(strcmp(a->type, "mime") == 0){ 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); copy(f, out);
Bterm(f); Bterm(f);
free(f);
return;
} }
// if it's not already mime encoded ... // 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); 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 */ /* dump our local 'From ' line when passing along mail messages */
if(strcmp(a->type, "message/rfc822") == 0){ if(strcmp(a->type, "message/rfc822") == 0){
p = Brdline(f, '\n'); p = Brdline(f, '\n');
@ -713,6 +713,7 @@ attachment(Attach *a, Biobuf *out)
body64(f, out); body64(f, out);
} }
Bterm(f); Bterm(f);
free(f);
} }
char *ascwday[] = char *ascwday[] =
@ -789,20 +790,25 @@ printsubject(Biobuf *b, char *subject)
int int
printinreplyto(Biobuf *out, char *dir) printinreplyto(Biobuf *out, char *dir)
{ {
String *s = s_copy(dir); String *s;
char buf[256]; char buf[256];
int fd; int fd;
int n; int n;
if(mountmail() < 0)
return -1;
if(strncmp(dir, "Mail/", 5) != 0)
return -1;
s = s_copy(dir+5);
s_append(s, "/messageid"); s_append(s, "/messageid");
fd = open(s_to_c(s), OREAD); fd = fsopenfd(mailfs, s_to_c(s), OREAD);
s_free(s); s_free(s);
if(fd < 0) if(fd < 0)
return 0; return -1;
n = read(fd, buf, sizeof(buf)-1); n = readn(fd, buf, sizeof(buf)-1);
close(fd); close(fd);
if(n <= 0) if(n <= 0)
return 0; return -1;
buf[n] = 0; buf[n] = 0;
return Bprint(out, "In-Reply-To: %s\n", buf); return Bprint(out, "In-Reply-To: %s\n", buf);
} }
@ -814,15 +820,17 @@ mkattach(char *file, char *type, int inline)
Attach *a; Attach *a;
char ftype[64]; char ftype[64];
char *p; char *p;
int n, pfd[2]; int fd, n, pfd[2], xfd[3];
if(file == nil) if(file == nil)
return 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); fprint(2, "%s: %s can't read file\n", argv0, file);
return nil; return nil;
} }
a = emalloc(sizeof(*a)); a = emalloc(sizeof(*a));
a->fd = fd;
a->path = file; a->path = file;
a->next = nil; a->next = nil;
a->type = type; a->type = type;
@ -868,28 +876,24 @@ mkattach(char *file, char *type, int inline)
a->type = "application/octet-stream"; // safest default a->type = "application/octet-stream"; // safest default
if(pipe(pfd) < 0) if(pipe(pfd) < 0)
return a; return a;
switch(fork()){
case -1: xfd[0] = pfd[0];
break; xfd[1] = pfd[0];
case 0: xfd[2] = dup(2, -1);
close(pfd[1]); if((pid=threadspawnl(xfd, unsharp("#9/bin/file"), "file", "-m", file, nil)) < 0){
close(0); close(xfd[0]);
dup(pfd[0], 0); close(xfd[2]);
close(1); return a;
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;
} }
/* 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++) for(c = ctype; ; c++)
if(strncmp(a->type, c->type, strlen(c->type)) == 0){ 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 // print the unix from line
int int
printunixfrom(int fd) printunixfrom(int fd)
@ -1031,9 +1045,10 @@ int
sendmail(Addr *to, Addr *cc, int *pid, char *rcvr) sendmail(Addr *to, Addr *cc, int *pid, char *rcvr)
{ {
char **av, **v; char **av, **v;
int ac, fd; int ac, fd, *targ;
int pfd[2]; int pfd[2], sfd, xfd[3];
String *cmd; String *cmd;
char *x;
Addr *a; Addr *a;
fd = -1; fd = -1;
@ -1063,56 +1078,40 @@ sendmail(Addr *to, Addr *cc, int *pid, char *rcvr)
v[ac] = 0; v[ac] = 0;
if(pipe(pfd) < 0) if(pipe(pfd) < 0)
fatal("%r"); fatal("pipe: %r");
switch(*pid = fork()){
case -1: xfd[0] = pfd[0];
fatal("%r"); xfd[1] = dup(1, -1);
break; xfd[2] = dup(2, -1);
case 0:
if(holding)
close(holding);
close(pfd[1]);
dup(pfd[0], 0);
close(pfd[0]);
if(rcvr != nil){ if(replymsg != nil)
if(pipe(pfd) < 0) putenv("replymsg", replymsg);
fatal("%r"); cmd = mboxpath("pipefrom", login, s_new(), 0);
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;
}
}
if(replymsg != nil) if((*pid = threadspawn(xfd, x=s_to_c(cmd), av)) < 0
putenv("replymsg", replymsg); && (*pid = threadspawn(xfd, x="myupassend", av)) < 0
&& (*pid = threadspawn(xfd, x=unsharp("#9/bin/upas/send"), av)) < 0)
cmd = mboxpath("pipefrom", login, s_new(), 0);
exec(s_to_c(cmd), av);
exec("myupassend", av);
exec(unsharp("#9/bin/upas/send"), av);
fatal("exec: %r"); fatal("exec: %r");
break; /* threadspawn closed pfd[0] (== xfd[0]) */
default: sfd = pfd[1];
if(rcvr != nil)
close(fd); fprint(2, "exec'ed %s\n", x);
close(pfd[0]);
break; 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. // start up pgp process and return an fd to talk to it with.
@ -1168,15 +1167,10 @@ waitforsubprocs(void)
char *err; char *err;
err = nil; err = nil;
while((w = wait()) != nil){ if(pgppid >= 0 && (w=procwait(pgppid)) && w->msg[0])
if(w->pid == pid || w->pid == pgppid){ err = w->msg;
if(w->msg[0] != 0) if(pid >= 0 && (w=procwait(pid)) && w->msg[0])
err = estrdup(w->msg); err = w->msg;
}
free(w);
}
if(err)
exits(err);
return nil; return nil;
} }
@ -1854,3 +1848,13 @@ doublequote(Fmt *f)
} }
return fmtrune(f, '"'); return fmtrune(f, '"');
} }
int
mountmail(void)
{
if(mailfs != nil)
return 0;
if((mailfs = nsmount("mail", nil)) == nil)
return -1;
return 0;
}

View file

@ -335,11 +335,10 @@ m_read(Biobuf *fp, int rmail, int interactive)
mp->size += n; mp->size += n;
if(n == VMLIMIT){ if(n == VMLIMIT){
if(m_read_to_file(fp, mp) < 0){ if(m_read_to_file(fp, mp) < 0){
perror("m_read"); perror("m_read_to_file");
exit(1); exit(1);
} }
} }
} }
/* /*

View file

@ -806,7 +806,7 @@ readmtypes(void)
Mtype *m; Mtype *m;
Mtype **l; Mtype **l;
b = Bopen(unsharp("#9/sys/lib/mimetype"), OREAD); b = Bopen(unsharp("#9/lib/mimetype"), OREAD);
if(b == nil) if(b == nil)
return; return;