Add possibility to trigger the mimeparser internal encoding-decoder
[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         int chosen_pref;        /* Chosen part preference level (lower is better) */
26         int use_fo_hooks;       /* Use fixed output hooks */
27         int dont_decode;        /* should we call the decoder or not? */
28 };
29
30
31 /*
32  * Callback function for mime parser that simply lists the part
33  */
34 void list_this_part(char *name, 
35                     char *filename, 
36                     char *partnum, 
37                     char *disp,
38                     void *content, 
39                     char *cbtype, 
40                     char *cbcharset, 
41                     size_t length, 
42                     char *encoding,
43                     char *cbid, 
44                     void *cbuserdata)
45 {
46         struct ma_info *ma;
47         
48         ma = (struct ma_info *)cbuserdata;
49         if (ma->is_ma == 0) {
50                 printf("part=%s|%s|%s|%s|%s|%ld|%s|%s\n",
51                         name, 
52                         filename, 
53                         partnum, 
54                         disp, 
55                         cbtype, 
56                         (long)length, 
57                         cbid, 
58                         cbcharset);
59         }
60 }
61
62 /* 
63  * Callback function for multipart prefix
64  */
65 void list_this_pref(char *name, 
66                     char *filename, 
67                     char *partnum, 
68                     char *disp,
69                     void *content, 
70                     char *cbtype, 
71                     char *cbcharset, 
72                     size_t length, 
73                     char *encoding,
74                     char *cbid, 
75                     void *cbuserdata)
76 {
77         struct ma_info *ma;
78         
79         ma = (struct ma_info *)cbuserdata;
80         if (!strcasecmp(cbtype, "multipart/alternative")) {
81                 ++ma->is_ma;
82         }
83
84         if (ma->is_ma == 0) {
85                 printf("pref=%s|%s\n", partnum, cbtype);
86         }
87 }
88
89 /* 
90  * Callback function for multipart sufffix
91  */
92 void list_this_suff(char *name, 
93                     char *filename, 
94                     char *partnum, 
95                     char *disp,
96                     void *content, 
97                     char *cbtype, 
98                     char *cbcharset, 
99                     size_t length, 
100                     char *encoding,
101                     char *cbid, 
102                     void *cbuserdata)
103 {
104         struct ma_info *ma;
105         
106         ma = (struct ma_info *)cbuserdata;
107         if (ma->is_ma == 0) {
108                 printf("suff=%s|%s\n", partnum, cbtype);
109         }
110         if (!strcasecmp(cbtype, "multipart/alternative")) {
111                 --ma->is_ma;
112         }
113 }
114
115
116 /*
117  * Callback function for mime parser that opens a section for downloading
118  * /
119 void mime_download(char *name, 
120                    char *filename, 
121                    char *partnum, 
122                    char *disp,
123                    void *content, 
124                    char *cbtype, 
125                    char *cbcharset, 
126                    size_t length,
127                    char *encoding, 
128                    char *cbid, 
129                    void *cbuserdata)
130 {
131         int rv = 0;
132         FILE *download_fp;
133
134         /* Silently go away if there's already a download open. * /
135
136         if (
137                 (!IsEmptyStr(partnum) && (!strcasecmp(CC->download_desired_section, partnum)))
138         ||      (!IsEmptyStr(cbid) && (!strcasecmp(CC->download_desired_section, cbid)))
139         ) {
140                 download_fp = STDOUT;
141
142         
143                 rv = fwrite(content, length, 1, download_fp);
144                 fflush(CC->download_fp);
145                 rewind(CC->download_fp);
146         
147                 OpenCmdResult(filename, cbtype);
148         }
149 }
150 */
151
152
153 /*
154  * Callback function for mime parser that outputs a section all at once.
155  * We can specify the desired section by part number *or* content-id.
156  * /
157 void mime_spew_section(char *name, 
158                        char *filename, 
159                        char *partnum, 
160                        char *disp,
161                        void *content, 
162                        char *cbtype, 
163                        char *cbcharset, 
164                        size_t length,
165                        char *encoding, 
166                        char *cbid, 
167                        void *cbuserdata)
168 {
169         int *found_it = (int *)cbuserdata;
170
171         if (
172                 (!IsEmptyStr(partnum) && (!strcasecmp(CC->download_desired_section, partnum)))
173         ||      (!IsEmptyStr(cbid) && (!strcasecmp(CC->download_desired_section, cbid)))
174         ) {
175                 *found_it = 1;
176                 printf("%d %d|-1|%s|%s|%s\n",
177                         BINARY_FOLLOWS,
178                         (int)length,
179                         filename,
180                         cbtype,
181                         cbcharset
182                 );
183                 fwrite(STDOUT, content, length);
184         }
185 }
186
187 */
188
189
190
191
192 int main(int argc, char* argv[])
193 {
194         char a;
195         int fd;
196         char *filename = NULL;
197         struct stat statbuf;
198         const char *Err;
199
200         StrBuf *MimeBuf;
201         long MimeLen;
202         char *MimeStr;
203         struct ma_info ma;
204         int do_proto = 0;
205         int dont_decode = 1;
206
207         setvbuf(stdout, NULL, _IONBF, 0);
208
209
210         while ((a = getopt(argc, argv, "dpf:")) != EOF)
211         {
212                 switch (a) {
213                 case 'f':
214                         filename = optarg;
215                         break;
216                 case 'p':
217                         do_proto = 1;
218                         break;
219                 case 'd':
220                         dont_decode = 0;
221                         break;
222                 }
223         }
224         StartLibCitadel(8);
225
226         if (filename == NULL) {
227                 printf("Filename requried! -f\n");
228                 return 1;
229         }
230         fd = open(filename, 0);
231         if (fd < 0) {
232                 printf("Error opening file [%s] %d [%s]\n", filename, errno, strerror(errno));
233                 return 1;
234         }
235         if (fstat(fd, &statbuf) == -1) {
236                 printf("Error stating file [%s] %d [%s]\n", filename, errno, strerror(errno));
237                 return 1;
238         }
239         MimeBuf = NewStrBufPlain(NULL, statbuf.st_size + 1);
240         if (StrBufReadBLOB(MimeBuf, &fd, 1, statbuf.st_size, &Err) < 0) {
241                 printf("Error reading file [%s] %d [%s] [%s]\n", filename, errno, strerror(errno), Err);
242                 FreeStrBuf(&MimeBuf);
243                 return 1;
244         }
245         MimeLen = StrLength(MimeBuf);
246         MimeStr = SmashStrBuf(&MimeBuf);
247
248         memset(&ma, 0, sizeof(struct ma_info));
249
250         mime_parser(MimeStr, MimeStr + MimeLen,
251                     (do_proto ? *list_this_part : NULL),
252                     (do_proto ? *list_this_pref : NULL),
253                     (do_proto ? *list_this_suff : NULL),
254                     (void *)&ma, dont_decode);
255
256
257         free(MimeStr);
258         return 0;
259 }