Back to index

courier  0.68.2
rfc2045decodemsgtoutf8.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2010-2011 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 #include      "rfc2045.h"
00007 #include      "rfc822/rfc822.h"
00008 #include      <ctype.h>
00009 #include      <unistd.h>
00010 #include      <string.h>
00011 
00012 
00013 
00014 struct doconvtoutf8_info {
00015 
00016        struct rfc2045_decodemsgtoutf8_cb *callback;
00017 
00018        int err_flag;
00019 };
00020 
00021 static void doconvtoutf8_write(const char *p, size_t n,
00022                             void *void_arg)
00023 {
00024        struct doconvtoutf8_info *ptr=
00025               (struct doconvtoutf8_info *)void_arg;
00026 
00027        if (n && ptr->err_flag == 0)
00028               ptr->err_flag=(*ptr->callback->output_func)
00029                      (p, n, ptr->callback->arg);
00030 }
00031 
00032 static void doconvtoutf8_error(const char *p, int n,
00033                             void *void_arg)
00034 {
00035        struct doconvtoutf8_info *ptr=(struct doconvtoutf8_info *)void_arg;
00036 
00037        ptr->err_flag= -1;
00038 }
00039 
00040 static int doconvtoutf8_rfc822hdr(const char *header,
00041                               const char *value,
00042                               struct rfc2045_decodemsgtoutf8_cb *callback)
00043 {
00044        struct doconvtoutf8_info info;
00045 
00046        info.err_flag=0;
00047        info.callback=callback;
00048 
00049        if (callback->headerfilter_func &&
00050            (*callback->headerfilter_func)(header, value, callback->arg) == 0)
00051               return 0;
00052 
00053        if ((callback->flags & RFC2045_DECODEMSG_NOHEADERNAME) == 0)
00054        {
00055               doconvtoutf8_write(header, strlen(header), &info);
00056               doconvtoutf8_write(": ", 2, &info);
00057        }
00058        rfc822_display_hdrvalue(header, value, "utf-8", 
00059                             doconvtoutf8_write,
00060                             doconvtoutf8_error,
00061                             &info);
00062        doconvtoutf8_write("\n", 1, &info);
00063        if (callback->headerdone_func && info.err_flag == 0)
00064        {
00065               int rc=(*callback->headerdone_func)(header, callback->arg);
00066 
00067               if (rc)
00068                      info.err_flag=rc;
00069        }
00070 
00071        return info.err_flag;
00072 }
00073 
00074 static int decode_handler(const char *p, size_t n, void *voidarg)
00075 {
00076        const struct doconvtoutf8_info *ptr=
00077               (const struct doconvtoutf8_info *)voidarg;
00078 
00079        int rc=0;
00080 
00081        if (n)
00082               rc=(*ptr->callback->output_func)(p, n, ptr->callback->arg);
00083 
00084        return rc;
00085 }
00086 
00087 int rfc2045_decodemsgtoutf8(struct rfc2045src *src,
00088                          struct rfc2045 *p,
00089                          struct rfc2045_decodemsgtoutf8_cb *callback)
00090 {
00091        struct rfc2045headerinfo *hi;
00092        int rc;
00093 
00094        hi=rfc2045header_start(src, p);
00095 
00096        if (hi)
00097        {
00098               char *header;
00099               char *value;
00100 
00101               while (rfc2045header_get(hi, &header, &value,
00102                                     RFC2045H_NOLC |
00103                                     RFC2045H_KEEPNL) == 0 && header)
00104               {
00105                      if (callback->flags & RFC2045_DECODEMSG_NOHEADERS)
00106                             continue;
00107 
00108                      if (doconvtoutf8_rfc822hdr(header, value,
00109                                              callback) < 0)
00110                             return -1;
00111               }
00112               rfc2045header_end(hi);
00113        }
00114 
00115        if (p->firstpart)
00116        {
00117               for (p=p->firstpart; p; p=p->next)
00118               {
00119                      if (!p->isdummy)
00120                      {
00121                             if ((rc=rfc2045_decodemsgtoutf8(src, p,
00122                                                         callback))
00123                                 != 0)
00124                                    return rc;
00125                      }
00126               }
00127        }
00128        else
00129        {
00130               const char *content_type;
00131               const char *transfer_encoding;
00132               const char *charset;
00133               struct doconvtoutf8_info info;
00134 
00135               info.callback=callback;
00136 
00137               rfc2045_mimeinfo(p, &content_type, &transfer_encoding,
00138                              &charset);
00139 
00140               if (strncmp(content_type, "text/", 5) == 0 &&
00141                   (callback->flags & RFC2045_DECODEMSG_NOBODY) == 0 &&
00142                   (rc=rfc2045_decodetextmimesection(src, p, "utf-8", NULL,
00143                                                 decode_handler,
00144                                                 &info)) != 0)
00145                      return rc;
00146        }
00147        return 0;
00148 }