Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/cmd/ip/imap4d/search.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <auth.h>
5
#include "imap4d.h"
6
 
7
static int	dateCmp(char *date, Search *s);
8
static int	addrSearch(MAddr *a, char *s);
9
static int	fileSearch(Msg *m, char *file, char *pat);
10
static int	headerSearch(Msg *m, char *hdr, char *pat);
11
 
12
/*
13
 * free to exit, parseErr, since called before starting any client reply
14
 *
15
 * the header and envelope searches should convert mime character set escapes.
16
 */
17
int
18
searchMsg(Msg *m, Search *s)
19
{
20
	MsgSet *ms;
21
	int ok;
22
 
23
	if(!msgStruct(m, 1) || m->expunged)
24
		return 0;
25
	for(ok = 1; ok && s != nil; s = s->next){
26
		switch(s->key){
27
		default:
28
			ok = 0;
29
			break;
30
		case SKNot:
31
			ok = !searchMsg(m, s->left);
32
			break;
33
		case SKOr:
34
			ok = searchMsg(m, s->left) || searchMsg(m, s->right);
35
			break;
36
		case SKAll:
37
			ok = 1;
38
			break;
39
		case SKAnswered:
40
			ok = (m->flags & MAnswered) == MAnswered;
41
			break;
42
		case SKDeleted:
43
			ok = (m->flags & MDeleted) == MDeleted;
44
			break;
45
		case SKDraft:
46
			ok = (m->flags & MDraft) == MDraft;
47
			break;
48
		case SKFlagged:
49
			ok = (m->flags & MFlagged) == MFlagged;
50
			break;
51
		case SKKeyword:
52
			ok = (m->flags & s->num) == s->num;
53
			break;
54
		case SKNew:
55
			ok = (m->flags & (MRecent|MSeen)) == MRecent;
56
			break;
57
		case SKOld:
58
			ok = (m->flags & MRecent) != MRecent;
59
			break;
60
		case SKRecent:
61
			ok = (m->flags & MRecent) == MRecent;
62
			break;
63
		case SKSeen:
64
			ok = (m->flags & MSeen) == MSeen;
65
			break;
66
		case SKUnanswered:
67
			ok = (m->flags & MAnswered) != MAnswered;
68
			break;
69
		case SKUndeleted:
70
			ok = (m->flags & MDeleted) != MDeleted;
71
			break;
72
		case SKUndraft:
73
			ok = (m->flags & MDraft) != MDraft;
74
			break;
75
		case SKUnflagged:
76
			ok = (m->flags & MFlagged) != MFlagged;
77
			break;
78
		case SKUnkeyword:
79
			ok = (m->flags & s->num) != s->num;
80
			break;
81
		case SKUnseen:
82
			ok = (m->flags & MSeen) != MSeen;
83
			break;
84
 
85
		case SKLarger:
86
			ok = msgSize(m) > s->num;
87
			break;
88
		case SKSmaller:
89
			ok = msgSize(m) < s->num;
90
			break;
91
 
92
		case SKBcc:
93
			ok = addrSearch(m->bcc, s->s);
94
			break;
95
		case SKCc:
96
			ok = addrSearch(m->cc, s->s);
97
			break;
98
		case SKFrom:
99
			ok = addrSearch(m->from, s->s);
100
			break;
101
		case SKTo:
102
			ok = addrSearch(m->to, s->s);
103
			break;
104
		case SKSubject:
105
			ok = 0;
106
			if(m->info[ISubject])
107
				ok = cistrstr(m->info[ISubject], s->s) != nil;
108
			break;
109
 
110
		case SKBefore:
111
			ok = dateCmp(m->unixDate, s) < 0;
112
			break;
113
		case SKOn:
114
			ok = dateCmp(m->unixDate, s) == 0;
115
			break;
116
		case SKSince:
117
			ok = dateCmp(m->unixDate, s) > 0;
118
			break;
119
		case SKSentBefore:
120
			ok = dateCmp(m->info[IDate], s) < 0;
121
			break;
122
		case SKSentOn:
123
			ok = dateCmp(m->info[IDate], s) == 0;
124
			break;
125
		case SKSentSince:
126
			ok = dateCmp(m->info[IDate], s) > 0;
127
			break;
128
 
129
		case SKUid:
130
		case SKSet:
131
			for(ms = s->set; ms != nil; ms = ms->next)
132
				if(s->key == SKUid && m->uid >= ms->from && m->uid <= ms->to
133
				|| s->key == SKSet && m->seq >= ms->from && m->seq <= ms->to)
134
					break;
135
			ok = ms != nil;
136
			break;
137
 
138
		case SKHeader:
139
			ok = headerSearch(m, s->hdr, s->s);
140
			break;
141
 
142
		case SKBody:
143
		case SKText:
144
			if(s->key == SKText && cistrstr(m->head.buf, s->s)){
145
				ok = 1;
146
				break;
147
			}
148
			ok = fileSearch(m, "body", s->s);
149
			break;
150
		}
151
	}
152
	return ok;
153
}
154
 
155
static int
156
fileSearch(Msg *m, char *file, char *pat)
157
{
158
	char buf[BufSize + 1];
159
	int n, nbuf, npat, fd, ok;
160
 
161
	npat = strlen(pat);
162
	if(npat >= BufSize / 2)
163
		return 0;
164
 
165
	fd = msgFile(m, file);
166
	if(fd < 0)
167
		return 0;
168
	ok = 0;
169
	nbuf = 0;
170
	for(;;){
171
		n = read(fd, &buf[nbuf], BufSize - nbuf);
172
		if(n <= 0)
173
			break;
174
		nbuf += n;
175
		buf[nbuf] = '\0';
176
		if(cistrstr(buf, pat) != nil){
177
			ok = 1;
178
			break;
179
		}
180
		if(nbuf > npat){
181
			memmove(buf, &buf[nbuf - npat], npat);
182
			nbuf = npat;
183
		}
184
	}
185
	close(fd);
186
	return ok;
187
}
188
 
189
static int
190
headerSearch(Msg *m, char *hdr, char *pat)
191
{
192
	SList hdrs;
193
	char *s, *t;
194
	int ok, n;
195
 
196
	n = m->head.size + 3;
197
	s = emalloc(n);
198
	hdrs.next = nil;
199
	hdrs.s = hdr;
200
	ok = 0;
201
	if(selectFields(s, n, m->head.buf, &hdrs, 1) > 0){
202
		t = strchr(s, ':');
203
		if(t != nil && cistrstr(t+1, pat) != nil)
204
			ok = 1;
205
	}
206
	free(s);
207
	return ok;
208
}
209
 
210
static int
211
addrSearch(MAddr *a, char *s)
212
{
213
	char *ok, *addr;
214
 
215
	for(; a != nil; a = a->next){
216
		addr = maddrStr(a);
217
		ok = cistrstr(addr, s);
218
		free(addr);
219
		if(ok != nil)
220
			return 1;
221
	}
222
	return 0;
223
}
224
 
225
static int
226
dateCmp(char *date, Search *s)
227
{
228
	Tm tm;
229
 
230
	date2tm(&tm, date);
231
	if(tm.year < s->year)
232
		return -1;
233
	if(tm.year > s->year)
234
		return 1;
235
	if(tm.mon < s->mon)
236
		return -1;
237
	if(tm.mon > s->mon)
238
		return 1;
239
	if(tm.mday < s->mday)
240
		return -1;
241
	if(tm.mday > s->mday)
242
		return 1;
243
	return 0;
244
}