2011-05-12 [colin] 3.7.9cvs22
[claws.git] / src / common / utils.c
index d99c44e891600cabeed08cf26cef3a405c4632c5..d5a5a9483e388c16783f60e4006083dc930c5f48 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2009 Hiroyuki Yamamoto & The Claws Mail Team
+ * Copyright (C) 1999-2011 Hiroyuki Yamamoto & The Claws Mail Team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include <glib/gi18n.h>
 
+#ifdef USE_PTHREAD
+#include <pthread.h>
+#endif
+
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
@@ -301,16 +305,6 @@ void ptr_array_free_strings(GPtrArray *array)
        }
 }
 
-gboolean str_find(const gchar *haystack, const gchar *needle)
-{
-       return strstr(haystack, needle) != NULL ? TRUE : FALSE;
-}
-
-gboolean str_case_find(const gchar *haystack, const gchar *needle)
-{
-       return strcasestr(haystack, needle) != NULL ? TRUE : FALSE;
-}
-
 gint to_number(const gchar *nstr)
 {
        register const gchar *p;
@@ -346,6 +340,13 @@ gchar *itos(gint n)
        d = (d*100) >> divisor;         \
 }
 
+
+/*!
+ * \brief Convert a given size in bytes in a human-readable string
+ *
+ * \param size  The size expressed in bytes to convert in string
+ * \return      The string that respresents the size in an human-readable way
+ */
 gchar *to_human_readable(goffset size)
 {
        static gchar str[14];
@@ -990,20 +991,23 @@ GSList *newsgroup_list_append(GSList *group_list, const gchar *str)
 GList *add_history(GList *list, const gchar *str)
 {
        GList *old;
+       gchar *oldstr;
 
        cm_return_val_if_fail(str != NULL, list);
 
        old = g_list_find_custom(list, (gpointer)str, (GCompareFunc)strcmp2);
        if (old) {
-               g_free(old->data);
+               oldstr = old->data;
                list = g_list_remove(list, old->data);
+               g_free(oldstr);
        } else if (g_list_length(list) >= MAX_HISTORY_SIZE) {
                GList *last;
 
                last = g_list_last(list);
                if (last) {
-                       g_free(last->data);
+                       oldstr = last->data;
                        list = g_list_remove(list, last->data);
+                       g_free(oldstr);
                }
        }
 
@@ -1121,7 +1125,7 @@ static const gchar * line_has_quote_char_last(const gchar * str, const gchar *qu
        int i;
 
        if (quote_chars == NULL)
-               return FALSE;
+               return NULL;
 
        for (i = 0; i < strlen(quote_chars); i++) {
                tmp_pos = strrchr (str, quote_chars[i]);
@@ -1159,8 +1163,8 @@ gint get_quote_level(const gchar *str, const gchar *quote_chars)
                if (strchr(quote_chars, *p))
                        quote_level++;
                else if (*p != '-' && !g_ascii_isspace(*p) && p <= last_pos) {
-                       /* any characters are allowed except '-' and space */
-                       while (*p != '-'
+                       /* any characters are allowed except '-','<' and space */
+                       while (*p != '-' && *p != '<'
                               && !strchr(quote_chars, *p)
                               && !g_ascii_isspace(*p)
                               && p < last_pos)
@@ -1544,7 +1548,7 @@ static gchar *decode_uri_gdup(const gchar *encoded_uri)
 }
 
 gint scan_mailto_url(const gchar *mailto, gchar **from, gchar **to, gchar **cc, gchar **bcc,
-                    gchar **subject, gchar **body, gchar ***attach)
+                    gchar **subject, gchar **body, gchar ***attach, gchar **inreplyto)
 {
        gchar *tmp_mailto;
        gchar *p;
@@ -1628,8 +1632,8 @@ gint scan_mailto_url(const gchar *mailto, gchar **from, gchar **to, gchar **cc,
                        *body = decode_uri_gdup(value);
                } else if (body && !*body && !g_ascii_strcasecmp(field, "insert")) {
                        gchar *tmp = decode_uri_gdup(value);
-                       if (!g_file_get_contents(value, body, NULL, NULL)) {
-                               g_error("Error: couldn't set insert file '%s' in body\n", value);
+                       if (!g_file_get_contents(tmp, body, NULL, NULL)) {
+                               g_warning("Error: couldn't set insert file '%s' in body\n", value);
                        }
                        g_free(tmp);
                        tmp = NULL;
@@ -1652,6 +1656,9 @@ gint scan_mailto_url(const gchar *mailto, gchar **from, gchar **to, gchar **cc,
                                my_att[num_attach-1] = tmp;
                                my_att[num_attach] = NULL;
                        }
+               } else if (inreplyto && !*inreplyto &&
+                          !g_ascii_strcasecmp(field, "in-reply-to")) {
+                       *inreplyto = decode_uri_gdup(value);
                }
        }
 
@@ -1986,6 +1993,16 @@ const gchar *get_cert_file(void)
 }
 #endif
 
+/* Return the filepath of the claws-mail.desktop file */
+const gchar *get_desktop_file(void)
+{
+#ifdef DESKTOPFILEPATH
+  return DESKTOPFILEPATH;
+#else
+  return NULL;
+#endif
+}
+
 /* Return the default directory for Plugins. */
 const gchar *get_plugin_dir(void)
 {
@@ -3515,9 +3532,7 @@ time_t tzoffset_sec(time_t *now)
 {
        struct tm gmt, *lt;
        gint off;
-#ifndef G_OS_WIN32
        struct tm buf1, buf2;
-#endif
 #ifdef G_OS_WIN32
        if (now && *now < 0)
                return 0;
@@ -3551,9 +3566,7 @@ gchar *tzoffset(time_t *now)
        struct tm gmt, *lt;
        gint off;
        gchar sign = '+';
-#ifndef G_OS_WIN32
        struct tm buf1, buf2;
-#endif
 #ifdef G_OS_WIN32
        if (now && *now < 0)
                return 0;
@@ -3591,10 +3604,8 @@ void get_rfc822_date(gchar *buf, gint len)
        time_t t;
        gchar day[4], mon[4];
        gint dd, hh, mm, ss, yyyy;
-#ifndef G_OS_WIN32
        struct tm buf1;
        gchar buf2[BUFFSIZE];
-#endif
 
        t = time(NULL);
        lt = localtime_r(&t, &buf1);
@@ -3712,7 +3723,8 @@ int subject_get_prefix_length(const gchar *subject)
                "Vs\\:",                        /* "Vs" (Norwegian) */
                "Ad\\:",                        /* "Ad" (Norwegian) */
                "\347\255\224\345\244\215\\:",  /* "Re" (Chinese, UTF-8) */
-               "R\303\251f\\. \\:",    /* "Réf. :" (French Lotus Notes) */
+               "R\303\251f\\. \\:",            /* "Réf. :" (French Lotus Notes) */
+               "Re \\:",                       /* "Re :" (French Yahoo Mail) */
                /* add more */
        };
        const int PREFIXES = sizeof prefixes / sizeof prefixes[0];
@@ -3771,6 +3783,7 @@ int subject_get_prefix_length(const gchar *subject)
                "vs:",                  /* "Vs" (Norwegian) */
                "ad:",                  /* "Ad" (Norwegian) */
                "R\303\251f. :",        /* "Réf. :" (French Lotus Notes) */
+               "Re :",                 /* "Re :" (French Yahoo Mail) */
                /* add more */
        };
        const int PREFIXES = sizeof prefixes / sizeof prefixes[0];
@@ -3821,29 +3834,23 @@ gchar *generate_msgid(gchar *buf, gint len, gchar *user_addr)
        struct tm *lt;
        time_t t;
        gchar *addr;
-#ifndef G_OS_WIN32
        struct tm buft;
-#endif
 
        t = time(NULL);
        lt = localtime_r(&t, &buft);
 
-       if (strcmp(buf, "") == 0) {
-               if (user_addr != NULL) {
-                       addr = g_strconcat(user_addr, "@", get_domain_name(), NULL);
-               }
-               else {
-                       addr = g_strconcat("@", get_domain_name(), NULL);
-               }
-       }
-       else {
-               if (user_addr != NULL) {
-                       addr = g_strconcat(user_addr, "@", buf, NULL);
-               }
-               else {
-                       addr = g_strconcat("@", buf, NULL);
-               }
-       }
+       if (user_addr != NULL)
+             addr = g_strdup_printf(".%s", user_addr);
+       else if (strlen(buf) != 0)
+             addr = g_strdup_printf("@%s", buf);
+       else
+             addr = g_strdup_printf("@%s", get_domain_name());
+
+       /* Replace all @ but the last one in addr, with underscores.
+        * RFC 2822 States that msg-id syntax only allows one @.
+        */
+       while (strchr(addr, '@') != NULL && strchr(addr, '@') != strrchr(addr, '@'))
+               *(strchr(addr, '@')) = '_';
 
        g_snprintf(buf, len, "%04d%02d%02d%02d%02d%02d.%08x%s",
                   lt->tm_year + 1900, lt->tm_mon + 1,
@@ -4250,7 +4257,7 @@ gboolean get_uri_part(const gchar *start, const gchar *scanpos,
         * should pass some URI type to this function and decide on that whether
         * to perform punctuation stripping */
 
-#define IS_REAL_PUNCT(ch)      (g_ascii_ispunct(ch) && !strchr("/?=-)", ch))
+#define IS_REAL_PUNCT(ch)      (g_ascii_ispunct(ch) && !strchr("/?=-_)", ch))
 
        for (; ep_ - 1 > scanpos + 1 &&
               IS_REAL_PUNCT(*(ep_ - 1));