]> code.citadel.org Git - citadel.git/blob - citadel/mime_parser.c
Started a rewrite of the MIME parser
[citadel.git] / citadel / mime_parser.c
1 /*
2  * mime_parser.c
3  *
4  * This is a really bad attempt at writing a parser to handle MIME-encoded
5  * messages.
6  *
7  * Copyright (c) 1998-1999 by Art Cancro
8  * This code is distributed under the terms of the GNU General Public License.
9  *
10  */
11
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <signal.h>
16 #include <sys/types.h>
17 #include <ctype.h>
18 #include <string.h>
19 #include "mime_parser.h"
20
21
22
23 void extract_key(char *target, char *source, char *key) {
24         int a, b;
25
26         strcpy(target, source);
27         for (a=0; a<strlen(target); ++a) {
28                 if ((!strncasecmp(&target[a], key, strlen(key)))
29                    && (target[a+strlen(key)]=='=')) {
30                         strcpy(target, &target[a+strlen(key)+1]);
31                         if (target[0]==34) strcpy(target, &target[1]);
32                         for (b=0; b<strlen(target); ++b)
33                                 if (target[b]==34) target[b]=0;
34                         return;
35                         }
36                 }
37         strcpy(target, "");
38         }
39
40
41
42         /**** OTHERWISE, HERE'S WHERE WE HANDLE THE STUFF!! *****
43
44         CallBack(name, filename, "", content, content_type, length);
45
46         **** END OF STUFF-HANDLER ****/
47
48
49 /* 
50  * Utility function to "readline" from memory
51  * (returns new pointer)
52  */
53 char *memreadline(char *start, char *buf, int maxlen) {
54         char ch;
55         char *ptr;
56
57         ptr = start;
58         bzero(buf, maxlen);
59
60         while(1) {
61                 ch = *ptr++;
62                 if ((ch==10)||(ch==0)) {
63                         if (strlen(buf)>0)
64                                 if (buf[strlen(buf)-1]==13)
65                                         buf[strlen(buf)-1] = 0;
66                         return ptr;
67                         }
68                 if (strlen(buf) < (maxlen-1)) {
69                         buf[strlen(buf)+1] = 0;
70                         buf[strlen(buf)] = ch;
71                         }
72                 }
73         }
74
75
76
77 /*
78  * Break out the components of a multipart message
79  * (This function expects to be fed HEADERS + CONTENT)
80  */
81 void mime_parser(char *content,
82                 void (*CallBack)
83                         (char *cbname,
84                         char *cbfilename,
85                         char *cbencoding,
86                         void *cbcontent,
87                         char *cbtype,
88                         size_t cblength)
89                 ) {
90
91         char *ptr;
92         char *part_start, *part_end;
93         char buf[256];
94         char header[256];
95         char boundary[256];
96         char content_type[256];
97         char encoding[256];
98         int content_length;
99         int i;
100
101         ptr = content;
102         bzero(boundary, sizeof boundary);
103         bzero(content_type, sizeof content_type);
104         bzero(encoding, sizeof encoding);
105         content_length = 0;
106
107         /* Learn interesting things from the headers */
108         strcpy(header, "");
109         do {
110                 ptr = memreadline(ptr, buf, sizeof buf);
111                 for (i=0; i<strlen(buf); ++i)
112                         if (isspace(buf[i])) buf[i]=' ';
113                 if (!isspace(buf[0])) {
114                         if (!strncasecmp(header, "Content-type: ", 14))
115                                 strcpy(content_type, &header[14]);
116                         if (!strncasecmp(header, "Content-length: ", 16))
117                                 content_length = atoi(&header[16]);
118                         if (!strncasecmp(header,
119                                 "Content-transfer-encoding: ", 27))
120                                         strcpy(encoding, &header[27]);
121                         if (strlen(boundary)==0)
122                                 extract_key(boundary, header, "boundary");
123                         strcpy(header, "");
124                         }
125                 if ((strlen(header)+strlen(buf)+2)<sizeof(header))
126                         strcat(header, buf);
127                 } while ((strlen(buf) > 0) && (*ptr != 0));
128
129         cprintf("Content type is <%s>\n", content_type);
130         cprintf("Encoding is <%s>\n", encoding);
131         cprintf("Content length is %d\n", content_length);
132         cprintf("Boundary is <%s>\n", boundary);
133
134         if (*ptr == 0) return; /* premature end of message */
135
136         /* If this is a multipart message, then recursively process it */
137         if (strlen(boundary)>0) {
138                 }
139         
140
141         }