Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-imap/imap-bodystructure.c @ 410:1f0e7229ee58 HEAD
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
file OBuffer.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 14 Oct 2002 02:49:11 +0300 |
parents | e807d88e653c |
children | 8179ef2a2c62 |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "lib.h" | |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
398
diff
changeset
|
4 #include "ibuffer.h" |
0 | 5 #include "temp-string.h" |
6 #include "rfc822-tokenize.h" | |
7 #include "message-parser.h" | |
8 #include "message-content-parser.h" | |
9 #include "imap-envelope.h" | |
10 #include "imap-bodystructure.h" | |
339
6f4eeb6a0a0d
Several fields in BODY were unquoted.
Timo Sirainen <tss@iki.fi>
parents:
307
diff
changeset
|
11 #include "imap-quote.h" |
0 | 12 |
13 #define EMPTY_BODYSTRUCTURE \ | |
14 "(\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\" 0 0)" | |
15 | |
16 typedef struct { | |
17 Pool pool; | |
18 TempString *str; | |
19 char *content_type, *content_subtype; | |
20 char *content_type_params; | |
21 char *content_transfer_encoding; | |
22 char *content_id; | |
23 char *content_description; | |
24 char *content_disposition; | |
25 char *content_disposition_params; | |
26 char *content_md5; | |
27 char *content_language; | |
28 | |
29 MessagePartEnvelopeData *envelope; | |
30 } MessagePartBodyData; | |
31 | |
32 static void part_write_bodystructure(MessagePart *part, TempString *str, | |
33 int extended); | |
34 | |
35 static void parse_content_type(const Rfc822Token *tokens, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
36 int count, void *context) |
0 | 37 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
38 MessagePartBodyData *data = context; |
0 | 39 const char *value; |
40 int i; | |
41 | |
42 /* find the content type separator */ | |
43 for (i = 0; i < count; i++) { | |
44 if (tokens[i].token == '/') | |
45 break; | |
46 } | |
47 | |
112
d6105a8a6ca9
Fixed rfc822_tokens_get_value(). It doesn't have "put spaces around all
Timo Sirainen <tss@iki.fi>
parents:
106
diff
changeset
|
48 value = rfc822_tokens_get_value_quoted(tokens, i); |
0 | 49 data->content_type = p_strdup(data->pool, value); |
50 | |
112
d6105a8a6ca9
Fixed rfc822_tokens_get_value(). It doesn't have "put spaces around all
Timo Sirainen <tss@iki.fi>
parents:
106
diff
changeset
|
51 value = rfc822_tokens_get_value_quoted(tokens+i+1, count-i-1); |
0 | 52 data->content_subtype = p_strdup(data->pool, value); |
53 } | |
54 | |
55 static void parse_save_params_list(const Rfc822Token *name, | |
56 const Rfc822Token *value, int value_count, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
57 void *context) |
0 | 58 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
59 MessagePartBodyData *data = context; |
0 | 60 const char *str; |
61 | |
62 if (data->str->len != 0) | |
63 t_string_append_c(data->str, ' '); | |
64 | |
65 t_string_append_c(data->str, '"'); | |
66 t_string_append_n(data->str, name->ptr, name->len); | |
67 t_string_append(data->str, "\" "); | |
68 | |
112
d6105a8a6ca9
Fixed rfc822_tokens_get_value(). It doesn't have "put spaces around all
Timo Sirainen <tss@iki.fi>
parents:
106
diff
changeset
|
69 str = rfc822_tokens_get_value_quoted(value, value_count); |
0 | 70 t_string_append(data->str, str); |
71 } | |
72 | |
73 static void parse_content_transfer_encoding(const Rfc822Token *tokens, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
74 int count, void *context) |
0 | 75 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
76 MessagePartBodyData *data = context; |
0 | 77 const char *value; |
78 | |
112
d6105a8a6ca9
Fixed rfc822_tokens_get_value(). It doesn't have "put spaces around all
Timo Sirainen <tss@iki.fi>
parents:
106
diff
changeset
|
79 value = rfc822_tokens_get_value_quoted(tokens, count); |
0 | 80 data->content_transfer_encoding = p_strdup(data->pool, value); |
81 } | |
82 | |
83 static void parse_content_disposition(const Rfc822Token *tokens, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
84 int count, void *context) |
0 | 85 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
86 MessagePartBodyData *data = context; |
0 | 87 const char *value; |
88 | |
112
d6105a8a6ca9
Fixed rfc822_tokens_get_value(). It doesn't have "put spaces around all
Timo Sirainen <tss@iki.fi>
parents:
106
diff
changeset
|
89 value = rfc822_tokens_get_value_quoted(tokens, count); |
0 | 90 data->content_disposition = p_strdup(data->pool, value); |
91 } | |
92 | |
93 static void parse_content_language(const Rfc822Token *tokens, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
94 int count, void *context) |
0 | 95 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
96 MessagePartBodyData *data = context; |
398
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
97 TempString *str; |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
98 int quoted; |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
99 |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
100 /* Content-Language: en-US, az-arabic (comments allowed) */ |
0 | 101 |
102 if (count <= 0) | |
103 return; | |
104 | |
398
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
105 str = t_string_new(256); |
0 | 106 |
398
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
107 quoted = FALSE; |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
108 for (; count > 0; count--, tokens++) { |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
109 switch (tokens->token) { |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
110 case '(': |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
111 /* ignore comment */ |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
112 break; |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
113 case ',': |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
114 /* list separator */ |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
115 if (quoted) { |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
116 t_string_append_c(str, '"'); |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
117 quoted = FALSE; |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
118 } |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
119 break; |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
120 default: |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
121 /* anything else goes as-is. only alphabetic characters |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
122 and '-' is allowed, so anything else is error |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
123 which we can deal with however we want. */ |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
124 if (!quoted) { |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
125 if (str->len > 0) |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
126 t_string_append_c(str, ' '); |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
127 t_string_append_c(str, '"'); |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
128 quoted = TRUE; |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
129 } |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
130 |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
131 if (IS_TOKEN_STRING(tokens->token)) { |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
132 t_string_append_n(str, tokens->ptr, |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
133 tokens->len); |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
134 } else { |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
135 t_string_append_c(str, tokens->token); |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
136 } |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
137 break; |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
138 } |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
139 } |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
140 |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
141 if (quoted) |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
142 t_string_append_c(str, '"'); |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
143 |
e807d88e653c
Parse Content-Language correctly for BODYSTRUCTURE.
Timo Sirainen <tss@iki.fi>
parents:
342
diff
changeset
|
144 data->content_language = p_strdup(data->pool, str->str); |
0 | 145 } |
146 | |
147 static void parse_header(MessagePart *part, | |
193 | 148 const char *name, size_t name_len, |
149 const char *value, size_t value_len, | |
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
|
150 void *context) |
0 | 151 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
152 Pool pool = context; |
0 | 153 MessagePartBodyData *part_data; |
154 int parent_rfc822; | |
155 | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
156 parent_rfc822 = part->parent != NULL && |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
157 (part->parent->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822); |
0 | 158 if (!parent_rfc822 && (name_len <= 8 || |
159 strncasecmp(name, "Content-", 8) != 0)) | |
160 return; | |
161 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
162 if (part->context == NULL) { |
0 | 163 /* initialize message part data */ |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
164 part->context = part_data = |
0 | 165 p_new(pool, MessagePartBodyData, 1); |
166 part_data->pool = pool; | |
167 } | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
168 part_data = part->context; |
0 | 169 |
170 t_push(); | |
171 | |
172 /* fix the name to be \0-terminated */ | |
173 name = t_strndup(name, name_len); | |
174 | |
175 if (strcasecmp(name, "Content-Type") == 0) { | |
176 part_data->str = t_string_new(256); | |
177 (void)message_content_parse_header(t_strndup(value, value_len), | |
178 parse_content_type, | |
179 parse_save_params_list, | |
180 part_data); | |
181 part_data->content_type_params = | |
182 p_strdup(pool, part_data->str->str); | |
183 } else if (strcasecmp(name, "Content-Transfer-Encoding") == 0) { | |
184 (void)message_content_parse_header(t_strndup(value, value_len), | |
185 parse_content_transfer_encoding, | |
186 NULL, part_data); | |
187 } else if (strcasecmp(name, "Content-ID") == 0) { | |
339
6f4eeb6a0a0d
Several fields in BODY were unquoted.
Timo Sirainen <tss@iki.fi>
parents:
307
diff
changeset
|
188 part_data->content_id = |
6f4eeb6a0a0d
Several fields in BODY were unquoted.
Timo Sirainen <tss@iki.fi>
parents:
307
diff
changeset
|
189 imap_quote_value(pool, value, value_len); |
0 | 190 } else if (strcasecmp(name, "Content-Description") == 0) { |
191 part_data->content_description = | |
339
6f4eeb6a0a0d
Several fields in BODY were unquoted.
Timo Sirainen <tss@iki.fi>
parents:
307
diff
changeset
|
192 imap_quote_value(pool, value, value_len); |
0 | 193 } else if (strcasecmp(name, "Content-Disposition") == 0) { |
194 part_data->str = t_string_new(256); | |
195 (void)message_content_parse_header(t_strndup(value, value_len), | |
196 parse_content_disposition, | |
197 parse_save_params_list, | |
198 part_data); | |
199 part_data->content_disposition_params = | |
200 p_strdup(pool, part_data->str->str); | |
201 } else if (strcasecmp(name, "Content-Language") == 0) { | |
202 (void)message_content_parse_header(t_strndup(value, value_len), | |
203 parse_content_language, NULL, | |
204 part_data); | |
205 } else if (strcasecmp(name, "Content-MD5") == 0) { | |
339
6f4eeb6a0a0d
Several fields in BODY were unquoted.
Timo Sirainen <tss@iki.fi>
parents:
307
diff
changeset
|
206 part_data->content_md5 = |
6f4eeb6a0a0d
Several fields in BODY were unquoted.
Timo Sirainen <tss@iki.fi>
parents:
307
diff
changeset
|
207 imap_quote_value(pool, value, value_len); |
0 | 208 } else if (parent_rfc822) { |
209 /* message/rfc822, we need the envelope */ | |
210 imap_envelope_parse_header(pool, &part_data->envelope, | |
211 name, value, value_len); | |
212 } | |
213 t_pop(); | |
214 } | |
215 | |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
398
diff
changeset
|
216 static void part_parse_headers(MessagePart *part, IBuffer *inbuf, |
307
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
217 uoff_t start_offset, Pool pool) |
0 | 218 { |
219 while (part != NULL) { | |
220 /* note that we want to parse the header of all | |
221 the message parts, multiparts too. */ | |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
398
diff
changeset
|
222 i_assert(part->physical_pos >= inbuf->v_offset - start_offset); |
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
398
diff
changeset
|
223 i_buffer_skip(inbuf, part->physical_pos - |
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
398
diff
changeset
|
224 (inbuf->v_offset - start_offset)); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
225 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
226 message_parse_header(part, inbuf, NULL, parse_header, pool); |
0 | 227 |
307
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
228 if (part->children != NULL) { |
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
229 part_parse_headers(part->children, inbuf, |
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
230 start_offset, pool); |
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
231 } |
0 | 232 |
233 part = part->next; | |
234 } | |
235 } | |
236 | |
237 static void part_write_body_multipart(MessagePart *part, TempString *str, | |
238 int extended) | |
239 { | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
240 MessagePartBodyData *data = part->context; |
0 | 241 |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
398
diff
changeset
|
242 i_assert(data != NULL); |
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
398
diff
changeset
|
243 |
0 | 244 if (part->children != NULL) |
245 part_write_bodystructure(part->children, str, extended); | |
246 else { | |
247 /* no parts in multipart message, | |
248 that's not allowed. write a single | |
249 0-length text/plain structure */ | |
250 t_string_append(str, EMPTY_BODYSTRUCTURE); | |
251 } | |
252 | |
253 t_string_append_c(str, ' '); | |
254 t_string_append(str, data->content_subtype); | |
255 | |
256 if (!extended) | |
257 return; | |
258 | |
259 /* BODYSTRUCTURE data */ | |
260 t_string_append_c(str, ' '); | |
261 if (data->content_type_params == NULL) | |
262 t_string_append(str, "NIL"); | |
263 else { | |
264 t_string_append_c(str, '('); | |
265 t_string_append(str, data->content_type_params); | |
266 t_string_append_c(str, ')'); | |
267 } | |
268 | |
269 t_string_append_c(str, ' '); | |
270 if (data->content_disposition == NULL) | |
271 t_string_append(str, "NIL"); | |
272 else { | |
273 t_string_append_c(str, '('); | |
274 t_string_append(str, data->content_disposition); | |
275 if (data->content_disposition_params != NULL) { | |
276 t_string_append(str, " ("); | |
277 t_string_append(str, data->content_disposition_params); | |
278 t_string_append_c(str, ')'); | |
279 } | |
280 t_string_append_c(str, ')'); | |
281 } | |
282 | |
283 t_string_append_c(str, ' '); | |
284 if (data->content_language == NULL) | |
285 t_string_append(str, "NIL"); | |
286 else { | |
287 t_string_append_c(str, '('); | |
288 t_string_append(str, data->content_language); | |
289 t_string_append_c(str, ')'); | |
290 } | |
291 } | |
292 | |
293 static void part_write_body(MessagePart *part, TempString *str, int extended) | |
294 { | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
295 MessagePartBodyData *data = part->context; |
0 | 296 |
297 if (data == NULL) { | |
298 /* there was no content headers, use an empty structure */ | |
299 data = t_new(MessagePartBodyData, 1); | |
300 } | |
301 | |
302 /* "content type" "subtype" */ | |
303 t_string_append(str, NVL(data->content_type, "\"text\"")); | |
304 t_string_append_c(str, ' '); | |
305 t_string_append(str, NVL(data->content_subtype, "\"plain\"")); | |
306 | |
307 /* ("content type param key" "value" ...) */ | |
308 t_string_append_c(str, ' '); | |
309 if (data->content_type_params == NULL) | |
310 t_string_append(str, "NIL"); | |
311 else { | |
312 t_string_append_c(str, '('); | |
313 t_string_append(str, data->content_type_params); | |
314 t_string_append_c(str, ')'); | |
315 } | |
316 | |
183
4a7ab9e94f25
size_t fixes for lib/. Changed OFF_T_FORMAT to PRIuOFF_T which is more
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
317 t_string_printfa(str, " %s %s %s %"PRIuUOFF_T, |
0 | 318 NVL(data->content_id, "NIL"), |
319 NVL(data->content_description, "NIL"), | |
320 NVL(data->content_transfer_encoding, "\"8bit\""), | |
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
|
321 part->body_size.virtual_size); |
0 | 322 |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
323 if (part->flags & MESSAGE_PART_FLAG_TEXT) { |
0 | 324 /* text/.. contains line count */ |
325 t_string_printfa(str, " %u", part->body_size.lines); | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
326 } else if (part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) { |
0 | 327 /* message/rfc822 contains envelope + body + line count */ |
328 MessagePartBodyData *child_data; | |
329 | |
330 i_assert(part->children != NULL); | |
331 i_assert(part->children->next == NULL); | |
332 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
333 child_data = part->children->context; |
0 | 334 |
335 t_string_append_c(str, ' '); | |
336 if (child_data != NULL && child_data->envelope != NULL) { | |
342
eeb855e385ce
() was missing around envelope in body/bodystructure.
Timo Sirainen <tss@iki.fi>
parents:
339
diff
changeset
|
337 t_string_append_c(str, '('); |
0 | 338 imap_envelope_write_part_data(child_data->envelope, |
339 str); | |
342
eeb855e385ce
() was missing around envelope in body/bodystructure.
Timo Sirainen <tss@iki.fi>
parents:
339
diff
changeset
|
340 t_string_append_c(str, ')'); |
0 | 341 } else { |
342 /* buggy message */ | |
343 t_string_append(str, "NIL"); | |
344 } | |
345 t_string_append_c(str, ' '); | |
346 part_write_bodystructure(part->children, str, extended); | |
347 t_string_printfa(str, " %u", part->body_size.lines); | |
348 } | |
349 | |
350 if (!extended) | |
351 return; | |
352 | |
353 /* BODYSTRUCTURE data */ | |
354 | |
355 /* "md5" ("content disposition" ("disposition" "params")) | |
356 ("body" "language" "params") */ | |
357 t_string_append_c(str, ' '); | |
358 t_string_append(str, NVL(data->content_md5, "NIL")); | |
359 | |
360 t_string_append_c(str, ' '); | |
361 if (data->content_disposition == NULL) | |
362 t_string_append(str, "NIL"); | |
363 else { | |
364 t_string_append_c(str, '('); | |
365 t_string_append(str, data->content_disposition); | |
366 t_string_append_c(str, ')'); | |
367 | |
368 if (data->content_disposition_params != NULL) { | |
369 t_string_append(str, " ("); | |
370 t_string_append(str, data->content_disposition_params); | |
371 t_string_append_c(str, ')'); | |
372 } | |
373 } | |
374 | |
375 t_string_append_c(str, ' '); | |
376 if (data->content_language == NULL) | |
377 t_string_append(str, "NIL"); | |
378 else { | |
379 t_string_append_c(str, '('); | |
380 t_string_append(str, data->content_language); | |
381 t_string_append_c(str, ')'); | |
382 } | |
383 } | |
384 | |
385 static void part_write_bodystructure(MessagePart *part, TempString *str, | |
386 int extended) | |
387 { | |
388 while (part != NULL) { | |
389 t_string_append_c(str, '('); | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
390 if (part->flags & MESSAGE_PART_FLAG_MULTIPART) |
0 | 391 part_write_body_multipart(part, str, extended); |
392 else | |
393 part_write_body(part, str, extended); | |
394 | |
395 part = part->next; | |
396 t_string_append_c(str, ')'); | |
397 } | |
398 } | |
399 | |
400 static const char *part_get_bodystructure(MessagePart *part, int extended) | |
401 { | |
402 TempString *str; | |
403 | |
404 str = t_string_new(2048); | |
405 part_write_bodystructure(part, str, extended); | |
406 return str->str; | |
407 } | |
408 | |
409 const char *imap_part_get_bodystructure(Pool pool, MessagePart **part, | |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
398
diff
changeset
|
410 IBuffer *inbuf, int extended) |
0 | 411 { |
307
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
412 uoff_t start_offset; |
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
413 |
0 | 414 if (*part == NULL) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
415 *part = message_parse(pool, inbuf, parse_header, pool); |
307
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
416 else { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
398
diff
changeset
|
417 start_offset = inbuf->v_offset; |
307
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
418 part_parse_headers(*part, inbuf, start_offset, pool); |
5954f9c2e620
BODY / BODYSTRUCTURE generator didn't like if message didn't start from zero
Timo Sirainen <tss@iki.fi>
parents:
193
diff
changeset
|
419 } |
0 | 420 |
421 return part_get_bodystructure(*part, extended); | |
422 } |