]> mj.ucw.cz Git - checkmail.git/blobdiff - charset.c
Updated maintainer scripts
[checkmail.git] / charset.c
index 606d8dc55bf5dc5cdb6a3a19817cc4f97eefd1f5..d32a414eead4eacb54fafccc4822931d1b46f640 100644 (file)
--- a/charset.c
+++ b/charset.c
@@ -25,6 +25,7 @@
  */
 
 #include "util.h"
+#include "rfc822.h"
 #include "charset.h"
 
 #include <ctype.h>
@@ -73,12 +74,7 @@ static int Index_64[128] = {
 #define hexval(c) Index_hex[(unsigned int)(c)]
 #define base64val(c) Index_64[(unsigned int)(c)]
 
-#define OPTIGNORELWS 0
-
-static int option(int opt UNUSED)
-{
-  return 1;
-}
+#define option_OPTIGNORELWS 1
 
 static size_t convert_string (char *f, size_t flen,
                              const char *from, const char *to,
@@ -197,9 +193,20 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len)
     }
   }
 
-  size_t dlen;
   if (charset && system_charset)
-    convert_string (d0, strlen(d0), charset, system_charset, &d0, &dlen);
+    {
+      char *dnew;
+      size_t dlen;
+      if (convert_string (d0, strlen(d0), charset, system_charset, &dnew, &dlen) == (size_t) -1)
+       {
+         debug("Charset conversion failure: <%s> from %s (%m)\n", d0, charset);
+         free (charset);
+         free (d0);
+         return (-1);
+       }
+      free (d0);
+      d0 = dnew;
+    }
   strfcpy (d, d0, len);
   free (charset);
   free (d0);
@@ -225,7 +232,8 @@ static const char *find_encoded_word (const char *s, const char **x)
       ;
     if (q[0] != '?' || !strchr ("BbQq", q[1]) || q[2] != '?')
       continue;
-    for (q = q + 3; 0x20 < *q && *q < 0x7f && *q != '?'; q++)
+    /* non-strict check since many MUAs will not encode spaces and question marks */
+    for (q = q + 3; 0x20 <= *q && *q < 0x7f && (*q != '?' || q[1] != '='); q++)
       ;
     if (q[0] != '?' || q[1] != '=')
     {
@@ -304,7 +312,7 @@ static void rfc2047_decode (char **pd)
     if (!(p = find_encoded_word (s, &q)))
     {
       /* no encoded words */
-      if (option (OPTIGNORELWS))
+      if (option_OPTIGNORELWS)
       {
         n = strlen (s);
         if (found_encoded && (m = lwslen (s, n)) != 0)
@@ -324,7 +332,7 @@ static void rfc2047_decode (char **pd)
       n = (size_t) (p - s);
       /* ignore spaces between encoded word
        * and linear-white-space between encoded word and *text */
-      if (option (OPTIGNORELWS))
+      if (option_OPTIGNORELWS)
       {
         if (found_encoded && (m = lwslen (s, n)) != 0)
         {
@@ -354,7 +362,13 @@ static void rfc2047_decode (char **pd)
       }
     }
 
-    rfc2047_decode_word (d, p, dlen);
+    if (rfc2047_decode_word (d, p, dlen) < 0)
+    {
+      n = q - p;
+      if (n > dlen)
+       n = dlen;
+      memcpy (d, p, n);
+    }
     found_encoded = 1;
     s = q;
     n = strlen (d);
@@ -375,11 +389,18 @@ charset_init(void)
   system_charset = nl_langinfo(CODESET);
   if (!system_charset[0])
     system_charset = NULL;
+  if (system_charset)
+    {
+      /* FIXME: Use iconvctl() if available? */
+      char *t = xmalloc(strlen(system_charset) + 11);
+      sprintf(t, "%s//TRANSLIT", system_charset);
+      system_charset = t;
+    }
   debug("Charset is %s\n", system_charset);
 }
 
-static void
-do_add_snippet(char **ppos, char *term, unsigned char *add)
+void
+add_snippet(char **ppos, char *term, char *add)
 {
   char *pos = *ppos;
   int space = 1;
@@ -415,10 +436,61 @@ do_add_snippet(char **ppos, char *term, unsigned char *add)
 }
 
 void
-add_snippet(char **ppos, char *term, char *add)
+add_snippet_raw(char **ppos, char *term, char *add)
+{
+  char *pos = *ppos;
+  while (pos < term && *add)
+    *pos++ = *add++;
+  *ppos = pos;
+  *pos = 0;
+}
+
+void
+add_subject_snippet(char **ppos, char *term, char *add)
 {
   char *buf = xstrdup(add);
   rfc2047_decode(&buf);
-  do_add_snippet(ppos, term, buf);
+  add_snippet(ppos, term, buf);
   free(buf);
 }
+
+void
+add_addr_snippet(char **ppos, char *term, char *add, int add_mbox, int add_personal)
+{
+  ADDRESS *addr = rfc822_parse_adrlist(NULL, add);
+  if (!addr)
+    {
+      debug("%s: Cannot parse address (%s)\n", add, rfc822_error(RFC822Error));
+      add_subject_snippet(ppos, term, add);
+      return;
+    }
+  rfc2047_decode(&addr->personal);
+  // debug("%s: pers=%s mbox=%s\n", add, addr->personal, addr->mailbox);
+  if (!addr->mailbox || !addr->mailbox[0])
+    add_mbox = 0;
+  if (!addr->personal || !addr->personal[0])
+    {
+      if (addr->mailbox && addr->mailbox[0])
+       {
+         char *c = strchr(addr->mailbox, '@');
+         if (c)
+           *c = 0;
+         add_mbox = 1;
+       }
+      add_personal = 0;
+    }
+  if (add_mbox || add_personal)
+    {
+      if (add_personal)
+       add_snippet(ppos, term, addr->personal);
+      if (add_mbox && add_personal)
+       add_snippet_raw(ppos, term, " <");
+      if (add_mbox)
+       add_snippet(ppos, term, addr->mailbox);
+      if (add_mbox && add_personal)
+       add_snippet_raw(ppos, term, ">");
+    }
+  else
+    add_snippet_raw(ppos, term, "???");
+  rfc822_free_address(&addr);
+}