Blob


1 #include "common.h"
2 #include "send.h"
4 Biobuf bin;
5 int rmail, tflg;
6 char *subjectarg;
8 char *findbody(char*);
10 void
11 main(int argc, char *argv[])
12 {
13 message *mp;
14 dest *dp;
15 Reprog *p;
16 Resub match[10];
17 char file[MAXPATHLEN];
18 Biobuf *fp;
19 char *rcvr, *cp;
20 Mlock *l;
21 String *tmp;
22 int i;
23 int header, body;
25 header = body = 0;
26 ARGBEGIN {
27 case 'h':
28 header = 1;
29 break;
30 case 'b':
31 header = 1;
32 body = 1;
33 break;
34 } ARGEND
36 Binit(&bin, 0, OREAD);
37 if(argc < 2){
38 fprint(2, "usage: filter rcvr mailfile [regexp mailfile ...]\n");
39 exits("usage");
40 }
41 mp = m_read(&bin, 1, 0);
43 /* get rid of local system name */
44 cp = strchr(s_to_c(mp->sender), '!');
45 if(cp){
46 cp++;
47 mp->sender = s_copy(cp);
48 }
50 dp = d_new(s_copy(argv[0]));
51 strecpy(file, file+sizeof file, argv[1]);
52 cp = findbody(s_to_c(mp->body));
53 for(i = 2; i < argc; i += 2){
54 p = regcomp(argv[i]);
55 if(p == 0)
56 continue;
57 if(regexec(p, s_to_c(mp->sender), match, 10)){
58 regsub(argv[i+1], file, sizeof(file), match, 10);
59 break;
60 }
61 if(header == 0 && body == 0)
62 continue;
63 if(regexec(p, s_to_c(mp->body), match, 10)){
64 if(body == 0 && match[0].s.sp >= cp)
65 continue;
66 regsub(argv[i+1], file, sizeof(file), match, 10);
67 break;
68 }
69 }
71 /*
72 * always lock the normal mail file to avoid too many lock files
73 * lying about. This isn't right but it's what the majority prefers.
74 */
75 l = syslock(argv[1]);
76 if(l == 0){
77 fprint(2, "can't lock mail file %s\n", argv[1]);
78 exit(1);
79 }
81 /*
82 * open the destination mail file
83 */
84 fp = sysopen(file, "ca", MBOXMODE);
85 if (fp == 0){
86 tmp = s_append(0, file);
87 s_append(tmp, ".tmp");
88 fp = sysopen(s_to_c(tmp), "cal", MBOXMODE);
89 if(fp == 0){
90 sysunlock(l);
91 fprint(2, "can't open mail file %s\n", file);
92 exit(1);
93 }
94 syslog(0, "mail", "error: used %s", s_to_c(tmp));
95 s_free(tmp);
96 }
97 Bseek(fp, 0, 2);
98 if(m_print(mp, fp, (char *)0, 1) < 0
99 || Bprint(fp, "\n") < 0
100 || Bflush(fp) < 0){
101 sysclose(fp);
102 sysunlock(l);
103 fprint(2, "can't write mail file %s\n", file);
104 exit(1);
106 sysclose(fp);
108 sysunlock(l);
109 rcvr = argv[0];
110 if(cp = strrchr(rcvr, '!'))
111 rcvr = cp+1;
112 logdelivery(dp, rcvr, mp);
113 exit(0);
116 char*
117 findbody(char *p)
119 if(*p == '\n')
120 return p;
122 while(*p){
123 if(*p == '\n' && *(p+1) == '\n')
124 return p+1;
125 p++;
127 return p;