Allow the user to specify a default character set for email headers.
authorArt Cancro <ajc@citadel.org>
Thu, 9 Feb 2006 04:00:10 +0000 (04:00 +0000)
committerArt Cancro <ajc@citadel.org>
Thu, 9 Feb 2006 04:00:10 +0000 (04:00 +0000)
webcit/messages.c
webcit/preferences.c

index 724dab8c55b522b6ea79e2f50333e6d13b56a94e..861b2a60e02ca34cd0627d7d783c3fd13f036a50 100644 (file)
@@ -67,14 +67,53 @@ void utf8ify_rfc822_string(char *buf) {
        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       */
+       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 */
        int passes = 0;
+       int i;
+       int illegal_non_rfc2047_encoding = 0;
 
+       /** Sometimes, badly formed messages contain strings which were simply
+        *  written out directly in some foreign character set instead of
+        *  using RFC2047 encoding.  This is illegal but we will attempt to
+        *  handle it anyway by converting from a user-specified default
+        *  charset to UTF-8 if we see any nonprintable characters.
+        */
+       for (i=0; i<strlen(buf); ++i) {
+               if ((buf[i] < 32) || (buf[i] > 126)) {
+                       illegal_non_rfc2047_encoding = 1;
+               }
+       }
+       if (illegal_non_rfc2047_encoding) {
+               char default_header_charset[128];
+               get_preference("default_header_charset", default_header_charset, sizeof default_header_charset);
+               if ( (strcasecmp(default_header_charset, "UTF-8")) && (strcasecmp(default_header_charset, "us-ascii")) ) {
+                       ic = ctdl_iconv_open("UTF-8", default_header_charset);
+                       if (ic != (iconv_t)(-1) ) {
+                               ibuf = malloc(1024);
+                               isav = ibuf;
+                               safestrncpy(ibuf, buf, 1024);
+                               ibuflen = strlen(ibuf);
+                               obuflen = 1024;
+                               obuf = (char *) malloc(obuflen);
+                               osav = obuf;
+                               iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
+                               osav[1024-obuflen] = 0;
+                               strcpy(buf, osav);
+                               free(osav);
+                               iconv_close(ic);
+                               free(isav);
+                       }
+               }
+       }
+
+       /** Now we handle foreign character sets properly encoded
+        *  in RFC2047 format.
+        */
        while (start=strstr(buf, "=?"), end=strstr(buf, "?="),
                ((start != NULL) && (end != NULL) && (end > start)) )
        {
@@ -82,10 +121,6 @@ void utf8ify_rfc822_string(char *buf) {
                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 */
@@ -95,7 +130,7 @@ void utf8ify_rfc822_string(char *buf) {
                        ibuflen = CtdlDecodeQuotedPrintable(ibuf, istr, strlen(istr));
                }
                else {
-                       strcpy(ibuf, istr);             /**< huh? */
+                       strcpy(ibuf, istr);             /**< unknown encoding */
                        ibuflen = strlen(istr);
                }
 
index a7362134e4db72eb066811ab11a373a24390588c..a21468c63f1816927b89a9ce32d1e1b7b75910fb 100644 (file)
@@ -145,10 +145,11 @@ void get_preference(char *key, char *value, size_t value_len) {
 }
 
 /**
- * \brief Write a key into the citadel settings database
- * \param key key whichs value is to be modified
- * \param value value to set
- * \param save_to_server really write it????
+ * \brief      Write a key into the webcit preferences database for this user
+ *
+ * \params     key             key whichs value is to be modified
+ * \param      value           value to set
+ * \param      save_to_server  1 = flush all data to the server, 0 = cache it for now
  */
 void set_preference(char *key, char *value, int save_to_server) {
        int num_prefs;
@@ -370,7 +371,16 @@ void display_preferences(void)
                "       </script>                               "
        );
 
+       /** Character set to assume is in use for improperly encoded headers */
+       get_preference("default_header_charset", buf, sizeof buf);
+       if (buf[0] == 0) strcpy(buf, "UTF-8");
+       wprintf("<tr><td>");
+       wprintf(_("Default character set for email headers:"));
+       wprintf("</td><td>");
+       wprintf("<input type=\"text\" NAME=\"default_header_charset\" MAXLENGTH=\"32\" VALUE=\"%s\">", buf);
+       wprintf("</td></tr>");
 
+       /** submit buttons */
        wprintf("</table>\n"
                "<input type=\"submit\" name=\"change_button\" value=\"%s\">"
                "&nbsp;"
@@ -379,11 +389,8 @@ void display_preferences(void)
                _("Cancel")
        );
 
-       wprintf("</form></center>\n");
-
        /** end form */
-
-
+       wprintf("</form></center>\n");
        wprintf("</td></tr></table></div>\n");
        wDumpContent(1);
 }
@@ -412,6 +419,7 @@ void set_preferences(void)
        set_preference("use_sig", bstr("use_sig"), 0);
        set_preference("daystart", bstr("daystart"), 0);
        set_preference("dayend", bstr("dayend"), 0);
+       set_preference("default_header_charset", bstr("default_header_charset"), 0);
 
        euid_escapize(ebuf, bstr("signature"));
        set_preference("signature", ebuf, 1);