1 #include "common.h" 2 #include "dat.h" 3 4 Biobuf in; 5 6 Addr *al; 7 int na; 8 String *from; 9 String *sender; 10 11 void printmsg(int fd, String *msg, char *replyto); 12 void appendtoarchive(char* listname, String *firstline, String *msg); 13 14 void 15 usage(void) 16 { 17 fprint(2, "usage: %s address-list-file listname\n", argv0); 18 exits("usage"); 19 } 20 21 void 22 main(int argc, char **argv) 23 { 24 String *msg; 25 String *firstline; 26 char *listname, *alfile; 27 Waitmsg *w; 28 int fd; 29 char *replytoname = nil; 30 31 ARGBEGIN{ 32 case 'r': 33 replytoname = ARGF(); 34 break; 35 }ARGEND; 36 37 rfork(RFENVG|RFREND); 38 39 if(argc < 2) 40 usage(); 41 alfile = argv[0]; 42 listname = argv[1]; 43 if(replytoname == nil) 44 replytoname = listname; 45 46 readaddrs(alfile); 47 48 if(Binit(&in, 0, OREAD) < 0) 49 sysfatal("opening input: %r"); 50 51 msg = s_new(); 52 firstline = s_new(); 53 54 /* discard the 'From ' line */ 55 if(s_read_line(&in, firstline) == nil) 56 sysfatal("reading input: %r"); 57 58 /* read up to the first 128k of the message. more is redculous */ 59 if(s_read(&in, msg, 128*1024) <= 0) 60 sysfatal("reading input: %r"); 61 62 /* parse the header */ 63 yyinit(s_to_c(msg), s_len(msg)); 64 yyparse(); 65 66 /* get the sender */ 67 getaddrs(); 68 if(from == nil) 69 from = sender; 70 if(from == nil) 71 sysfatal("message must contain From: or Sender:"); 72 if(strcmp(listname, s_to_c(from)) == 0) 73 sysfatal("can't remail messages from myself"); 74 addaddr(s_to_c(from)); 75 76 /* start the mailer up and return a pipe to it */ 77 fd = startmailer(listname); 78 79 /* send message adding our own reply-to and precedence */ 80 printmsg(fd, msg, replytoname); 81 close(fd); 82 83 /* wait for mailer to end */ 84 while(w = wait()){ 85 if(w->msg != nil && w->msg[0]) 86 sysfatal("%s", w->msg); 87 free(w); 88 } 89 90 /* if the mailbox exits, cat the mail to the end of it */ 91 appendtoarchive(listname, firstline, msg); 92 exits(0); 93 } 94 95 /* send message filtering Reply-to out of messages */ 96 void 97 printmsg(int fd, String *msg, char *replyto) 98 { 99 Field *f; 100 Node *p; 101 char *cp, *ocp; 102 103 cp = s_to_c(msg); 104 fprint(fd, "Reply-To: %s\nPrecedence: bulk\n", replyto); 105 for(f = firstfield; f; f = f->next){ 106 ocp = cp; 107 for(p = f->node; p; p = p->next) 108 cp = p->end+1; 109 if(f->node->c == REPLY_TO) 110 continue; 111 if(f->node->c == PRECEDENCE) 112 continue; 113 write(fd, ocp, cp-ocp); 114 } 115 write(fd, cp, s_len(msg) - (cp - s_to_c(msg))); 116 } 117 118 /* if the mailbox exits, cat the mail to the end of it */ 119 void 120 appendtoarchive(char* listname, String *firstline, String *msg) 121 { 122 String *mbox; 123 int fd; 124 125 mbox = s_new(); 126 mboxpath("mbox", listname, mbox, 0); 127 if(access(s_to_c(mbox), 0) < 0) 128 return; 129 fd = open(s_to_c(mbox), OWRITE); 130 if(fd < 0) 131 return; 132 s_append(msg, "\n"); 133 write(fd, s_to_c(firstline), s_len(firstline)); 134 write(fd, s_to_c(msg), s_len(msg)); 135 } 136