Add disk_applet executable to the ignore list
[rmail.git] / src / utils / mime.c
blobb02cfc32dbc50f14fb6a5ea0df67f7aa1395e004
1 /* MIME types
3 * http://www.iana.org/assignments/media-types/index.html
5 */
7 #include <stdio.h>
8 #include <string.h>
9 #include <ctype.h>
11 #include "string_utils.h"
12 #include "mime.h"
14 /* XXX Only for text/plain check RFCs ??? */
15 /**
16 * Parse text parameters
18 * @param[in] buf Header line
19 * @param[in|out] hdr Mime header struct
21 static void parse_text_params(const char *buf, struct mime_header *hdr)
23 const char *p;
25 p = trim_spaces(buf);
27 #if 0
28 fprintf(stderr, "%s - %s\n", __func__, p);
29 #endif
31 if (!strncasecmp(p, "charset=", 8)) {
32 p += 8;
33 /* Check if the charset is double-quoted */
34 if (*p == '"') {
35 /* skip the first quote-character */
36 p++;
39 if (!strncasecmp(p, "us-ascii", 8)) {
40 hdr->type_charset = MIME_TYPE_CHARSET_US_ASCII;
41 } else if (!strncasecmp(p, "iso-8859-1", 10)) {
42 hdr->type_charset = MIME_TYPE_CHARSET_ISO_8859_1;
43 } else if (!strncasecmp(p, "utf-8", 5)) {
44 hdr->type_charset = MIME_TYPE_CHARSET_UTF_8;
45 } else if (!strncasecmp(p, "windows-1252", 12)) {
46 hdr->type_charset = MIME_TYPE_CHARSET_WINDOWS_1252;
47 } else {
48 hdr->type_charset = MIME_TYPE_CHARSET_UNKNOWN;
53 /**
54 * Parse multipart parameters
56 * @param[in] buf Header line
57 * @param[in|out] hdr Mime header struct
59 static void parse_multipart_params(const char *buf, struct mime_header *hdr)
61 const char *p;
62 const char *endp;
64 p = trim_spaces(buf);
66 #if 0
67 fprintf(stderr, "%s - %s\n", __func__, p);
68 #endif
69 if (!strncasecmp(p, "boundary=", 9)) {
70 p += 9;
72 /* Skip the first quote-character */
73 if (*p == '"') {
74 p++;
75 endp = strchr(p, '"');
76 } else {
77 endp = strchr(p, ';');
80 if (!endp) {
81 endp = strchr(p, '\n');
84 /* Skip the lasst char e.g: ";\n */
85 if (endp) {
86 endp--;
89 if (!substrncpy(hdr->boundary, p, endp, 1024)) {
90 *hdr->boundary = '\0';
95 static void mime_content_subtype_text(const char *buf, struct mime_header *hdr)
97 const char *p;
99 p = buf;
100 if (*p != '/') {
101 hdr->subtype = MIME_SUBTYPE_UNKNOWN;
102 return;
105 p++;
107 if (!strncasecmp(p, "plain", 5)) {
108 hdr->subtype = MIME_SUBTYPE_PLAIN;
109 p += 5;
110 } else if (!strncasecmp(p, "html", 4)) {
111 hdr->subtype = MIME_SUBTYPE_HTML;
112 p += 4;
113 } else {
114 hdr->subtype = MIME_SUBTYPE_UNKNOWN;
115 return;
118 /* Check Parameters */
119 if (*p == ';') {
120 p++;
121 parse_text_params(p, hdr);
126 * multipart/mixed: MIME E-mail; Defined in RFC 2045 and RFC 2046
127 * multipart/alternative: MIME E-mail; Defined in RFC 2045 and RFC 2046
128 * multipart/related: MIME E-mail; Defined in RFC 2387 and used by MHTML (HTML mail)
129 * multipart/form-data: MIME Webform; Defined in RFC 2388
130 * multipart/signed: Defined in RFC 1847
131 * multipart/encrypted: Defined in RFC 1847
134 static void mime_content_subtype_multipart(const char *buf, struct mime_header *hdr)
136 if (*buf != '/') {
137 hdr->subtype = MIME_SUBTYPE_UNKNOWN;
138 return;
141 buf++;
143 if (!strncasecmp(buf, "alternative", 11))
144 hdr->subtype = MIME_SUBTYPE_ALTERNATIVE;
145 else if (!strncasecmp(buf, "mixed", 5))
146 hdr->subtype = MIME_SUBTYPE_MIXED;
147 else if (!strncasecmp(buf, "related", 7))
148 hdr->subtype = MIME_SUBTYPE_RELATED;
149 else if (!strncasecmp(buf, "form-data", 9))
150 hdr->subtype = MIME_SUBTYPE_FORM_DATA;
151 else if (!strncasecmp(buf, "signed", 6))
152 hdr->subtype = MIME_SUBTYPE_SIGNED;
153 else if (!strncasecmp(buf, "encrypted", 9))
154 hdr->subtype = MIME_SUBTYPE_ENCRYPTED;
156 else if (!strncasecmp(buf, "byteranges", 10))
157 hdr->subtype = MIME_SUBTYPE_BYTERANGES;
158 else if (!strncasecmp(buf, "digest", 6))
159 hdr->subtype = MIME_SUBTYPE_DIGEST;
160 else if (!strncasecmp(buf, "header-set", 10))
161 hdr->subtype = MIME_SUBTYPE_HEADER_SET;
162 else if (!strncasecmp(buf, "parallel", 8))
163 hdr->subtype = MIME_SUBTYPE_PARALLEL;
164 else if (!strncasecmp(buf, "report", 6))
165 hdr->subtype = MIME_SUBTYPE_REPORT;
166 else if (!strncasecmp(buf, "appledouble", 11))
167 hdr->subtype = MIME_SUBTYPE_APPLEDOUBLE;
168 else if (!strncasecmp(buf, "voice-message", 13))
169 hdr->subtype = MIME_SUBTYPE_VOICE_MESSAGE;
170 else
171 hdr->subtype = MIME_SUBTYPE_UNKNOWN;
174 /* Parse media type */
175 void mime_content_type(const char *buf, struct mime_header *hdr)
177 const char *p;
179 p = buf;
181 while (*p != '\0' && isspace(*p)) {
182 if (*p == '\n' || *p == '\r') {
183 hdr->type = MIME_TYPE_UNKNOWN;
184 return;
186 p++;
189 /* Check MIME type */
190 /* text/plain is the default for e-mail */
191 if (!strncasecmp(p, "text", 4)) {
192 hdr->type = MIME_TYPE_TEXT;
193 p += 4;
194 mime_content_subtype_text(p, hdr);
195 } else if (!strncasecmp(p, "multipart", 9)) {
196 hdr->type = MIME_TYPE_MULTIPART;
197 p += 9;
198 mime_content_subtype_multipart(p, hdr);
199 } else if (!strncasecmp(p, "application", 11)) {
200 hdr->type = MIME_TYPE_APPLICATION;
201 p += 11;
202 } else if (!strncasecmp(p, "audio", 5)) {
203 hdr->type = MIME_TYPE_AUDIO;
204 p += 5;
205 } else if (!strncasecmp(p, "example", 7)) {
206 hdr->type = MIME_TYPE_EXAMPLE;
207 p += 7;
208 } else if (!strncasecmp(p, "image", 5)) {
209 hdr->type = MIME_TYPE_IMAGE;
210 p += 5;
211 } else if (!strncasecmp(p, "message", 7)) {
212 hdr->type = MIME_TYPE_MESSAGE;
213 p += 7;
214 } else if (!strncasecmp(p, "model", 5)) {
215 hdr->type = MIME_TYPE_MODEL;
216 p += 5;
217 } else if (!strncasecmp(p, "video", 5)) {
218 hdr->type = MIME_TYPE_VIDEO;
219 p += 5;
220 } else {
221 hdr->type = MIME_TYPE_UNKNOWN;
225 /* XXX Only for text/plain check RFCs ??? */
226 void mime_content_type_parameter(const char *buf, struct mime_header *hdr)
228 switch (hdr->type) {
229 case MIME_TYPE_TEXT:
230 parse_text_params(buf, hdr);
231 break;
232 case MIME_TYPE_MULTIPART:
233 parse_multipart_params(buf, hdr);
234 break;
235 default:
236 break;
240 void mime_content_disposition(const char *buf, struct mime_header *hdr)
242 const char *p;
244 p = buf;
246 while (*p != '\0' && isspace(*p)) {
247 if (*p == '\n' || *p == '\r') {
248 hdr->disposition = MIME_DISPOSITION_UNKNOWN;
249 return;
251 p++;
254 /* text/plain is the default */
255 if (!strncasecmp(p, "inline", 6)) {
256 hdr->disposition = MIME_DISPOSITION_INLINE;
257 p += 6;
258 } else if (!strncasecmp(p, "attachment", 10)) {
259 hdr->disposition = MIME_DISPOSITION_ATTACHMENT;
260 p += 10;
261 } else {
262 hdr->disposition = MIME_DISPOSITION_UNKNOWN;
265 /* Check Parameters */
266 if (*p == ';') {
267 fprintf(stderr, "%s - ; found\n", __func__);
271 void mime_content_transfer_encoding(const char *buf, struct mime_header *hdr)
273 const char *p;
275 p = buf;
277 while (*p != '\0' && isspace(*p)) {
278 if (*p == '\n' || *p == '\r') {
279 hdr->transfer_encoding = MIME_ENCODING_7BIT;
280 return;
282 p++;
285 if (!strncasecmp(p, "7bit", 4)) {
286 hdr->transfer_encoding = MIME_ENCODING_7BIT;
287 } else if (!strncasecmp(p, "quoted-printable", 16)) {
288 hdr->transfer_encoding = MIME_ENCODING_QUOTED_PRINTABLE;
289 } else if (!strncasecmp(p, "base64", 6)) {
290 hdr->transfer_encoding = MIME_ENCODING_BASE64;
291 } else if (!strncasecmp(p, "8bit", 4)) {
292 hdr->transfer_encoding = MIME_ENCODING_8BIT;
293 } else if (!strncasecmp(p, "binary", 6)) {
294 hdr->transfer_encoding = MIME_ENCODING_BINARY;
295 } else {
296 hdr->transfer_encoding = MIME_ENCODING_UNKNOWN;
297 return;
300 /* Check Parameters */
301 if (*p == ';') {
302 fprintf(stderr, "%s - ; found\n", __func__);
306 /* DEBUG */
307 static void debug_mime_text_charset(const struct mime_header *hdr)
309 fprintf(stderr, "; charset=");
311 switch (hdr->type_charset) {
312 case MIME_TYPE_CHARSET_US_ASCII:
313 fprintf(stderr, "\"us-ascii\"");
314 break;
315 case MIME_TYPE_CHARSET_ISO_8859_1:
316 fprintf(stderr, "\"iso-8859-1\"");
317 break;
318 case MIME_TYPE_CHARSET_UTF_8:
319 fprintf(stderr, "\"utf-8\"");
320 break;
321 case MIME_TYPE_CHARSET_WINDOWS_1252:
322 fprintf(stderr, "\"windows-1252\"");
323 break;
324 case MIME_SUBTYPE_UNKNOWN:
325 fprintf(stderr, "UNKNOWN");
326 break;
327 default:
328 fprintf(stderr, "%d", hdr->type_charset);
329 break;
333 static void debug_mime_text(const struct mime_header *hdr)
335 fprintf(stderr, "text/");
337 switch (hdr->subtype) {
338 case MIME_SUBTYPE_PLAIN:
339 fprintf(stderr, "plain");
340 break;
341 case MIME_SUBTYPE_HTML:
342 fprintf(stderr, "html");
343 break;
344 case MIME_SUBTYPE_UNKNOWN:
345 fprintf(stderr, "UNKNOWN");
346 break;
347 default:
348 fprintf(stderr, "%d", hdr->subtype);
349 break;
352 debug_mime_text_charset(hdr);
355 static void debug_mime_multipart(const struct mime_header *hdr)
357 fprintf(stderr, "multipart/");
359 switch (hdr->subtype) {
360 case MIME_SUBTYPE_ALTERNATIVE:
361 fprintf(stderr, "alternative");
362 break;
363 case MIME_SUBTYPE_MIXED:
364 fprintf(stderr, "mixed");
365 break;
366 case MIME_SUBTYPE_RELATED:
367 fprintf(stderr, "related");
368 break;
369 case MIME_SUBTYPE_FORM_DATA:
370 fprintf(stderr, "form-data");
371 break;
372 case MIME_SUBTYPE_SIGNED:
373 fprintf(stderr, "signed");
374 break;
375 case MIME_SUBTYPE_ENCRYPTED:
376 fprintf(stderr, "encrypted");
377 break;
378 case MIME_SUBTYPE_UNKNOWN:
379 fprintf(stderr, "UNKNOWN");
380 break;
381 default:
382 fprintf(stderr, "%d", hdr->subtype);
383 break;
386 fprintf(stderr, "; boundary=\"%s\"\n", hdr->boundary);
389 static void debug_mime_application(const struct mime_header *hdr)
391 fprintf(stderr, "application/");
393 switch (hdr->subtype) {
394 case MIME_SUBTYPE_UNKNOWN:
395 fprintf(stderr, "UNKNOWN");
396 break;
397 default:
398 fprintf(stderr, "%d", hdr->subtype);
399 break;
401 fprintf(stderr, "\n");
404 static void debug_mime_audio(const struct mime_header *hdr)
406 fprintf(stderr, "audio/");
407 switch (hdr->subtype) {
408 case MIME_SUBTYPE_UNKNOWN:
409 fprintf(stderr, "UNKNOWN");
410 break;
411 default:
412 fprintf(stderr, "%d", hdr->subtype);
413 break;
415 fprintf(stderr, "\n");
419 static void debug_mime_image(const struct mime_header *hdr)
421 fprintf(stderr, "image/");
422 switch (hdr->subtype) {
423 case MIME_SUBTYPE_UNKNOWN:
424 fprintf(stderr, "UNKNOWN");
425 break;
426 default:
427 fprintf(stderr, "%d", hdr->subtype);
428 break;
430 fprintf(stderr, "\n");
434 static void debug_mime_message(const struct mime_header *hdr)
436 fprintf(stderr, "message/");
437 switch (hdr->subtype) {
438 case MIME_SUBTYPE_UNKNOWN:
439 fprintf(stderr, "UNKNOWN");
440 break;
441 default:
442 fprintf(stderr, "%d", hdr->subtype);
443 break;
445 fprintf(stderr, "\n");
448 static void debug_mime_model(const struct mime_header *hdr)
450 fprintf(stderr, "model/");
451 switch (hdr->subtype) {
452 case MIME_SUBTYPE_UNKNOWN:
453 fprintf(stderr, "UNKNOWN");
454 break;
455 default:
456 fprintf(stderr, "%d", hdr->subtype);
457 break;
459 fprintf(stderr, "\n");
462 static void debug_mime_video(const struct mime_header *hdr)
464 fprintf(stderr, "video/");
465 switch (hdr->subtype) {
466 case MIME_SUBTYPE_UNKNOWN:
467 fprintf(stderr, "UNKNOWN");
468 break;
469 default:
470 fprintf(stderr, "%d", hdr->subtype);
471 break;
473 fprintf(stderr, "\n");
476 void debug_mime_header(const struct mime_header *hdr)
478 fprintf(stderr, "MIME Header:\n");
480 /* MIME Content-Type */
481 fprintf(stderr, " Content-Type.............: ");
482 switch (hdr->type) {
483 case MIME_TYPE_TEXT:
484 debug_mime_text(hdr);
485 fprintf(stderr, "\n");
486 break;
487 case MIME_TYPE_MULTIPART:
488 debug_mime_multipart(hdr);
489 break;
490 case MIME_TYPE_APPLICATION:
491 debug_mime_application(hdr);
492 break;
493 case MIME_TYPE_AUDIO:
494 debug_mime_audio(hdr);
495 break;
496 case MIME_TYPE_EXAMPLE:
497 fprintf(stderr, "example\n");
498 break;
499 case MIME_TYPE_IMAGE:
500 debug_mime_image(hdr);
501 break;
502 case MIME_TYPE_MESSAGE:
503 debug_mime_message(hdr);
504 break;
505 case MIME_TYPE_MODEL:
506 debug_mime_model(hdr);
507 break;
508 case MIME_TYPE_VIDEO:
509 debug_mime_video(hdr);
510 break;
511 case MIME_TYPE_UNKNOWN:
512 default:
513 fprintf(stderr, "Unknown\n");
514 break;
517 /* MIME Content-Disposition */
518 fprintf(stderr, " Content-Disposition......: ");
519 switch (hdr->disposition) {
520 case MIME_DISPOSITION_INLINE:
521 fprintf(stderr, "inline\n");
522 break;
523 case MIME_DISPOSITION_ATTACHMENT:
524 fprintf(stderr, "attachment\n");
525 break;
526 case MIME_DISPOSITION_UNKNOWN:
527 default:
528 fprintf(stderr, "Unknown\n");
529 break;
532 /* MIME Content-Transfer-Encoding */
533 fprintf(stderr, " Content-Transfer-Encoding: ");
534 switch (hdr->transfer_encoding) {
535 case MIME_ENCODING_7BIT:
536 fprintf(stderr, "7bit\n");
537 break;
538 case MIME_ENCODING_QUOTED_PRINTABLE:
539 fprintf(stderr, "quoted-printable\n");
540 break;
541 case MIME_ENCODING_BASE64:
542 fprintf(stderr, "base64\n");
543 break;
544 case MIME_ENCODING_8BIT:
545 fprintf(stderr, "8bit\n");
546 break;
547 case MIME_ENCODING_BINARY:
548 fprintf(stderr, "binary\n");
549 break;
550 case MIME_ENCODING_UNKNOWN:
551 default:
552 fprintf(stderr, "Unknown\n");
553 break;