RFC 2047 defines
Examples:
Subject: =?iso-8859-1?B?zvLi5fI6ICAgICAgTVBMQUIzLjQw?=
Subject: =?iso-8859-1?B?zvLi5fI6ICAgICAgUElDcyBhbmQgYmF0dGVyeS1iYWNrdXAgU1
JBTQ==?=
Subject: =?iso-8859-1?Q?=CE=F2=E2=E5=F2:______Re:_PCB_AutoRouting_=28is_it
_smart_w?=
ay ? / really Dumb )
Subject: Re: [PIC]: RSA =?iso-8859-1?Q?encryption=B7=B7?=
Subject: [PICLIST] =?Iso-8859-1?Q?[ot]:_Strain_Gauges=3F?=
Subject: [PICLIST] =?iso-8859-1?Q?_Re:_=5BPIC=5D:_RSA_encryption=B7=B7?=
Subject: [PICLIST] =?iso-8859-1?Q?=5BEE=5D:TV_&_video_IC=B4s_!!?=
Subject: [PICLIST] =?iso-8859-1?Q?=5BOT=5D:Scales_&_balances=B7?=
see also:
sample code:
iso8859.pl
/*
** RFC 2047 defines MIME extensions for mail headers.
**
** This function decodes that into binary/8bit data.
**
** Example:
** =?iso-8859-1?q?I'm_called_?= =?iso-8859-1?q?Daniel?=
**
** Should result in "I'm called Daniel", but:
**
** =?iso-8859-1?q?I'm_called?= Daniel
**
** Should result in "I'm called Daniel" too.
**
** Returns the newly allcated string, or the previous if nothing changed
*/
static char *mdecodeRFC2047(char *string, int length)
{
char *iptr = string;
char *oldptr;
char *storage = (char *)emalloc(length + 1);
char *output = storage;
char charset[129];
char encoding[33];
char blurb[129];
char equal;
int value;
char didanything = FALSE;
while (*iptr) {
if (!strncmp(iptr, "=?", 2) &&
(3 == sscanf(iptr + 2, "%128[^?]?%32[^?]?%128[^ ]",
charset, encoding, blurb))) {
/* This is a full, valid 'encoded-word'. Decode! */
char *ptr = blurb;
ptr = strstr(blurb, "?=");
if (ptr) {
*ptr = 0;
}
else {
*output++ = *iptr++;
/* it wasn't a real encoded-word */
continue;
}
ptr = blurb;
didanything = TRUE; /* yes, we decode something */
/* we could've done this with a %n in the sscanf, but we know all
sscanfs don't grok that */
iptr +=
2 + strlen(charset) + 1 + strlen(encoding) + 1 +
strlen(blurb) + 2;
if (!strcasecmp("q", encoding)) {
/* quoted printable decoding */
for (; *ptr; ptr++) {
switch (*ptr) {
case '=':
sscanf(ptr + 1, "%02X", &value);
*output++ = value;
ptr += 2;
break;
case '_':
*output++ = ' ';
break;
default:
*output++ = *ptr;
break;
}
}
}
else if (!strcasecmp("b", encoding)) {
/* base64 decoding */
int len;
base64Decode(ptr, output, &len);
output += len - 1;
}
else {
/* unsupported encoding type */
strcpy(output, "<unknown>");
output += 9;
}
oldptr = iptr; /* save start position */
while (*iptr && isspace(*iptr))
iptr++; /* pass all whitespaces */
/* if this is an encoded word here, we should skip the passed
whitespaces. If it isn't an encoded-word, we should include the
whitespaces in the output. */
if (!strncmp(iptr, "=?", 2) &&
(4 == sscanf(iptr + 2, "%128[^?]?%32[^?]?%128[^?]?%c",
charset, encoding, blurb, &equal)) &&
('=' == equal)) {
continue; /* this IS an encoded-word, continue from here */
}
else
/* this IS NOT an encoded-word, move back to the first whitespace */
iptr = oldptr;
}
else
*output++ = *iptr++;
}
*output = 0;
if (didanything) {
/* this check prevents unneccessary strsav() calls if not needed */
free(string); /* free old memory */
#if DEBUG_PARSE
/* debug display */
printf("NEW: %s\n", storage);
{
unsigned char *f;
puts("NEW:");
for (f = storage; f < output; f++) {
if (isgraph(*f))
printf("%c", *f);
else
printf("%02X", (unsigned char)*f);
}
puts("");
}
#endif
return storage; /* return new */
}
else {
free(storage);
return string;
}
}