rohrpost

A commandline mail client to change the world as we see it.
git clone git://r-36.net/rohrpost
Log | Files | Refs | LICENSE

commit 535143e5642d255782af28d9f6cce4521f275802
parent 82d4c902bfe337b2e91d09edd7a90ae0283da28c
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(-)

diff --git a/base64.c b/base64.c @@ -103,3 +103,9 @@ b64dec(char *istr, int *len) return ret; } +int +b64len(int len) +{ + return (len / 3) * 4 + (len % 3 > 0)? 4 : 0; +} + diff --git a/base64.h b/base64.h @@ -8,6 +8,7 @@ char *b64enc(char *str, int l); char *b64dec(char *str, int *len); +int b64len(int len); #endif diff --git a/ind.c b/ind.c @@ -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; diff --git a/ind.h b/ind.h @@ -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); diff --git a/meta.c b/meta.c @@ -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)) { + } } } diff --git a/mime.c b/mime.c @@ -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) { diff --git a/mime.h b/mime.h @@ -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); diff --git a/quote.c b/quote.c @@ -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';