Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-mail/message-parser.c @ 265:d0ba9a65891c HEAD
message_parse_header() went to infinite loop with partial header
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 17 Sep 2002 04:49:45 +0300 |
parents | 62058959536a |
children | 3dcc2275b4ca |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "lib.h" | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
4 #include "iobuffer.h" |
0 | 5 #include "rfc822-tokenize.h" |
6 #include "message-content-parser.h" | |
7 #include "message-parser.h" | |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
8 #include "message-size.h" |
0 | 9 |
10 typedef struct _MessageBoundary { | |
11 struct _MessageBoundary *next; | |
12 | |
13 MessagePart *part; | |
14 const char *boundary; | |
184 | 15 size_t len; |
0 | 16 } MessageBoundary; |
17 | |
18 typedef struct { | |
19 Pool pool; | |
20 MessagePart *part; | |
21 | |
22 char *last_boundary; | |
23 char *last_content_type; | |
24 MessageBoundary *boundaries; | |
25 | |
26 MessageHeaderFunc func; | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
27 void *context; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
28 } MessageParseContext; |
0 | 29 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
30 static MessagePart *message_parse_part(IOBuffer *inbuf, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
31 MessageParseContext *parse_ctx); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
32 static MessagePart *message_parse_body(IOBuffer *inbuf, |
0 | 33 MessageBoundary *boundaries, |
34 MessageSize *body_size); | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
35 static MessagePart *message_skip_boundary(IOBuffer *inbuf, |
0 | 36 MessageBoundary *boundaries, |
37 MessageSize *boundary_size); | |
38 | |
39 static void message_size_add_part(MessageSize *dest, MessagePart *part) | |
40 { | |
41 dest->physical_size += | |
42 part->header_size.physical_size + | |
43 part->body_size.physical_size; | |
44 dest->virtual_size += | |
45 part->header_size.virtual_size + | |
46 part->body_size.virtual_size; | |
47 dest->lines += part->header_size.lines + part->body_size.lines; | |
48 } | |
49 | |
50 static MessagePart *message_part_append(Pool pool, MessagePart *parent) | |
51 { | |
52 MessagePart *part, **list; | |
53 | |
54 part = p_new(pool, MessagePart, 1); | |
55 part->parent = parent; | |
56 | |
212
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
57 /* set child position */ |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
58 part->physical_pos = |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
59 parent->physical_pos + |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
60 parent->body_size.physical_size + |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
61 parent->header_size.physical_size; |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
62 |
0 | 63 list = &part->parent->children; |
64 while (*list != NULL) | |
65 list = &(*list)->next; | |
66 | |
67 *list = part; | |
68 return part; | |
69 } | |
70 | |
71 static void parse_content_type(const Rfc822Token *tokens, int count, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
72 void *context) |
0 | 73 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
74 MessageParseContext *parse_ctx = context; |
0 | 75 const char *str; |
76 | |
77 if (tokens[0].token != 'A') | |
78 return; | |
79 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
80 if (parse_ctx->last_content_type != NULL) |
0 | 81 return; |
82 | |
112
d6105a8a6ca9
Fixed rfc822_tokens_get_value(). It doesn't have "put spaces around all
Timo Sirainen <tss@iki.fi>
parents:
106
diff
changeset
|
83 str = rfc822_tokens_get_value(tokens, count); |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
84 parse_ctx->last_content_type = p_strdup(parse_ctx->pool, str); |
0 | 85 |
86 if (strcasecmp(str, "message/rfc822") == 0) | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
87 parse_ctx->part->flags |= MESSAGE_PART_FLAG_MESSAGE_RFC822; |
0 | 88 else if (strncasecmp(str, "text/", 5) == 0) |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
89 parse_ctx->part->flags |= MESSAGE_PART_FLAG_TEXT; |
0 | 90 else if (strncasecmp(str, "multipart/", 10) == 0) { |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
91 parse_ctx->part->flags |= MESSAGE_PART_FLAG_MULTIPART; |
0 | 92 |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
93 if (strcasecmp(str+10, "digest") == 0) { |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
94 parse_ctx->part->flags |= |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
95 MESSAGE_PART_FLAG_MULTIPART_DIGEST; |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
96 } |
0 | 97 } |
98 } | |
99 | |
100 static void parse_content_type_param(const Rfc822Token *name, | |
101 const Rfc822Token *value, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
102 int value_count, void *context) |
0 | 103 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
104 MessageParseContext *parse_ctx = context; |
0 | 105 const char *str; |
106 | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
107 if ((parse_ctx->part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0 || |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
108 name->len != 8 || strncasecmp(name->ptr, "boundary", 8) != 0) |
0 | 109 return; |
110 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
111 if (parse_ctx->last_boundary == NULL) { |
112
d6105a8a6ca9
Fixed rfc822_tokens_get_value(). It doesn't have "put spaces around all
Timo Sirainen <tss@iki.fi>
parents:
106
diff
changeset
|
112 str = rfc822_tokens_get_value(value, value_count); |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
113 parse_ctx->last_boundary = p_strdup(parse_ctx->pool, str); |
0 | 114 } |
115 } | |
116 | |
117 static void parse_header_field(MessagePart *part, | |
184 | 118 const char *name, size_t name_len, |
119 const char *value, size_t value_len, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
120 void *context) |
0 | 121 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
122 MessageParseContext *parse_ctx = context; |
0 | 123 |
124 /* call the user-defined header parser */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
125 if (parse_ctx->func != NULL) { |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
126 parse_ctx->func(part, name, name_len, value, value_len, |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
127 parse_ctx->context); |
0 | 128 } |
129 | |
130 if (name_len == 12 && strncasecmp(name, "Content-Type", 12) == 0) { | |
131 /* we need to know the boundary */ | |
132 (void)message_content_parse_header(t_strndup(value, value_len), | |
133 parse_content_type, | |
134 parse_content_type_param, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
135 parse_ctx); |
0 | 136 } |
137 } | |
138 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
139 static MessagePart *message_parse_multipart(IOBuffer *inbuf, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
140 MessageParseContext *parse_ctx) |
0 | 141 { |
142 MessagePart *parent_part, *next_part, *part; | |
143 MessageBoundary *b; | |
144 | |
145 /* multipart message. add new boundary */ | |
146 b = t_new(MessageBoundary, 1); | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
147 b->part = parse_ctx->part; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
148 b->boundary = parse_ctx->last_boundary; |
0 | 149 b->len = strlen(b->boundary); |
150 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
151 b->next = parse_ctx->boundaries; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
152 parse_ctx->boundaries = b; |
0 | 153 |
154 /* reset fields */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
155 parse_ctx->last_boundary = NULL; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
156 parse_ctx->last_content_type = NULL; |
0 | 157 |
158 /* skip the data before the first boundary */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
159 parent_part = parse_ctx->part; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
160 next_part = message_skip_boundary(inbuf, parse_ctx->boundaries, |
0 | 161 &parent_part->body_size); |
162 | |
163 /* now, parse the parts */ | |
164 while (next_part == parent_part) { | |
165 /* new child */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
166 part = message_part_append(parse_ctx->pool, parent_part); |
0 | 167 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
168 parse_ctx->part = part; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
169 next_part = message_parse_part(inbuf, parse_ctx); |
0 | 170 |
171 /* update our size */ | |
172 message_size_add_part(&parent_part->body_size, part); | |
173 | |
174 if (next_part != parent_part) | |
175 break; | |
176 | |
177 /* skip the boundary */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
178 next_part = message_skip_boundary(inbuf, parse_ctx->boundaries, |
0 | 179 &parent_part->body_size); |
180 } | |
181 | |
182 /* remove boundary */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
183 i_assert(parse_ctx->boundaries == b); |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
184 parse_ctx->boundaries = b->next; |
0 | 185 return next_part; |
186 } | |
187 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
188 static MessagePart *message_parse_part(IOBuffer *inbuf, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
189 MessageParseContext *parse_ctx) |
0 | 190 { |
191 MessagePart *next_part, *part; | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
192 uoff_t hdr_size; |
0 | 193 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
194 message_parse_header(parse_ctx->part, inbuf, |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
195 &parse_ctx->part->header_size, |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
196 parse_header_field, parse_ctx); |
0 | 197 |
198 /* update message position/size */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
199 hdr_size = parse_ctx->part->header_size.physical_size; |
0 | 200 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
201 if (parse_ctx->last_boundary != NULL) |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
202 return message_parse_multipart(inbuf, parse_ctx); |
0 | 203 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
204 if (parse_ctx->last_content_type == NULL) { |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
205 if (parse_ctx->part->parent != NULL && |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
206 (parse_ctx->part->parent->flags & |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
207 MESSAGE_PART_FLAG_MULTIPART_DIGEST)) { |
0 | 208 /* when there's no content-type specified and we're |
209 below multipart/digest, the assume message/rfc822 | |
210 content-type */ | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
211 parse_ctx->part->flags |= |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
212 MESSAGE_PART_FLAG_MESSAGE_RFC822; |
0 | 213 } else { |
214 /* otherwise we default to text/plain */ | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
215 parse_ctx->part->flags |= MESSAGE_PART_FLAG_TEXT; |
0 | 216 } |
217 } | |
218 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
219 parse_ctx->last_boundary = NULL; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
220 parse_ctx->last_content_type = NULL; |
0 | 221 |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
222 if (parse_ctx->part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) { |
0 | 223 /* message/rfc822 part - the message body begins with |
224 headers again, this works pretty much the same as | |
225 a single multipart/mixed item */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
226 part = message_part_append(parse_ctx->pool, parse_ctx->part); |
0 | 227 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
228 parse_ctx->part = part; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
229 next_part = message_parse_part(inbuf, parse_ctx); |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
230 parse_ctx->part = part->parent; |
0 | 231 |
232 /* our body size is the size of header+body in message/rfc822 */ | |
233 message_size_add_part(&part->parent->body_size, part); | |
234 } else { | |
235 /* normal message, read until the next boundary */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
236 part = parse_ctx->part; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
237 next_part = message_parse_body(inbuf, parse_ctx->boundaries, |
0 | 238 &part->body_size); |
239 } | |
240 | |
241 return next_part; | |
242 } | |
243 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
244 MessagePart *message_parse(Pool pool, IOBuffer *inbuf, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
245 MessageHeaderFunc func, void *context) |
0 | 246 { |
247 MessagePart *part; | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
248 MessageParseContext parse_ctx; |
0 | 249 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
250 memset(&parse_ctx, 0, sizeof(parse_ctx)); |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
251 parse_ctx.pool = pool; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
252 parse_ctx.func = func; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
253 parse_ctx.context = context; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
254 parse_ctx.part = part = p_new(pool, MessagePart, 1); |
0 | 255 |
256 t_push(); | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
257 message_parse_part(inbuf, &parse_ctx); |
0 | 258 t_pop(); |
259 return part; | |
260 } | |
261 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
262 /* skip over to next line increasing message size */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
263 static void message_skip_line(IOBuffer *inbuf, MessageSize *msg_size) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
264 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
265 unsigned char *msg; |
184 | 266 size_t i, size, startpos; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
267 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
268 startpos = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
269 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
270 while (io_buffer_read_data_blocking(inbuf, &msg, &size, startpos) > 0) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
271 for (i = startpos; i < size; i++) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
272 if (msg[i] == '\n') { |
153
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
273 if (msg_size != NULL) { |
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
274 if (i == 0 || msg[i-1] != '\r') |
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
275 msg_size->virtual_size++; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
276 msg_size->lines++; |
153
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
277 } |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
278 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
279 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
280 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
281 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
282 if (i < size) { |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
283 startpos = i+1; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
284 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
285 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
286 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
287 /* leave the last character, it may be \r */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
288 io_buffer_skip(inbuf, i - 1); |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
289 startpos = 1; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
290 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
291 if (msg_size != NULL) { |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
292 msg_size->physical_size += i - 1; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
293 msg_size->virtual_size += i - 1; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
294 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
295 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
296 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
297 io_buffer_skip(inbuf, startpos); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
298 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
299 if (msg_size != NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
300 msg_size->physical_size += startpos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
301 msg_size->virtual_size += startpos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
302 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
303 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
304 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
305 void message_parse_header(MessagePart *part, IOBuffer *inbuf, |
0 | 306 MessageSize *hdr_size, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
307 MessageHeaderFunc func, void *context) |
0 | 308 { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
309 unsigned char *msg; |
184 | 310 size_t i, size, startpos, missing_cr_count; |
311 size_t line_start, colon_pos, end_pos, name_len, value_len; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
312 int ret; |
0 | 313 |
314 if (hdr_size != NULL) | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
315 memset(hdr_size, 0, sizeof(MessageSize)); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
316 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
317 missing_cr_count = startpos = line_start = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
318 colon_pos = UINT_MAX; |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
319 for (;;) { |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
320 ret = io_buffer_read_data_blocking(inbuf, &msg, &size, |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
321 startpos+1); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
322 if (ret == -2) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
323 /* overflow, line is too long. just skip it. */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
324 i_assert(size > 2); |
0 | 325 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
326 message_skip_line(inbuf, hdr_size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
327 startpos = line_start = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
328 colon_pos = UINT_MAX; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
329 continue; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
330 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
331 |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
332 if (ret < 0) { |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
333 /* EOF, but we may still have something in buffer. |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
334 this is needed only when there's no message body */ |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
335 msg = io_buffer_get_data(inbuf, &size); |
265
d0ba9a65891c
message_parse_header() went to infinite loop with partial header
Timo Sirainen <tss@iki.fi>
parents:
253
diff
changeset
|
336 if (size == startpos) |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
337 break; |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
338 } |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
339 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
340 for (i = startpos; i < size; i++) { |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
341 if (msg[i] == ':' && colon_pos == UINT_MAX) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
342 colon_pos = i; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
343 continue; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
344 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
345 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
346 if (msg[i] != '\n') |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
347 continue; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
348 |
0 | 349 if (hdr_size != NULL) |
350 hdr_size->lines++; | |
351 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
352 if (i == 0 || msg[i-1] != '\r') { |
0 | 353 /* missing CR */ |
354 missing_cr_count++; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
355 } |
0 | 356 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
357 if (i == 0 || (i == 1 && msg[i-1] == '\r')) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
358 /* no headers at all */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
359 break; |
0 | 360 } |
361 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
362 if ((i > 0 && msg[i-1] == '\n') || |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
363 (i > 1 && msg[i-2] == '\n' && msg[i-1] == '\r')) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
364 /* \n\n or \n\r\n - end of headers */ |
0 | 365 break; |
366 } | |
367 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
368 /* make sure the header doesn't continue to next line */ |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
369 if (i+1 == size || !IS_LWSP(msg[i+1])) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
370 if (colon_pos != UINT_MAX && |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
371 colon_pos != line_start && func != NULL && |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
372 !IS_LWSP(msg[line_start])) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
373 /* we have a valid header line */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
374 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
375 /* get length of name-field */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
376 end_pos = colon_pos-1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
377 while (end_pos > line_start && |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
378 IS_LWSP(msg[end_pos])) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
379 end_pos--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
380 name_len = end_pos - line_start + 1; |
0 | 381 |
169
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
382 /* get length of value field. skip |
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
383 only the initial LWSP after ':'. |
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
384 some fields may want to keep |
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
385 the extra spaces.. */ |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
386 colon_pos++; |
169
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
387 if (colon_pos < i && |
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
388 IS_LWSP(msg[colon_pos])) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
389 colon_pos++; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
390 value_len = i - colon_pos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
391 if (msg[i-1] == '\r') value_len--; |
0 | 392 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
393 /* and finally call the function */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
394 func(part, msg + line_start, name_len, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
395 msg + colon_pos, value_len, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
396 context); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
397 } |
0 | 398 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
399 colon_pos = UINT_MAX; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
400 line_start = i+1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
401 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
402 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
403 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
404 if (i < size) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
405 /* end of header */ |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
406 startpos = i+1; |
0 | 407 break; |
408 } | |
409 | |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
410 /* leave the last line to buffer */ |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
411 if (colon_pos != UINT_MAX) |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
412 colon_pos -= line_start; |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
413 if (hdr_size != NULL) |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
414 hdr_size->physical_size += line_start; |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
415 io_buffer_skip(inbuf, line_start); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
416 |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
417 startpos = i-line_start; |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
418 line_start = 0; |
0 | 419 } |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
420 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
421 io_buffer_skip(inbuf, startpos); |
0 | 422 |
423 if (hdr_size != NULL) { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
424 hdr_size->physical_size += startpos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
425 hdr_size->virtual_size += |
0 | 426 hdr_size->physical_size + missing_cr_count; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
427 i_assert(hdr_size->virtual_size >= hdr_size->physical_size); |
0 | 428 } |
429 } | |
430 | |
431 static MessageBoundary *boundary_find(MessageBoundary *boundaries, | |
184 | 432 const char *msg, size_t len) |
0 | 433 { |
434 while (boundaries != NULL) { | |
435 if (boundaries->len <= len && | |
436 strncmp(boundaries->boundary, msg, boundaries->len) == 0) | |
437 return boundaries; | |
438 | |
439 boundaries = boundaries->next; | |
440 } | |
441 | |
442 return NULL; | |
443 } | |
444 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
445 /* read until next boundary is found. if skip_over = FALSE, stop at the |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
446 [\r]\n before the boundary, otherwise leave it right after the known |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
447 boundary so the ending "--" can be checked. */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
448 static MessageBoundary * |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
449 message_find_boundary(IOBuffer *inbuf, MessageBoundary *boundaries, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
450 MessageSize *msg_size, int skip_over) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
451 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
452 MessageBoundary *boundary; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
453 unsigned char *msg; |
184 | 454 size_t i, size, startpos, line_start, missing_cr_count; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
455 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
456 boundary = NULL; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
457 missing_cr_count = startpos = line_start = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
458 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
459 while (io_buffer_read_data_blocking(inbuf, &msg, &size, startpos) > 0) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
460 for (i = startpos; i < size; i++) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
461 if (msg[i] != '\n') |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
462 continue; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
463 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
464 if (i > line_start+2 && msg[line_start] == '-' && |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
465 msg[line_start+1] == '-') { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
466 /* possible boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
467 boundary = boundary_find(boundaries, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
468 msg + line_start + 2, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
469 i - line_start - 2); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
470 if (boundary != NULL) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
471 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
472 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
473 |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
474 if (i == 0 || msg[i-1] != '\r') { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
475 /* missing CR */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
476 missing_cr_count++; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
477 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
478 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
479 msg_size->lines++; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
480 line_start = i+1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
481 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
482 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
483 if (boundary != NULL) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
484 break; |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
485 |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
486 if (i - line_start > 128 && |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
487 msg[line_start] == '-' && msg[line_start+1] == '-') { |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
488 /* long partial line, see if it's a boundary. |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
489 RFC-2046 says that the boundaries must be |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
490 70 chars without "--" or less. We allow |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
491 a bit larger.. */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
492 boundary = boundary_find(boundaries, |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
493 msg + line_start + 2, |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
494 i - line_start - 2); |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
495 if (boundary != NULL) |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
496 break; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
497 |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
498 /* nope, we can skip over the line, just |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
499 leave the last char since it may be \r */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
500 i--; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
501 } else { |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
502 /* leave the last line to buffer, it may be |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
503 boundary */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
504 i = line_start; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
505 if (i > 2) i -= 2; /* leave the \r\n too */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
506 line_start -= i; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
507 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
508 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
509 io_buffer_skip(inbuf, i); |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
510 msg_size->physical_size += i; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
511 msg_size->virtual_size += i; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
512 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
513 startpos = size - i; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
514 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
515 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
516 if (boundary != NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
517 if (skip_over) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
518 /* leave the pointer right after the boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
519 line_start += 2 + boundary->len; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
520 } else if (line_start > 0 && msg[line_start-1] == '\n') { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
521 /* leave the \r\n before the boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
522 line_start--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
523 msg_size->lines--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
524 |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
525 if (line_start > 0 && msg[line_start-1] == '\r') |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
526 line_start--; |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
527 else |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
528 missing_cr_count--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
529 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
530 startpos = line_start; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
531 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
532 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
533 io_buffer_skip(inbuf, startpos); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
534 msg_size->physical_size += startpos; |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
535 msg_size->virtual_size += startpos + missing_cr_count; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
536 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
537 i_assert(msg_size->virtual_size >= msg_size->physical_size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
538 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
539 return boundary; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
540 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
541 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
542 static MessagePart *message_parse_body(IOBuffer *inbuf, |
0 | 543 MessageBoundary *boundaries, |
544 MessageSize *body_size) | |
545 { | |
546 MessageBoundary *boundary; | |
547 | |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
548 if (boundaries == NULL) { |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
549 message_get_body_size(inbuf, body_size, (uoff_t)-1); |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
550 return NULL; |
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
551 } else { |
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
552 boundary = message_find_boundary(inbuf, boundaries, |
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
553 body_size, FALSE); |
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
554 return boundary == NULL ? NULL : boundary->part; |
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
555 } |
0 | 556 } |
557 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
558 /* skip data until next boundary is found. if it's end boundary, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
559 skip the footer as well. */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
560 static MessagePart *message_skip_boundary(IOBuffer *inbuf, |
0 | 561 MessageBoundary *boundaries, |
562 MessageSize *boundary_size) | |
563 { | |
564 MessageBoundary *boundary; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
565 unsigned char *msg; |
184 | 566 size_t size; |
0 | 567 int end_boundary; |
568 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
569 boundary = message_find_boundary(inbuf, boundaries, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
570 boundary_size, TRUE); |
0 | 571 if (boundary == NULL) |
572 return NULL; | |
573 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
574 /* now, see if it's end boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
575 end_boundary = FALSE; |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
576 if (io_buffer_read_data_blocking(inbuf, &msg, &size, 1) > 0) { |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
577 i_assert(size >= 2); |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
578 end_boundary = msg[0] == '-' && msg[1] == '-'; |
0 | 579 } |
580 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
581 /* skip the rest of the line */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
582 message_skip_line(inbuf, boundary_size); |
0 | 583 |
584 if (end_boundary) { | |
585 /* skip the footer */ | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
586 return message_parse_body(inbuf, boundaries, boundary_size); |
0 | 587 } |
588 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
589 return boundary == NULL ? NULL : boundary->part; |
0 | 590 } |