/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "common.h"#include "dat.h" Biobuf in; Addr *al;int na;String *from;String *sender; void printmsg(int fd, String *msg, char *replyto, char *listname);void appendtoarchive(char* listname, String *firstline, String *msg);void printsubject(int fd, Field *f, char *listname); voidusage(void){ fprint(2, "usage: %s address-list-file listname\n", argv0); exits("usage");} voidmain(int argc, char **argv){ String *msg; String *firstline; char *listname, *alfile; Waitmsg *w; int fd; char *replytoname = nil; ARGBEGIN{ case 'r': replytoname = ARGF(); break; }ARGEND; rfork(RFENVG|RFREND); if(argc < 2) usage(); alfile = argv[0]; listname = argv[1]; if(replytoname == nil) replytoname = listname; readaddrs(alfile); if(Binit(&in, 0, OREAD) < 0) sysfatal("opening input: %r"); msg = s_new(); firstline = s_new(); /* discard the 'From ' line */ if(s_read_line(&in, firstline) == nil) sysfatal("reading input: %r"); /* read up to the first 128k of the message. more is ridiculous. Not if word documents are distributed. Upped it to 2MB (pb) */ if(s_read(&in, msg, 2*1024*1024) <= 0) sysfatal("reading input: %r"); /* parse the header */ yyinit(s_to_c(msg), s_len(msg)); yyparse(); /* get the sender */ getaddrs(); if(from == nil) from = sender; if(from == nil) sysfatal("message must contain From: or Sender:"); if(strcmp(listname, s_to_c(from)) == 0) sysfatal("can't remail messages from myself"); addaddr(s_to_c(from)); /* start the mailer up and return a pipe to it */ fd = startmailer(listname); /* send message adding our own reply-to and precedence */ printmsg(fd, msg, replytoname, listname); close(fd); /* wait for mailer to end */ while(w = wait()){ if(w->msg != nil && w->msg[0]) sysfatal("%s", w->msg); free(w); } /* if the mailbox exists, cat the mail to the end of it */ appendtoarchive(listname, firstline, msg); exits(0);} /* send message filtering Reply-to out of messages */voidprintmsg(int fd, String *msg, char *replyto, char *listname){ Field *f, *subject; Node *p; char *cp, *ocp; subject = nil; cp = s_to_c(msg); for(f = firstfield; f; f = f->next){ ocp = cp; for(p = f->node; p; p = p->next) cp = p->end+1; if(f->node->c == REPLY_TO) continue; if(f->node->c == PRECEDENCE) continue; if(f->node->c == SUBJECT){ subject = f; continue; } write(fd, ocp, cp-ocp); } printsubject(fd, subject, listname); fprint(fd, "Reply-To: %s\nPrecedence: bulk\n", replyto); write(fd, cp, s_len(msg) - (cp - s_to_c(msg)));} /* if the mailbox exists, cat the mail to the end of it */voidappendtoarchive(char* listname, String *firstline, String *msg){ String *mbox; int fd; mbox = s_new(); mboxpath("mbox", listname, mbox, 0); if(access(s_to_c(mbox), 0) < 0) return; fd = open(s_to_c(mbox), OWRITE); if(fd < 0) return; s_append(msg, "\n"); write(fd, s_to_c(firstline), s_len(firstline)); write(fd, s_to_c(msg), s_len(msg));} /* add the listname to the subject */voidprintsubject(int fd, Field *f, char *listname){ char *s, *e; Node *p; char *ln; if(f == nil || f->node == nil){ fprint(fd, "Subject: [%s]\n", listname); return; } s = e = f->node->end + 1; for(p = f->node; p; p = p->next) e = p->end; *e = 0; ln = smprint("[%s]", listname); if(ln != nil && strstr(s, ln) == nil) fprint(fd, "Subject: %s%s\n", ln, s); else fprint(fd, "Subject:%s\n", s); free(ln);}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#include "common.h"
#include "dat.h"
Biobuf in;
Addr *al;
int na;
String *from;
String *sender;
void printmsg(int fd, String *msg, char *replyto, char *listname);
void appendtoarchive(char* listname, String *firstline, String *msg);
void printsubject(int fd, Field *f, char *listname);
void
usage(void)
{
fprint(2, "usage: %s address-list-file listname\n", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
String *msg;
String *firstline;
char *listname, *alfile;
Waitmsg *w;
int fd;
char *replytoname = nil;
ARGBEGIN{
case 'r':
replytoname = ARGF();
break;
}ARGEND;
rfork(RFENVG|RFREND);
if(argc < 2)
usage();
alfile = argv[0];
listname = argv[1];
if(replytoname == nil)
replytoname = listname;
readaddrs(alfile);
if(Binit(&in, 0, OREAD) < 0)
sysfatal("opening input: %r");
msg = s_new();
firstline = s_new();
/* discard the 'From ' line */
if(s_read_line(&in, firstline) == nil)
sysfatal("reading input: %r");
/* read up to the first 128k of the message. more is ridiculous.
Not if word documents are distributed. Upped it to 2MB (pb) */
if(s_read(&in, msg, 2*1024*1024) <= 0)
sysfatal("reading input: %r");
/* parse the header */
yyinit(s_to_c(msg), s_len(msg));
yyparse();
/* get the sender */
getaddrs();
if(from == nil)
from = sender;
if(from == nil)
sysfatal("message must contain From: or Sender:");
if(strcmp(listname, s_to_c(from)) == 0)
sysfatal("can't remail messages from myself");
addaddr(s_to_c(from));
/* start the mailer up and return a pipe to it */
fd = startmailer(listname);
/* send message adding our own reply-to and precedence */
printmsg(fd, msg, replytoname, listname);
close(fd);
/* wait for mailer to end */
while(w = wait()){
if(w->msg != nil && w->msg[0])
sysfatal("%s", w->msg);
free(w);
}
/* if the mailbox exists, cat the mail to the end of it */
appendtoarchive(listname, firstline, msg);
exits(0);
}
/* send message filtering Reply-to out of messages */
void
printmsg(int fd, String *msg, char *replyto, char *listname)
{
Field *f, *subject;
Node *p;
char *cp, *ocp;
subject = nil;
cp = s_to_c(msg);
for(f = firstfield; f; f = f->next){
ocp = cp;
for(p = f->node; p; p = p->next)
cp = p->end+1;
if(f->node->c == REPLY_TO)
continue;
if(f->node->c == PRECEDENCE)
continue;
if(f->node->c == SUBJECT){
subject = f;
continue;
}
write(fd, ocp, cp-ocp);
}
printsubject(fd, subject, listname);
fprint(fd, "Reply-To: %s\nPrecedence: bulk\n", replyto);
write(fd, cp, s_len(msg) - (cp - s_to_c(msg)));
}
/* if the mailbox exists, cat the mail to the end of it */
void
appendtoarchive(char* listname, String *firstline, String *msg)
{
String *mbox;
int fd;
mbox = s_new();
mboxpath("mbox", listname, mbox, 0);
if(access(s_to_c(mbox), 0) < 0)
return;
fd = open(s_to_c(mbox), OWRITE);
if(fd < 0)
return;
s_append(msg, "\n");
write(fd, s_to_c(firstline), s_len(firstline));
write(fd, s_to_c(msg), s_len(msg));
}
/* add the listname to the subject */
void
printsubject(int fd, Field *f, char *listname)
{
char *s, *e;
Node *p;
char *ln;
if(f == nil || f->node == nil){
fprint(fd, "Subject: [%s]\n", listname);
return;
}
s = e = f->node->end + 1;
for(p = f->node; p; p = p->next)
e = p->end;
*e = 0;
ln = smprint("[%s]", listname);
if(ln != nil && strstr(s, ln) == nil)
fprint(fd, "Subject: %s%s\n", ln, s);
else
fprint(fd, "Subject:%s\n", s);
free(ln);
}