* Handle display of RFC2047-encoded subjects and senders by converting
authorArt Cancro <ajc@citadel.org>
Fri, 22 Jul 2005 03:40:22 +0000 (03:40 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 22 Jul 2005 03:40:22 +0000 (03:40 +0000)
  them to UTF-8 (all WebCit pages are output as UTF-8).  Resolves bug #136.

webcit/ChangeLog
webcit/messages.c

index 86b69bcedd9b8e6f79afb5bc84098ebd44311133..125fb66b7b20f48e5408dd686669a83e784c209c 100644 (file)
@@ -1,4 +1,8 @@
 $Log$
+Revision 619.29  2005/07/22 03:40:22  ajc
+* Handle display of RFC2047-encoded subjects and senders by converting
+  them to UTF-8 (all WebCit pages are output as UTF-8).  Resolves bug #136.
+
 Revision 619.28  2005/07/20 04:26:24  ajc
 * Detect libiconv on the host system and link it in if present.
 * If libiconv is present, convert foreign charsets to UTF-8 on the fly
@@ -2724,3 +2728,4 @@ Sun Dec  6 19:50:55 EST 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
 
 1998-12-03 Nathan Bryant <bryant@cs.usm.maine.edu>
        * webserver.c: warning fix
+
index b7118d608e619c028b05843f293b16021b2485a8..c20ebc455e8b621317297b60f0744b14a9423979 100644 (file)
@@ -42,6 +42,74 @@ struct addrbookent {
 };
 
 
+
+#ifdef HAVE_ICONV
+/* Handle subjects with RFC2047 encoding, such as:
+ * =?koi8-r?B?78bP0s3Mxc7JxSDXz9rE1dvO2c3JINvB0sHNySDP?=
+ */
+void utf8ify_rfc822_string(char *buf) {
+       char *start, *end;
+       char newbuf[1024];
+       char charset[128];
+       char encoding[16];
+       char istr[1024];
+       iconv_t ic = (iconv_t)(-1) ;
+       char *ibuf;                   /* Buffer of characters to be converted */
+       char *obuf;                   /* Buffer for converted characters      */
+       size_t ibuflen;               /* Length of input buffer               */
+       size_t obuflen;               /* Length of output buffer              */
+       char *isav;                   /* Saved pointer to input buffer        */
+       char *osav;                   /* Saved pointer to output buffer       */
+
+       while (start=strstr(buf, "=?"), end=strstr(buf, "?="),
+               ((start != NULL) && (end != NULL) && (end > start)) )
+       {
+               extract_token(charset, start, 1, '?', sizeof charset);
+               extract_token(encoding, start, 2, '?', sizeof encoding);
+               extract_token(istr, start, 3, '?', sizeof istr);
+
+               strcpy(start, "");
+               ++end;
+               ++end;
+
+               ibuf = malloc(1024);
+               isav = ibuf;
+               if (!strcasecmp(encoding, "B")) {       /* base64 */
+                       ibuflen = CtdlDecodeBase64(ibuf, istr, strlen(istr));
+               }
+               else if (!strcasecmp(encoding, "Q")) {  /* quoted-printable */
+                       ibuflen = CtdlDecodeQuotedPrintable(ibuf, istr, strlen(istr));
+               }
+               else {
+                       strcpy(ibuf, istr);             /* huh? */
+                       ibuflen = strlen(istr);
+               }
+
+               ic = iconv_open("UTF-8", charset);
+               if (ic != (iconv_t)(-1) ) {
+                       obuf = malloc(1024);
+                       obuflen = 1024;
+                       obuf = (char *) malloc(obuflen);
+                       osav = obuf;
+                       iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
+                       osav[1024-obuflen] = 0;
+                       snprintf(newbuf, sizeof newbuf, "%s%s%s", buf, osav, end);
+                       strcpy(buf, newbuf);
+                       free(osav);
+                       iconv_close(ic);
+               }
+               else {
+                       snprintf(newbuf, sizeof newbuf, "%s(unreadable)%s", buf, end);
+                       strcpy(buf, newbuf);
+               }
+
+               free(isav);
+       }
+
+}
+#endif
+
+
 /*
  * Look for URL's embedded in a buffer and make them linkable.  We use a
  * target window in order to keep the BBS session in its own window.
@@ -483,6 +551,9 @@ void read_message(long msgnum) {
                if (!strncasecmp(buf, "from=", 5)) {
                        strcpy(from, &buf[5]);
                        wprintf("from <A HREF=\"/showuser&who=");
+#ifdef HAVE_ICONV
+                       utf8ify_rfc822_string(from);
+#endif
                        urlescputs(from);
                        wprintf("\">");
                        escputs(from);
@@ -588,6 +659,9 @@ void read_message(long msgnum) {
        }
 
        wprintf("</SPAN>");
+#ifdef HAVE_ICONV
+       utf8ify_rfc822_string(m_subject);
+#endif
        if (strlen(m_subject) > 0) {
                wprintf("<br />"
                        "<SPAN CLASS=\"message_subject\">"
@@ -802,6 +876,10 @@ void summarize_message(long msgnum, int is_new) {
                if (!strncasecmp(buf, "subj=", 5)) {
                        if (strlen(&buf[5]) > 0) {
                                strcpy(summ.subj, &buf[5]);
+#ifdef HAVE_ICONV
+                               /* Handle subjects with RFC2047 encoding */
+                               utf8ify_rfc822_string(summ.subj);
+#endif
                                if (strlen(summ.subj) > 75) {
                                        strcpy(&summ.subj[72], "...");
                                }
@@ -832,6 +910,10 @@ void summarize_message(long msgnum, int is_new) {
                }
        }
        
+#ifdef HAVE_ICONV
+       /* Handle senders with RFC2047 encoding */
+       utf8ify_rfc822_string(summ.from);
+#endif
        if (strlen(summ.from) > 25) {
                strcpy(&summ.from[22], "...");
        }