X-Git-Url: https://git.distorted.org.uk/~mdw/ezmlm/blobdiff_plain/5b62e993b0af39700031c2875d7f6654e6a02850..f8beb284087c279acfb30506f5bb32baa4949b44:/decodeHDR.c diff --git a/decodeHDR.c b/decodeHDR.c new file mode 100644 index 0000000..4693d3d --- /dev/null +++ b/decodeHDR.c @@ -0,0 +1,92 @@ +/*$Id: decodeHDR.c,v 1.2 1998/02/28 19:03:02 lindberg Exp $*/ +/*$Name: ezmlm-idx-040 $*/ + +#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); +} +