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:
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';