Back to index

libcitadel  8.12
mimeparser_test.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007 #include <dirent.h>
00008 #include <errno.h>
00009 
00010 #include <fcntl.h>
00011 
00012 #include <unistd.h>
00013 #include <stddef.h>
00014 
00015 
00016 #include "../lib/libcitadel.h"
00017 
00018 /* shamelesly copied from msgbase.h */
00019 struct ma_info {
00020        int is_ma;           /* Set to 1 if we are using this stuff */
00021        int freeze;          /* Freeze the replacement chain because we're
00022                              * digging through a subsection */
00023        int did_print;              /* One alternative has been displayed */
00024        char chosen_part[128];      /* Which part of a m/a did we choose? */
00025        const char *printme;
00026        int chosen_pref;     /* Chosen part preference level (lower is better) */
00027        int use_fo_hooks;    /* Use fixed output hooks */
00028        int dont_decode;        /* should we call the decoder or not? */
00029 };
00030 
00031 
00032 /*
00033  * Callback function for mime parser that simply lists the part
00034  */
00035 static void list_this_part(char *name, 
00036                         char *filename, 
00037                         char *partnum, 
00038                         char *disp,
00039                         void *content, 
00040                         char *cbtype, 
00041                         char *cbcharset, 
00042                         size_t length, 
00043                         char *encoding,
00044                         char *cbid, 
00045                         void *cbuserdata)
00046 {
00047        struct ma_info *ma;
00048        
00049        ma = (struct ma_info *)cbuserdata;
00050        if (ma->is_ma == 0) {
00051               printf("part=%s|%s|%s|%s|%s|%ld|%s|%s\n",
00052                      name, 
00053                      filename, 
00054                      partnum, 
00055                      disp, 
00056                      cbtype, 
00057                      (long)length, 
00058                      cbid, 
00059                      cbcharset);
00060        }
00061 }
00062 
00063 /* 
00064  * Callback function for multipart prefix
00065  */
00066 static void list_this_pref(char *name, 
00067                         char *filename, 
00068                         char *partnum, 
00069                         char *disp,
00070                         void *content, 
00071                         char *cbtype, 
00072                         char *cbcharset, 
00073                         size_t length, 
00074                         char *encoding,
00075                         char *cbid, 
00076                         void *cbuserdata)
00077 {
00078        struct ma_info *ma;
00079        
00080        ma = (struct ma_info *)cbuserdata;
00081        if (!strcasecmp(cbtype, "multipart/alternative")) {
00082               ++ma->is_ma;
00083        }
00084 
00085        if (ma->is_ma == 0) {
00086               printf("pref=%s|%s\n", partnum, cbtype);
00087        }
00088 }
00089 
00090 /* 
00091  * Callback function for multipart sufffix
00092  */
00093 static void list_this_suff(char *name, 
00094                         char *filename, 
00095                         char *partnum, 
00096                         char *disp,
00097                         void *content, 
00098                         char *cbtype, 
00099                         char *cbcharset, 
00100                         size_t length, 
00101                         char *encoding,
00102                         char *cbid, 
00103                         void *cbuserdata)
00104 {
00105        struct ma_info *ma;
00106        
00107        ma = (struct ma_info *)cbuserdata;
00108        if (ma->is_ma == 0) {
00109               printf("suff=%s|%s\n", partnum, cbtype);
00110        }
00111        if (!strcasecmp(cbtype, "multipart/alternative")) {
00112               --ma->is_ma;
00113        }
00114 }
00115 
00116 
00117 /*
00118  * Callback function for mime parser that opens a section for downloading
00119  */
00120 static void mime_download(char *name, 
00121                        char *filename, 
00122                        char *partnum, 
00123                        char *disp,
00124                        void *content, 
00125                        char *cbtype, 
00126                        char *cbcharset, 
00127                        size_t length,
00128                        char *encoding, 
00129                        char *cbid, 
00130                        void *cbuserdata)
00131 {
00132        int rc = 0;
00133 
00134        /* Silently go away if there's already a download open. */
00135 
00136        struct ma_info *ma;
00137        
00138        ma = (struct ma_info *)cbuserdata;
00139 
00140        if ((!IsEmptyStr(partnum) && (!strcasecmp(ma->printme, partnum)))) {
00141               char *decoded = NULL;
00142               size_t bytes_decoded;
00143               rc = mime_decode_now (content, 
00144                                   length,
00145                                   encoding,
00146                                   &decoded,
00147                                   &bytes_decoded);
00148               if (rc < 0) {
00149                      printf("failed to decode content\n");
00150                      return;
00151               }
00152               if (rc == 0){
00153                      rc = write(STDOUT_FILENO, content, length);
00154               }
00155               else {
00156                      rc = write(STDOUT_FILENO, decoded, bytes_decoded);
00157                      free(decoded);
00158               }
00159        }
00160 }
00161 
00162 
00163 
00164 /*
00165  * Callback function for mime parser that outputs a section all at once.
00166  * We can specify the desired section by part number *or* content-id.
00167  * /
00168 void mime_spew_section(char *name, 
00169                      char *filename, 
00170                      char *partnum, 
00171                      char *disp,
00172                      void *content, 
00173                      char *cbtype, 
00174                      char *cbcharset, 
00175                      size_t length,
00176                      char *encoding, 
00177                      char *cbid, 
00178                      void *cbuserdata)
00179 {
00180        int *found_it = (int *)cbuserdata;
00181 
00182        if (
00183               (!IsEmptyStr(partnum) && (!strcasecmp(CC->download_desired_section, partnum)))
00184        ||     (!IsEmptyStr(cbid) && (!strcasecmp(CC->download_desired_section, cbid)))
00185        ) {
00186               *found_it = 1;
00187               printf("%d %d|-1|%s|%s|%s\n",
00188                      BINARY_FOLLOWS,
00189                      (int)length,
00190                      filename,
00191                      cbtype,
00192                      cbcharset
00193               );
00194               fwrite(STDOUT, content, length);
00195        }
00196 }
00197 
00198 */
00199 
00200 
00201 
00202 
00203 int main(int argc, char* argv[])
00204 {
00205        char a;
00206        int fd;
00207        char *filename = NULL;
00208        struct stat statbuf;
00209        const char *Err;
00210 
00211        StrBuf *MimeBuf;
00212        long MimeLen;
00213        char *MimeStr;
00214        struct ma_info ma;
00215        int do_proto = 0;
00216        int dont_decode = 1;
00217 
00218        setvbuf(stdout, NULL, _IONBF, 0);
00219        memset(&ma, 0, sizeof(struct ma_info));
00220 
00221        while ((a = getopt(argc, argv, "dpf:P:")) != EOF)
00222        {
00223               switch (a) {
00224               case 'f':
00225                      filename = optarg;
00226                      break;
00227               case 'p':
00228                      do_proto = 1;
00229                      break;
00230               case 'd':
00231                      dont_decode = 0;
00232                      break;
00233               case 'P':
00234                      ma.printme = optarg;
00235               }
00236        }
00237        StartLibCitadel(8);
00238 
00239        if (filename == NULL) {
00240               printf("Filename requried! -f\n");
00241               return 1;
00242        }
00243        fd = open(filename, 0);
00244        if (fd < 0) {
00245               printf("Error opening file [%s] %d [%s]\n", filename, errno, strerror(errno));
00246               return 1;
00247        }
00248        if (fstat(fd, &statbuf) == -1) {
00249               printf("Error stating file [%s] %d [%s]\n", filename, errno, strerror(errno));
00250               return 1;
00251        }
00252        MimeBuf = NewStrBufPlain(NULL, statbuf.st_size + 1);
00253        if (StrBufReadBLOB(MimeBuf, &fd, 1, statbuf.st_size, &Err) < 0) {
00254               printf("Error reading file [%s] %d [%s] [%s]\n", filename, errno, strerror(errno), Err);
00255               FreeStrBuf(&MimeBuf);
00256               return 1;
00257        }
00258        MimeLen = StrLength(MimeBuf);
00259        MimeStr = SmashStrBuf(&MimeBuf);
00260 
00261        if (ma.printme == NULL)
00262               mime_parser(MimeStr, MimeStr + MimeLen,
00263                          (do_proto ? *list_this_part : NULL),
00264                          (do_proto ? *list_this_pref : NULL),
00265                          (do_proto ? *list_this_suff : NULL),
00266                          (void *)&ma, dont_decode);
00267        else 
00268               mime_parser(MimeStr, MimeStr + MimeLen,
00269                          *mime_download, NULL, NULL, (void *)&ma, dont_decode);
00270 
00271        free(MimeStr);
00272        return 0;
00273 }