MimeParser Rewrite: add test to revalidate the results of the rewrite to the stable...
[citadel.git] / libcitadel / tests / mimeparser_test.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <dirent.h>
8 #include <errno.h>
9
10 #include <fcntl.h>
11
12 #include <unistd.h>
13 #include <stddef.h>
14
15
16 #include "../lib/libcitadel.h"
17
18 /* shamelesly copied from msgbase.h */
19 struct ma_info {
20         int is_ma;              /* Set to 1 if we are using this stuff */
21         int freeze;             /* Freeze the replacement chain because we're
22                                  * digging through a subsection */
23         int did_print;          /* One alternative has been displayed */
24         char chosen_part[128];  /* Which part of a m/a did we choose? */
25         const char *printme;
26         int chosen_pref;        /* Chosen part preference level (lower is better) */
27         int use_fo_hooks;       /* Use fixed output hooks */
28         int dont_decode;        /* should we call the decoder or not? */
29 };
30
31
32 /*
33  * Callback function for mime parser that simply lists the part
34  */
35 static void list_this_part(char *name, 
36                            char *filename, 
37                            char *partnum, 
38                            char *disp,
39                            void *content, 
40                            char *cbtype, 
41                            char *cbcharset, 
42                            size_t length, 
43                            char *encoding,
44                            char *cbid, 
45                            void *cbuserdata)
46 {
47         struct ma_info *ma;
48         
49         ma = (struct ma_info *)cbuserdata;
50         if (ma->is_ma == 0) {
51                 printf("part=%s|%s|%s|%s|%s|%ld|%s|%s\n",
52                         name, 
53                         filename, 
54                         partnum, 
55                         disp, 
56                         cbtype, 
57                         (long)length, 
58                         cbid, 
59                         cbcharset);
60         }
61 }
62
63 /* 
64  * Callback function for multipart prefix
65  */
66 static void list_this_pref(char *name, 
67                            char *filename, 
68                            char *partnum, 
69                            char *disp,
70                            void *content, 
71                            char *cbtype, 
72                            char *cbcharset, 
73                            size_t length, 
74                            char *encoding,
75                            char *cbid, 
76                            void *cbuserdata)
77 {
78         struct ma_info *ma;
79         
80         ma = (struct ma_info *)cbuserdata;
81         if (!strcasecmp(cbtype, "multipart/alternative")) {
82                 ++ma->is_ma;
83         }
84
85         if (ma->is_ma == 0) {
86                 printf("pref=%s|%s\n", partnum, cbtype);
87         }
88 }
89
90 /* 
91  * Callback function for multipart sufffix
92  */
93 static void list_this_suff(char *name, 
94                            char *filename, 
95                            char *partnum, 
96                            char *disp,
97                            void *content, 
98                            char *cbtype, 
99                            char *cbcharset, 
100                            size_t length, 
101                            char *encoding,
102                            char *cbid, 
103                            void *cbuserdata)
104 {
105         struct ma_info *ma;
106         
107         ma = (struct ma_info *)cbuserdata;
108         if (ma->is_ma == 0) {
109                 printf("suff=%s|%s\n", partnum, cbtype);
110         }
111         if (!strcasecmp(cbtype, "multipart/alternative")) {
112                 --ma->is_ma;
113         }
114 }
115
116
117 /*
118  * Callback function for mime parser that opens a section for downloading
119  */
120 static void mime_download(char *name, 
121                           char *filename, 
122                           char *partnum, 
123                           char *disp,
124                           void *content, 
125                           char *cbtype, 
126                           char *cbcharset, 
127                           size_t length,
128                           char *encoding, 
129                           char *cbid, 
130                           void *cbuserdata)
131 {
132         int rc = 0;
133
134         /* Silently go away if there's already a download open. */
135
136         struct ma_info *ma;
137         
138         ma = (struct ma_info *)cbuserdata;
139
140         if ((!IsEmptyStr(partnum) && (!strcasecmp(ma->printme, partnum)))) {
141                         rc = write(STDOUT_FILENO, content, length);
142         }
143 }
144
145
146
147 /*
148  * Callback function for mime parser that outputs a section all at once.
149  * We can specify the desired section by part number *or* content-id.
150  * /
151 void mime_spew_section(char *name, 
152                        char *filename, 
153                        char *partnum, 
154                        char *disp,
155                        void *content, 
156                        char *cbtype, 
157                        char *cbcharset, 
158                        size_t length,
159                        char *encoding, 
160                        char *cbid, 
161                        void *cbuserdata)
162 {
163         int *found_it = (int *)cbuserdata;
164
165         if (
166                 (!IsEmptyStr(partnum) && (!strcasecmp(CC->download_desired_section, partnum)))
167         ||      (!IsEmptyStr(cbid) && (!strcasecmp(CC->download_desired_section, cbid)))
168         ) {
169                 *found_it = 1;
170                 printf("%d %d|-1|%s|%s|%s\n",
171                         BINARY_FOLLOWS,
172                         (int)length,
173                         filename,
174                         cbtype,
175                         cbcharset
176                 );
177                 fwrite(STDOUT, content, length);
178         }
179 }
180
181 */
182
183
184
185
186 int main(int argc, char* argv[])
187 {
188         char a;
189         int fd;
190         char *filename = NULL;
191         struct stat statbuf;
192         const char *Err;
193
194         StrBuf *MimeBuf;
195         long MimeLen;
196         char *MimeStr;
197         struct ma_info ma;
198         int do_proto = 0;
199         int dont_decode = 1;
200
201         setvbuf(stdout, NULL, _IONBF, 0);
202         memset(&ma, 0, sizeof(struct ma_info));
203
204         while ((a = getopt(argc, argv, "dpf:P:")) != EOF)
205         {
206                 switch (a) {
207                 case 'f':
208                         filename = optarg;
209                         break;
210                 case 'p':
211                         do_proto = 1;
212                         break;
213                 case 'd':
214                         dont_decode = 0;
215                         break;
216                 case 'P':
217                         ma.printme = optarg;
218                 }
219         }
220         StartLibCitadel(8);
221
222         if (filename == NULL) {
223                 printf("Filename requried! -f\n");
224                 return 1;
225         }
226         fd = open(filename, 0);
227         if (fd < 0) {
228                 printf("Error opening file [%s] %d [%s]\n", filename, errno, strerror(errno));
229                 return 1;
230         }
231         if (fstat(fd, &statbuf) == -1) {
232                 printf("Error stating file [%s] %d [%s]\n", filename, errno, strerror(errno));
233                 return 1;
234         }
235         MimeBuf = NewStrBufPlain(NULL, statbuf.st_size + 1);
236         if (StrBufReadBLOB(MimeBuf, &fd, 1, statbuf.st_size, &Err) < 0) {
237                 printf("Error reading file [%s] %d [%s] [%s]\n", filename, errno, strerror(errno), Err);
238                 FreeStrBuf(&MimeBuf);
239                 return 1;
240         }
241         MimeLen = StrLength(MimeBuf);
242         MimeStr = SmashStrBuf(&MimeBuf);
243
244         if (ma.printme == NULL)
245                 mime_parser(MimeStr, MimeStr + MimeLen,
246                             (do_proto ? *list_this_part : NULL),
247                             (do_proto ? *list_this_pref : NULL),
248                             (do_proto ? *list_this_suff : NULL),
249                             (void *)&ma, dont_decode);
250         else 
251                 mime_parser(MimeStr, MimeStr + MimeLen,
252                             *mime_download, NULL, NULL, (void *)&ma, dont_decode);
253
254         free(MimeStr);
255         return 0;
256 }