123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #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);
- }
|