19a747e4fSDavid du Colombier #include "common.h"
29a747e4fSDavid du Colombier #include "dat.h"
39a747e4fSDavid du Colombier
49a747e4fSDavid du Colombier Biobuf in;
59a747e4fSDavid du Colombier
69a747e4fSDavid du Colombier Addr *al;
79a747e4fSDavid du Colombier int na;
89a747e4fSDavid du Colombier String *from;
99a747e4fSDavid du Colombier String *sender;
109a747e4fSDavid du Colombier
1139734e7eSDavid du Colombier void printmsg(int fd, String *msg, char *replyto, char *listname);
129a747e4fSDavid du Colombier void appendtoarchive(char* listname, String *firstline, String *msg);
1339734e7eSDavid du Colombier void printsubject(int fd, Field *f, char *listname);
149a747e4fSDavid du Colombier
159a747e4fSDavid du Colombier void
usage(void)169a747e4fSDavid du Colombier usage(void)
179a747e4fSDavid du Colombier {
189a747e4fSDavid du Colombier fprint(2, "usage: %s address-list-file listname\n", argv0);
199a747e4fSDavid du Colombier exits("usage");
209a747e4fSDavid du Colombier }
219a747e4fSDavid du Colombier
229a747e4fSDavid du Colombier void
main(int argc,char ** argv)239a747e4fSDavid du Colombier main(int argc, char **argv)
249a747e4fSDavid du Colombier {
259a747e4fSDavid du Colombier String *msg;
269a747e4fSDavid du Colombier String *firstline;
279a747e4fSDavid du Colombier char *listname, *alfile;
289a747e4fSDavid du Colombier Waitmsg *w;
299a747e4fSDavid du Colombier int fd;
303ff48bf5SDavid du Colombier char *replytoname = nil;
319a747e4fSDavid du Colombier
329a747e4fSDavid du Colombier ARGBEGIN{
333ff48bf5SDavid du Colombier case 'r':
343ff48bf5SDavid du Colombier replytoname = ARGF();
353ff48bf5SDavid du Colombier break;
369a747e4fSDavid du Colombier }ARGEND;
379a747e4fSDavid du Colombier
389a747e4fSDavid du Colombier rfork(RFENVG|RFREND);
399a747e4fSDavid du Colombier
409a747e4fSDavid du Colombier if(argc < 2)
419a747e4fSDavid du Colombier usage();
429a747e4fSDavid du Colombier alfile = argv[0];
439a747e4fSDavid du Colombier listname = argv[1];
443ff48bf5SDavid du Colombier if(replytoname == nil)
453ff48bf5SDavid du Colombier replytoname = listname;
469a747e4fSDavid du Colombier
479a747e4fSDavid du Colombier readaddrs(alfile);
489a747e4fSDavid du Colombier
499a747e4fSDavid du Colombier if(Binit(&in, 0, OREAD) < 0)
509a747e4fSDavid du Colombier sysfatal("opening input: %r");
519a747e4fSDavid du Colombier
529a747e4fSDavid du Colombier msg = s_new();
539a747e4fSDavid du Colombier firstline = s_new();
549a747e4fSDavid du Colombier
559a747e4fSDavid du Colombier /* discard the 'From ' line */
569a747e4fSDavid du Colombier if(s_read_line(&in, firstline) == nil)
579a747e4fSDavid du Colombier sysfatal("reading input: %r");
589a747e4fSDavid du Colombier
59*86a363ceSDavid du Colombier /* read up to the first 128k of the message. more is ridiculous.
6039734e7eSDavid du Colombier Not if word documents are distributed. Upped it to 2MB (pb) */
6139734e7eSDavid du Colombier if(s_read(&in, msg, 2*1024*1024) <= 0)
629a747e4fSDavid du Colombier sysfatal("reading input: %r");
639a747e4fSDavid du Colombier
649a747e4fSDavid du Colombier /* parse the header */
659a747e4fSDavid du Colombier yyinit(s_to_c(msg), s_len(msg));
669a747e4fSDavid du Colombier yyparse();
679a747e4fSDavid du Colombier
689a747e4fSDavid du Colombier /* get the sender */
699a747e4fSDavid du Colombier getaddrs();
709a747e4fSDavid du Colombier if(from == nil)
719a747e4fSDavid du Colombier from = sender;
729a747e4fSDavid du Colombier if(from == nil)
739a747e4fSDavid du Colombier sysfatal("message must contain From: or Sender:");
749a747e4fSDavid du Colombier if(strcmp(listname, s_to_c(from)) == 0)
759a747e4fSDavid du Colombier sysfatal("can't remail messages from myself");
769a747e4fSDavid du Colombier addaddr(s_to_c(from));
779a747e4fSDavid du Colombier
789a747e4fSDavid du Colombier /* start the mailer up and return a pipe to it */
799a747e4fSDavid du Colombier fd = startmailer(listname);
809a747e4fSDavid du Colombier
819a747e4fSDavid du Colombier /* send message adding our own reply-to and precedence */
8239734e7eSDavid du Colombier printmsg(fd, msg, replytoname, listname);
839a747e4fSDavid du Colombier close(fd);
849a747e4fSDavid du Colombier
859a747e4fSDavid du Colombier /* wait for mailer to end */
869a747e4fSDavid du Colombier while(w = wait()){
879a747e4fSDavid du Colombier if(w->msg != nil && w->msg[0])
889a747e4fSDavid du Colombier sysfatal("%s", w->msg);
899a747e4fSDavid du Colombier free(w);
909a747e4fSDavid du Colombier }
919a747e4fSDavid du Colombier
92*86a363ceSDavid du Colombier /* if the mailbox exists, cat the mail to the end of it */
939a747e4fSDavid du Colombier appendtoarchive(listname, firstline, msg);
949a747e4fSDavid du Colombier exits(0);
959a747e4fSDavid du Colombier }
969a747e4fSDavid du Colombier
979a747e4fSDavid du Colombier /* send message filtering Reply-to out of messages */
989a747e4fSDavid du Colombier void
printmsg(int fd,String * msg,char * replyto,char * listname)9939734e7eSDavid du Colombier printmsg(int fd, String *msg, char *replyto, char *listname)
1009a747e4fSDavid du Colombier {
10139734e7eSDavid du Colombier Field *f, *subject;
1029a747e4fSDavid du Colombier Node *p;
1039a747e4fSDavid du Colombier char *cp, *ocp;
1049a747e4fSDavid du Colombier
10539734e7eSDavid du Colombier subject = nil;
1069a747e4fSDavid du Colombier cp = s_to_c(msg);
1079a747e4fSDavid du Colombier for(f = firstfield; f; f = f->next){
1089a747e4fSDavid du Colombier ocp = cp;
1099a747e4fSDavid du Colombier for(p = f->node; p; p = p->next)
1109a747e4fSDavid du Colombier cp = p->end+1;
1119a747e4fSDavid du Colombier if(f->node->c == REPLY_TO)
1129a747e4fSDavid du Colombier continue;
1139a747e4fSDavid du Colombier if(f->node->c == PRECEDENCE)
1149a747e4fSDavid du Colombier continue;
11539734e7eSDavid du Colombier if(f->node->c == SUBJECT){
11639734e7eSDavid du Colombier subject = f;
11739734e7eSDavid du Colombier continue;
11839734e7eSDavid du Colombier }
1199a747e4fSDavid du Colombier write(fd, ocp, cp-ocp);
1209a747e4fSDavid du Colombier }
12139734e7eSDavid du Colombier printsubject(fd, subject, listname);
12239734e7eSDavid du Colombier fprint(fd, "Reply-To: %s\nPrecedence: bulk\n", replyto);
1239a747e4fSDavid du Colombier write(fd, cp, s_len(msg) - (cp - s_to_c(msg)));
1249a747e4fSDavid du Colombier }
1259a747e4fSDavid du Colombier
126*86a363ceSDavid du Colombier /* if the mailbox exists, cat the mail to the end of it */
1279a747e4fSDavid du Colombier void
appendtoarchive(char * listname,String * firstline,String * msg)1289a747e4fSDavid du Colombier appendtoarchive(char* listname, String *firstline, String *msg)
1299a747e4fSDavid du Colombier {
1309a747e4fSDavid du Colombier String *mbox;
1319a747e4fSDavid du Colombier int fd;
1329a747e4fSDavid du Colombier
1339a747e4fSDavid du Colombier mbox = s_new();
1349a747e4fSDavid du Colombier mboxpath("mbox", listname, mbox, 0);
1359a747e4fSDavid du Colombier if(access(s_to_c(mbox), 0) < 0)
1369a747e4fSDavid du Colombier return;
1379a747e4fSDavid du Colombier fd = open(s_to_c(mbox), OWRITE);
1389a747e4fSDavid du Colombier if(fd < 0)
1399a747e4fSDavid du Colombier return;
1409a747e4fSDavid du Colombier s_append(msg, "\n");
1419a747e4fSDavid du Colombier write(fd, s_to_c(firstline), s_len(firstline));
1429a747e4fSDavid du Colombier write(fd, s_to_c(msg), s_len(msg));
1439a747e4fSDavid du Colombier }
14439734e7eSDavid du Colombier
14539734e7eSDavid du Colombier /* add the listname to the subject */
14639734e7eSDavid du Colombier void
printsubject(int fd,Field * f,char * listname)14739734e7eSDavid du Colombier printsubject(int fd, Field *f, char *listname)
14839734e7eSDavid du Colombier {
14939734e7eSDavid du Colombier char *s, *e;
15039734e7eSDavid du Colombier Node *p;
15139734e7eSDavid du Colombier char *ln;
15239734e7eSDavid du Colombier
15339734e7eSDavid du Colombier if(f == nil || f->node == nil){
15439734e7eSDavid du Colombier fprint(fd, "Subject: [%s]\n", listname);
15539734e7eSDavid du Colombier return;
15639734e7eSDavid du Colombier }
15739734e7eSDavid du Colombier s = e = f->node->end + 1;
15839734e7eSDavid du Colombier for(p = f->node; p; p = p->next)
15939734e7eSDavid du Colombier e = p->end;
16039734e7eSDavid du Colombier *e = 0;
16139734e7eSDavid du Colombier ln = smprint("[%s]", listname);
16239734e7eSDavid du Colombier if(ln != nil && strstr(s, ln) == nil)
16339734e7eSDavid du Colombier fprint(fd, "Subject: %s%s\n", ln, s);
16439734e7eSDavid du Colombier else
16539734e7eSDavid du Colombier fprint(fd, "Subject:%s\n", s);
16639734e7eSDavid du Colombier free(ln);
16739734e7eSDavid du Colombier }
168