--- /dev/null
+/*$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);
+}
+