#ifndef _QUOTED_PRINTABLE_H_
#define _QUOTED_PRINTABLE_H_
void quoted_printable_decode(const unsigned char *src, size_t src_size,
unsigned char* dest);
int is_quoted_printable(char* instr);
#endif
#include <stdio.h>
#include <string.h>
#include "quoted-printable.h"
void quoted_printable_decode(const unsigned char *src, size_t src_size,
unsigned char* dest);
#define QP_IS_TRAILING_SPACE(c) \
((c) == ' ' || (c) == '\t')
int hex_to_binary(const char *data, char *dest)
{
int value, len;
while (*data != '\0') {
if (*data >= '0' && *data <= '9')
value = (*data - '0') << 4;
else if (*data >= 'a' && *data <= 'f')
value = (*data - 'a' + 10) << 4;
else if (*data >= 'A' && *data <= 'F')
value = (*data - 'A' + 10) << 4;
else
return -1;
data++;
if (*data >= '0' && *data <= '9')
value |= *data - '0';
else if (*data >= 'a' && *data <= 'f')
value |= *data - 'a' + 10;
else if (*data >= 'A' && *data <= 'F')
value |= *data - 'A' + 10;
else
return -1;
len = strlen(dest);
dest[len] = value;
data++;
}
return 0;
}
void quoted_printable_decode(const unsigned char *src, size_t src_size,
unsigned char* dest)
{
char hexbuf[3];
size_t src_pos, pos, next;
hexbuf[2] = '\0';
next = 0;
for (src_pos = 0; src_pos < src_size; src_pos++) {
if (src[src_pos] != '=' && src[src_pos] != '\n')
continue;
if (src[src_pos] == '\n') {
/* drop trailing whitespace */
pos = src_pos;
if (pos > 0 && src[pos-1] == '\r')
pos--;
while (pos > 0 && QP_IS_TRAILING_SPACE(src[pos-1]))
pos--;
strncat(dest, src + next, pos - next);
next = src_pos+1;
strncat(dest, "\r\n", 2);
continue;
}
/* '=' */
strncat(dest, src + next, src_pos - next);
next = src_pos;
if (src_pos+1 >= src_size)
break;
if (src[src_pos+1] == '\n') {
/* =\n -> skip both */
src_pos++;
next += 2;
continue;
}
if (src_pos+2 >= src_size)
break;
if (src[src_pos+1] == '\r' && src[src_pos+2] == '\n') {
/* =\r\n -> skip both */
src_pos += 2;
next += 3;
continue;
}
/* =<hex> */
hexbuf[0] = src[src_pos+1];
hexbuf[1] = src[src_pos+2];
if (hex_to_binary(hexbuf, dest) == 0) {
src_pos += 2;
next = src_pos + 1;
} else {
/* non-hex data, show as-is */
next = src_pos;
}
}
if (src_pos == src_size) {
/* add everything but trailing spaces */
if (src_pos > 0 && src[src_pos-1] == '\r')
src_pos--;
while (src_pos > 0 && QP_IS_TRAILING_SPACE(src[src_pos-1]))
src_pos--;
strncat(dest, src + next, src_pos - next);
next = src_pos;
}
}
int is_quoted_printable(char* instr)
{
int ret;
ret = strcasestr(instr, "quoted-printable");
if(ret == NULL) return 0;
return 1;
}
#if 1
// for test
int main(int argc, char argv[])
{
//char* instr = "=EC=9E=A5=EB=AA=A8=EB=8B=98";
char* instr =
"=20=EA=B7=B8=EB=A3=B9=EC=97=86=EC=9D=8C=0A=EC=A0=84=ED=99=94=EB=B2=88"
"=ED=98=B8=31=3A=20=30=31=31=2D=39=34=34=37=2D=32=33=35=38=0A=EB=8C=80"
"=ED=91=9C=EB=B2=88=ED=98=B8=3A=20=30=0A=EC=A0=84=ED=99=94=EC=A2=85=EB";
char outbuf[200] = {0, };
quoted_printable_decode(instr, strlen(instr), outbuf);
printf("outbuf[%s]\n", outbuf);
return 1;
}
#endif