removed StartLibCitadel()
[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                 char *decoded = NULL;
142                 size_t bytes_decoded;
143                 rc = mime_decode_now (content, 
144                                       length,
145                                       encoding,
146                                       &decoded,
147                                       &bytes_decoded);
148                 if (rc < 0) {
149                         printf("failed to decode content\n");
150                         return;
151                 }
152                 if (rc == 0){
153                         rc = write(STDOUT_FILENO, content, length);
154                 }
155                 else {
156                         rc = write(STDOUT_FILENO, decoded, bytes_decoded);
157                         free(decoded);
158                 }
159         }
160 }
161
162
163
164 /*
165  * Callback function for mime parser that outputs a section all at once.
166  * We can specify the desired section by part number *or* content-id.
167  * /
168 void mime_spew_section(char *name, 
169                        char *filename, 
170                        char *partnum, 
171                        char *disp,
172                        void *content, 
173                        char *cbtype, 
174                        char *cbcharset, 
175                        size_t length,
176                        char *encoding, 
177                        char *cbid, 
178                        void *cbuserdata)
179 {
180         int *found_it = (int *)cbuserdata;
181
182         if (
183                 (!IsEmptyStr(partnum) && (!strcasecmp(CC->download_desired_section, partnum)))
184         ||      (!IsEmptyStr(cbid) && (!strcasecmp(CC->download_desired_section, cbid)))
185         ) {
186                 *found_it = 1;
187                 printf("%d %d|-1|%s|%s|%s\n",
188                         BINARY_FOLLOWS,
189                         (int)length,
190                         filename,
191                         cbtype,
192                         cbcharset
193                 );
194                 fwrite(STDOUT, content, length);
195         }
196 }
197
198 */
199
200
201
202
203 int main(int argc, char* argv[])
204 {
205         char a;
206         int fd;
207         char *filename = NULL;
208         struct stat statbuf;
209         const char *Err;
210
211         StrBuf *MimeBuf;
212         long MimeLen;
213         char *MimeStr;
214         struct ma_info ma;
215         int do_proto = 0;
216         int dont_decode = 1;
217
218         setvbuf(stdout, NULL, _IONBF, 0);
219         memset(&ma, 0, sizeof(struct ma_info));
220
221         while ((a = getopt(argc, argv, "dpf:P:")) != EOF)
222         {
223                 switch (a) {
224                 case 'f':
225                         filename = optarg;
226                         break;
227                 case 'p':
228                         do_proto = 1;
229                         break;
230                 case 'd':
231                         dont_decode = 0;
232                         break;
233                 case 'P':
234                         ma.printme = optarg;
235                 }
236         }
237
238         if (filename == NULL) {
239                 printf("Filename requried! -f\n");
240                 return 1;
241         }
242         fd = open(filename, 0);
243         if (fd < 0) {
244                 printf("Error opening file [%s] %d [%s]\n", filename, errno, strerror(errno));
245                 return 1;
246         }
247         if (fstat(fd, &statbuf) == -1) {
248                 printf("Error stating file [%s] %d [%s]\n", filename, errno, strerror(errno));
249                 return 1;
250         }
251         MimeBuf = NewStrBufPlain(NULL, statbuf.st_size + 1);
252         if (StrBufReadBLOB(MimeBuf, &fd, 1, statbuf.st_size, &Err) < 0) {
253                 printf("Error reading file [%s] %d [%s] [%s]\n", filename, errno, strerror(errno), Err);
254                 FreeStrBuf(&MimeBuf);
255                 return 1;
256         }
257         MimeLen = StrLength(MimeBuf);
258         MimeStr = SmashStrBuf(&MimeBuf);
259
260         if (ma.printme == NULL)
261                 mime_parser(MimeStr, MimeStr + MimeLen,
262                             (do_proto ? *list_this_part : NULL),
263                             (do_proto ? *list_this_pref : NULL),
264                             (do_proto ? *list_this_suff : NULL),
265                             (void *)&ma, dont_decode);
266         else 
267                 mime_parser(MimeStr, MimeStr + MimeLen,
268                             *mime_download, NULL, NULL, (void *)&ma, dont_decode);
269
270         free(MimeStr);
271         return 0;
272 }