URI:
       tml.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tml.c (3454B)
       ---
            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, char *listname);
           12 void appendtoarchive(char* listname, String *firstline, String *msg);
           13 void printsubject(int fd, Field *f, char *listname);
           14 
           15 void
           16 usage(void)
           17 {
           18         fprint(2, "usage: %s address-list-file listname\n", argv0);
           19         exits("usage");
           20 }
           21 
           22 void
           23 main(int argc, char **argv)
           24 {
           25         String *msg;
           26         String *firstline;
           27         char *listname, *alfile;
           28         Waitmsg *w;
           29         int fd;
           30         char *replytoname = nil;
           31 
           32         ARGBEGIN{
           33         case 'r':
           34                 replytoname = ARGF();
           35                 break;
           36         }ARGEND;
           37 
           38         rfork(RFENVG);
           39 
           40         if(argc < 2)
           41                 usage();
           42         alfile = argv[0];
           43         listname = argv[1];
           44         if(replytoname == nil)
           45                 replytoname = listname;
           46 
           47         readaddrs(alfile);
           48 
           49         if(Binit(&in, 0, OREAD) < 0)
           50                 sysfatal("opening input: %r");
           51 
           52         msg = s_new();
           53         firstline = s_new();
           54 
           55         /* discard the 'From ' line */
           56         if(s_read_line(&in, firstline) == nil)
           57                 sysfatal("reading input: %r");
           58 
           59         /* read up to the first 128k of the message.  more is redculous.
           60              Not if word documents are distributed.  Upped it to 2MB (pb) */
           61         if(s_read(&in, msg, 2*1024*1024) <= 0)
           62                 sysfatal("reading input: %r");
           63 
           64         /* parse the header */
           65         yyinit(s_to_c(msg), s_len(msg));
           66         yyparse();
           67 
           68         /* get the sender */
           69         getaddrs();
           70         if(from == nil)
           71                 from = sender;
           72         if(from == nil)
           73                 sysfatal("message must contain From: or Sender:");
           74         if(strcmp(listname, s_to_c(from)) == 0)
           75                 sysfatal("can't remail messages from myself");
           76         addaddr(s_to_c(from));
           77 
           78         /* start the mailer up and return a pipe to it */
           79         fd = startmailer(listname);
           80 
           81         /* send message adding our own reply-to and precedence */
           82         printmsg(fd, msg, replytoname, listname);
           83         close(fd);
           84 
           85         /* wait for mailer to end */
           86         while(w = wait()){
           87                 if(w->msg != nil && w->msg[0])
           88                         sysfatal("%s", w->msg);
           89                 free(w);
           90         }
           91 
           92         /* if the mailbox exits, cat the mail to the end of it */
           93         appendtoarchive(listname, firstline, msg);
           94         exits(0);
           95 }
           96 
           97 /* send message filtering Reply-to out of messages */
           98 void
           99 printmsg(int fd, String *msg, char *replyto, char *listname)
          100 {
          101         Field *f, *subject;
          102         Node *p;
          103         char *cp, *ocp;
          104 
          105         subject = nil;
          106         cp = s_to_c(msg);
          107         for(f = firstfield; f; f = f->next){
          108                 ocp = cp;
          109                 for(p = f->node; p; p = p->next)
          110                         cp = p->end+1;
          111                 if(f->node->c == REPLY_TO)
          112                         continue;
          113                 if(f->node->c == PRECEDENCE)
          114                         continue;
          115                 if(f->node->c == SUBJECT){
          116                         subject = f;
          117                         continue;
          118                 }
          119                 write(fd, ocp, cp-ocp);
          120         }
          121         printsubject(fd, subject, listname);
          122         fprint(fd, "Reply-To: %s\nPrecedence: bulk\n", replyto);
          123         write(fd, cp, s_len(msg) - (cp - s_to_c(msg)));
          124 }
          125 
          126 /* if the mailbox exits, cat the mail to the end of it */
          127 void
          128 appendtoarchive(char* listname, String *firstline, String *msg)
          129 {
          130         String *mbox;
          131         int fd;
          132 
          133         mbox = s_new();
          134         mboxpath("mbox", listname, mbox, 0);
          135         if(access(s_to_c(mbox), 0) < 0)
          136                 return;
          137         fd = open(s_to_c(mbox), OWRITE);
          138         if(fd < 0)
          139                 return;
          140         s_append(msg, "\n");
          141         write(fd, s_to_c(firstline), s_len(firstline));
          142         write(fd, s_to_c(msg), s_len(msg));
          143 }
          144 
          145 /* add the listname to the subject */
          146 void
          147 printsubject(int fd, Field *f, char *listname)
          148 {
          149         char *s, *e;
          150         Node *p;
          151         char *ln;
          152 
          153         if(f == nil || f->node == nil){
          154                 fprint(fd, "Subject: [%s]\n", listname);
          155                 return;
          156         }
          157         s = e = f->node->end + 1;
          158         for(p = f->node; p; p = p->next)
          159                 e = p->end;
          160         *e = 0;
          161         ln = smprint("[%s]", listname);
          162         if(ln != nil && strstr(s, ln) == nil)
          163                 fprint(fd, "Subject: %s%s\n", ln, s);
          164         else
          165                 fprint(fd, "Subject:%s\n", s);
          166         free(ln);
          167 }