0.9.4claws61
[claws.git] / src / common / utils.c
index dd29497363e6b1d8a5128160499a639f7992daf6..d5e861f527bca8e3d6f833ec2f96d1f101522c41 100644 (file)
@@ -576,13 +576,12 @@ gint subject_compare_for_sort(const gchar *s1, const gchar *s2)
 void trim_subject_for_compare(gchar *str)
 {
        gchar *srcp;
-       int skip;
 
        eliminate_parenthesis(str, '[', ']');
        eliminate_parenthesis(str, '(', ')');
        g_strstrip(str);
 
-       srcp = str + subject_get_reply_prefix_length(str);
+       srcp = str + subject_get_prefix_length(str);
        if (srcp != str)
                memmove(str, srcp, strlen(srcp) + 1);
 }
@@ -593,7 +592,7 @@ void trim_subject_for_sort(gchar *str)
 
        g_strstrip(str);
 
-       srcp = str + subject_get_reply_prefix_length(str);
+       srcp = str + subject_get_prefix_length(str);
        if (srcp != str)        
                memmove(str, srcp, strlen(srcp) + 1);
 }
@@ -604,7 +603,7 @@ void trim_subject(gchar *str)
        gchar op, cl;
        gint in_brace;
 
-       destp = str + subject_get_reply_prefix_length(str);
+       destp = str + subject_get_prefix_length(str);
 
        if (*destp == '[') {
                op = '[';
@@ -3254,7 +3253,7 @@ void * subject_table_lookup(GHashTable *subject_table, gchar * subject)
        if (subject == NULL)
                subject = "";
        else
-               subject += subject_get_reply_prefix_length(subject);
+               subject += subject_get_prefix_length(subject);
 
        return g_hash_table_lookup(subject_table, subject);
 }
@@ -3264,7 +3263,7 @@ void subject_table_insert(GHashTable *subject_table, gchar * subject,
 {
        if (subject == NULL || *subject == 0)
                return;
-       subject += subject_get_reply_prefix_length(subject);
+       subject += subject_get_prefix_length(subject);
        g_hash_table_insert(subject_table, subject, data);
 }
 
@@ -3273,13 +3272,13 @@ void subject_table_remove(GHashTable *subject_table, gchar * subject)
        if (subject == NULL)
                return;
 
-       subject += subject_get_reply_prefix_length(subject);    
+       subject += subject_get_prefix_length(subject);  
        g_hash_table_remove(subject_table, subject);
 }
 
 /*!
  *\brief       Check if a string is prefixed with known (combinations) 
- *             of reply prefixes. The function assumes that each prefix 
+ *             of prefixes. The function assumes that each prefix 
  *             is terminated by zero or exactly _one_ space.
  *
  *\param       str String to check for a prefixes
@@ -3288,20 +3287,21 @@ void subject_table_remove(GHashTable *subject_table, gchar * subject)
  *             for a "clean" subject line. If no prefix was found, 0
  *             is returned.
  */            
-int subject_get_reply_prefix_length(const gchar *subject)
+int subject_get_prefix_length(const gchar *subject)
 {
        /*!< Array with allowable reply prefixes regexps. */
-       static const gchar * const reply_prefixes[] = {
+       static const gchar * const prefixes[] = {
                "Re\\:",                        /* "Re:" */
                "Re\\[[1-9][0-9]*\\]\\:",       /* "Re[XXX]:" (non-conforming news mail clients) */
                "Antw\\:",                      /* "Antw:" (Dutch / German Outlook) */
                "Aw\\:",                        /* "Aw:"   (German) */
                "Antwort\\:",                   /* "Antwort:" (German Lotus Notes) */
                "Res\\:",                       /* "Res:" (Brazilian Outlook) */
-               "Fw\\:"                         /* "Fw:" Forward */
+               "Fw\\:",                        /* "Fw:" Forward */
+               "Enc\\:"                        /* "Enc:" Forward (Brazilian Outlook) */
                /* add more */
        };
-       const int REPLY_PREFIXES = sizeof reply_prefixes / sizeof reply_prefixes[0];
+       const int PREFIXES = sizeof prefixes / sizeof prefixes[0];
        int n;
        regmatch_t pos;
        static regex_t regex;
@@ -3313,12 +3313,12 @@ int subject_get_reply_prefix_length(const gchar *subject)
        if (!init_) {
                GString *s = g_string_new("");
                
-               for (n = 0; n < REPLY_PREFIXES; n++)
+               for (n = 0; n < PREFIXES; n++)
                        /* Terminate each prefix regexpression by a
                         * "\ ?" (zero or ONE space), and OR them */
                        g_string_sprintfa(s, "(%s\\ ?)%s",
-                                         reply_prefixes[n],
-                                         n < REPLY_PREFIXES - 1 ? 
+                                         prefixes[n],
+                                         n < PREFIXES - 1 ? 
                                          "|" : "");
                
                g_string_prepend(s, "(");
@@ -3565,3 +3565,94 @@ gint g_int_compare(gconstpointer a, gconstpointer b)
 {
        return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
 }
+
+gchar *generate_msgid(const gchar *address, gchar *buf, gint len)
+{
+       /* steal from compose.c::compose_generate_msgid() */
+       struct tm *lt;
+       time_t t;
+       gchar *addr;
+
+       t = time(NULL);
+       lt = localtime(&t);
+
+       if (address && *address) {
+               if (strchr(address, '@'))
+                       addr = g_strdup(address);
+               else
+                       addr = g_strconcat(address, "@", get_domain_name(), NULL);
+       } else
+               addr = g_strconcat(g_get_user_name(), "@", get_domain_name(),
+                                  NULL);
+
+       g_snprintf(buf, len, "%04d%02d%02d%02d%02d%02d.%08x.%s",
+                  lt->tm_year + 1900, lt->tm_mon + 1,
+                  lt->tm_mday, lt->tm_hour,
+                  lt->tm_min, lt->tm_sec,
+                  (guint)random(), addr);
+
+       g_free(addr);
+       return buf;
+}
+
+/**
+ * Create a new boundary in a way that it is very unlikely that this
+ * will occur in the following text.  It would be easy to ensure
+ * uniqueness if everything is either quoted-printable or base64
+ * encoded (note that conversion is allowed), but because MIME bodies
+ * may be nested, it may happen that the same boundary has already
+ * been used. We avoid scanning the message for conflicts and hope the
+ * best.
+ *
+ *   boundary := 0*69<bchars> bcharsnospace
+ *   bchars := bcharsnospace / " "
+ *   bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
+ *                    "+" / "_" / "," / "-" / "." /
+ *                    "/" / ":" / "=" / "?"  
+ *
+ * ":" and "," removed because of buggy MTAs
+ */
+
+gchar *generate_mime_boundary(void)
+{
+       static gchar tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                            "abcdefghijklmnopqrstuvwxyz" 
+                            "1234567890'()+_./=?";
+       gchar bufuniq[17];
+       gchar bufdate[BUFFSIZE];
+       int i, equal;
+       int pid;
+
+       pid = getpid();
+
+       /* We make the boundary depend on the pid, so that all running
+        * processed generate different values even when they have been
+        * started within the same second and srand48(time(NULL)) has been
+        * used.  I can't see whether this is really an advantage but it
+        * doesn't do any harm.
+        */
+       equal = -1;
+       for (i = 0; i < sizeof(bufuniq) - 1; i++) {
+               bufuniq[i] = tbl[(lrand48() ^ pid) % (sizeof(tbl) - 1)];        /* fill with random */
+               if (bufuniq[i] == '=' && equal == -1)
+                       equal = i;
+       }
+       bufuniq[i] = 0;
+
+       /* now make sure that we do have the sequence "=." in it which cannot
+        * be matched by quoted-printable or base64 encoding */
+       if (equal != -1 && (equal + 1) < i)
+               bufuniq[equal + 1] = '.';
+       else {
+               bufuniq[0] = '=';
+               bufuniq[1] = '.';
+       }
+
+       get_rfc822_date(bufdate, sizeof(bufdate));
+       subst_char(bufdate, ' ', '_');
+       subst_char(bufdate, ',', '_');
+       subst_char(bufdate, ':', '_');
+
+       return g_strdup_printf("Multipart_%s_%s",
+                              bufdate, bufuniq);
+}