Blame


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