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