xref: /plan9/sys/src/cmd/upas/send/filter.c (revision 90faae218fd4c4565fd13bea6fd8b4e654b38f29)
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