1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
/*$Id: decodeHDR.c,v 1.2 1998/02/28 19:03:02 lindberg Exp $*/
/*$Name: ezmlm-idx-0313 $*/
#include "stralloc.h"
#include "strerr.h"
#include "error.h"
#include "case.h"
#include "byte.h"
#include "uint32.h"
#include "mime.h"
#include "errtxt.h"
static void die_nomem(fatal)
char *fatal;
{
strerr_die2x(111,fatal,ERR_NOMEM);
}
void decodeHDR(indata,n,outdata,charset,fatal)
char *indata;
unsigned int n;
stralloc *outdata;
char *charset;
char *fatal;
/* decodes indata depending on charset. May put '\n' and '\0' into out */
/* data and can take them as indata. */
{
unsigned int pos;
char *cp,*cpnext,*cpstart,*cpenc,*cptxt,*cpend,*cpafter;
cpnext = indata;
cpafter = cpnext + n;
cpstart = cpnext;
if (!stralloc_copys(outdata,"")) die_nomem(fatal);
if (!stralloc_ready(outdata,n)) die_nomem(fatal);
for (;;) {
cpstart = cpstart + byte_chr(cpstart,cpafter-cpstart,'=');
if (cpstart == cpafter)
break;
++cpstart;
if (*cpstart != '?')
continue;
++cpstart;
cpenc = cpstart + byte_chr(cpstart,cpafter-cpstart,'?');
if (cpenc == cpafter)
continue;
cpenc++;
cptxt = cpenc + byte_chr(cpenc,cpafter-cpenc,'?');
if (cptxt == cpafter)
continue;
cptxt++;
cpend = cptxt + byte_chr(cptxt,cpafter-cptxt,'?');
if (cpend == cpafter || *(cpend + 1) != '=')
continue;
/* We'll decode anything. On lists with many charsets, this may */
/* result in unreadable subjects, but that's the case even if */
/* no decoding is done. This way, the subject will be optimal */
/* for threading, but charset info is lost. We aim to correctly */
/* decode us-ascii and all iso-8859/2022 charsets. Exacly how */
/* these will be displayed depends on dir/charset. */
cp = cpnext;
/* scrap lwsp between coded strings */
while (*cp == ' ' || *cp == '\t')
cp++;
if (cp != cpstart - 2)
if (!stralloc_catb(outdata,cpnext, cpstart - cpnext - 2))
die_nomem(fatal);
cpnext = cp + 1;
cpstart = cpnext;
switch (*cpenc) {
case 'b':
case 'B':
pos = outdata->len;
decodeB(cptxt,cpend-cptxt,outdata,2,fatal);
cpnext = cpend + 2;
cpstart = cpnext;
break;
case 'q':
case 'Q':
decodeQ(cptxt,cpend-cptxt,outdata,fatal);
cpnext = cpend + 2;
cpstart = cpnext;
break;
default: /* shouldn't happen, but let's be reasonable */
cpstart = cpend + 2;
break;
}
}
if (!stralloc_catb(outdata,cpnext,indata-cpnext+n)) die_nomem(fatal);
}
|