tAdding some header encoding and fixing qpenc. - rohrpost - A commandline mail client to change the world as we see it.
 (HTM) git clone git://r-36.net/rohrpost
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 535143e5642d255782af28d9f6cce4521f275802
 (DIR) parent 82d4c902bfe337b2e91d09edd7a90ae0283da28c
 (HTM) Author: Christoph Lohmann <20h@r-36.net>
       Date:   Sun,  1 Jan 2012 18:09:49 +0100
       
       Adding some header encoding and fixing qpenc.
       
       Diffstat:
         base64.c                            |       6 ++++++
         base64.h                            |       1 +
         ind.c                               |      39 +++++++++++++++++++++++++++++++
         ind.h                               |       3 +++
         meta.c                              |       4 +++-
         mime.c                              |      54 +++++++++++++++++++++++++++++++
         mime.h                              |       1 +
         quote.c                             |       7 +++++++
       
       8 files changed, 114 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/base64.c b/base64.c
       t@@ -103,3 +103,9 @@ b64dec(char *istr, int *len)
                return ret;
        }
        
       +int
       +b64len(int len)
       +{
       +        return (len / 3) * 4 + (len % 3 > 0)? 4 : 0;
       +}
       +
 (DIR) diff --git a/base64.h b/base64.h
       t@@ -8,6 +8,7 @@
        
        char *b64enc(char *str, int l);
        char *b64dec(char *str, int *len);
       +int b64len(int len);
        
        #endif
        
 (DIR) diff --git a/ind.c b/ind.c
       t@@ -466,6 +466,45 @@ strncsh(char *p, char *chars)
        }
        
        char *
       +strrlncsh(char *p, char *chars, int limit)
       +{
       +        char *np;
       +
       +        np = &p[limit-1];
       +        for(; !strchr(chars, np[0] && p != np); np--);
       +
       +        return np;
       +}
       +
       +int
       +strisascii(char *str)
       +{
       +        int len, i;
       +
       +        len = strlen(str);
       +        for (i = 0; i < len; i++)
       +                if(!isascii(str[i]))
       +                        return 0;
       +        return 1;
       +}
       +
       +char *
       +findlimitws(char *str, int limit)
       +{
       +        int i, len;
       +        char *ptr;
       +
       +        len = strlen(str);
       +        if (len < limit)
       +                return NULL;
       +
       +        ptr = strrlncsh(str, "\t\r\v\f ", limit);
       +        if (ptr == str)
       +                return &str[limit-1];
       +        return ptr;
       +}
       +
       +char *
        mktmpfile(char *prefix, int *fd)
        {
                char *name;
 (DIR) diff --git a/ind.h b/ind.h
       t@@ -46,6 +46,9 @@ char *sgets(char *s, int size, char **p);
        char *sgetuntil(char *str, char **p, char *max, int *len);
        char *strcsh(char *p, char *chars);
        char *strncsh(char *p, char *chars);
       +char *strrlncshr(char *p, char *chars);
       +int strisascii(char *str);
       +char *findlimitws(char *str, int limit);
        
        char *mktmpfile(char *prefix, int *fd);
        
 (DIR) diff --git a/meta.c b/meta.c
       t@@ -21,9 +21,11 @@ meta_t *
        meta_headers2mime(meta_t *meta)
        {
                llistelem_t *param, *header;
       +        char *enc;
        
                forllist(meta->hdrs, header) {
       -                if(
       +                if(!strisascii(header->value)) {
       +                }
                }
        }
        
 (DIR) diff --git a/mime.c b/mime.c
       t@@ -330,6 +330,60 @@ mime_decodeparam(char *value)
                return str;
        }
        
       +char *
       +mime_encodeheader(char *header, char *value)
       +{
       +        char *ret, *b64, *p, *mp, *str;
       +        int len, hlen, lmax, isascii = 0, firstline;
       +
       +        /*
       +         * RFC 2047:
       +         *  One encoded word should be at max. 75 characters.
       +         *  One encoded line is limited to 76 characters.
       +         */
       +        hlen = strlen(header) + 2;
       +        if (strisascii(value)) {
       +                isascii = 1;
       +                lmax = 75 - hlen;
       +        } else {
       +                lmax = 63 - hlen;
       +        }
       +        slen = strlen(value);
       +
       +        ret = NULL;
       +        for (p = value, firstline = 0; slen > 0; slen -= lmax, p = mp) {
       +                if (firstline == 1) {
       +                        lmax += hlen;
       +                        firstline++;
       +                }
       +
       +                mp = findlimitws(p, lmax);
       +                if (mp == NULL) {
       +                        str = memdupz(p, slen);
       +                } else {
       +                        str = memdupz(p, mp - p);
       +                }
       +
       +                if (!isascii) {
       +                        b64 = b64enc(str, strlen(str));
       +                        free(str);
       +                        mp = smprintf("=?UTF-8?b?%s?=", b64);
       +                        free(b64);
       +                        str = mp;
       +                }
       +
       +                if (ret != NULL) {
       +                        mp = smprintf("%s %s", ret, str);
       +                        free(ret);
       +                        ret = mp;
       +                } else {
       +                        ret = smprintf("%s", str);
       +                }
       +        }
       +
       +        return ret;
       +}
       +
        int
        mime_paramsort(llistelem_t *elem1, llistelem_t *elem2)
        {
 (DIR) diff --git a/mime.h b/mime.h
       t@@ -37,6 +37,7 @@ char *mime_decodeheaderext(char *value);
        int mime_isextws(char *str, int len);
        char *mime_decodeheader(char *value);
        char *mime_decodeparam(char *value);
       +char *mime_encodeheader(char *header, char *value);
        int mime_paramsort(llistelem_t *elem1, llistelem_t *elem2);
        llist_t *mime_sanitizeparams(llist_t *phdr);
        
 (DIR) diff --git a/quote.c b/quote.c
       t@@ -46,6 +46,13 @@ qpenc(char *str, int len, int ishdr)
                                        snprintf(add, sizeof(add), "=%02x",
                                                        str[i] & 0xFF);
                                        break;
       +                        case '\n':
       +                                if (i > 0 && strchr("\t\r\v\f", str[i-1])) {
       +                                        add[0] = '=';
       +                                        add[1] = str[i];
       +                                        add[2] = '\0';
       +                                        break;
       +                                }
                                default:
                                        add[0] = str[i];
                                        add[1] = '\0';