sync with 0.8.0cvs1
[claws.git] / src / utils.c
index 9cf692566199e4e3f816ffcb88e7494025b88dbe..4d33b92bd74626de2013f129c85ce72e729dac32 100644 (file)
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <errno.h>
+#include <netdb.h>
 
 #if (HAVE_WCTYPE_H && HAVE_WCHAR_H)
 #  include <wchar.h>
@@ -982,7 +983,7 @@ gboolean is_ascii_str(const guchar *str)
        return TRUE;
 }
 
-gint get_quote_level(const gchar *str)
+gint get_quote_level(const gchar *str, const gchar *quote_chars)
 {
        const gchar *first_pos;
        const gchar *last_pos;
@@ -990,11 +991,11 @@ gint get_quote_level(const gchar *str)
        gint quote_level = -1;
 
        /* speed up line processing by only searching to the last '>' */
-       if ((first_pos = strchr(str, '>')) != NULL) {
+       if ((first_pos = line_has_quote_char(str, quote_chars)) != NULL) {
                /* skip a line if it contains a '<' before the initial '>' */
                if (memchr(str, '<', first_pos - str) != NULL)
                        return -1;
-               last_pos = strrchr(first_pos, '>');
+               last_pos = line_has_quote_char_last(first_pos, quote_chars);
        } else
                return -1;
 
@@ -1006,14 +1007,16 @@ gint get_quote_level(const gchar *str)
                                break;
                }
 
-               if (*p == '>')
+               if (strchr(quote_chars, *p))
                        quote_level++;
                else if (*p != '-' && !isspace(*p) && p <= last_pos) {
                        /* any characters are allowed except '-' and space */
-                       while (*p != '-' && *p != '>' && !isspace(*p) &&
-                              p < last_pos)
+                       while (*p != '-' 
+                              && !strchr(quote_chars, *p) 
+                              && !isspace(*p) 
+                              && p < last_pos)
                                p++;
-                       if (*p == '>')
+                       if (strchr(quote_chars, *p))
                                quote_level++;
                        else
                                break;
@@ -1025,6 +1028,42 @@ gint get_quote_level(const gchar *str)
        return quote_level;
 }
 
+const gchar * line_has_quote_char(const gchar * str, const gchar *quote_chars) 
+{
+       gchar * position = NULL;
+       gchar * tmp_pos = NULL;
+       int i;
+
+       if (quote_chars == NULL)
+               return FALSE;
+       
+       for (i = 0; i < strlen(quote_chars); i++) {
+               tmp_pos = strchr (str,  quote_chars[i]);
+               if(position == NULL 
+                  || (tmp_pos != NULL && position >= tmp_pos) )
+                       position = tmp_pos;
+       }
+       return position; 
+}
+
+const gchar * line_has_quote_char_last(const gchar * str, const gchar *quote_chars) 
+{
+       gchar * position = NULL;
+       gchar * tmp_pos = NULL;
+       int i;
+
+       if (quote_chars == NULL)
+               return FALSE;
+       
+       for (i = 0; i < strlen(quote_chars); i++) {
+               tmp_pos = strrchr (str, quote_chars[i]);
+               if(position == NULL 
+                  || (tmp_pos != NULL && position <= tmp_pos) )
+                       position = tmp_pos;
+       }
+       return position; 
+}
+
 gchar *strstr_with_skip_quote(const gchar *haystack, const gchar *needle)
 {
        register guint haystack_len, needle_len;
@@ -1062,7 +1101,94 @@ gchar *strstr_with_skip_quote(const gchar *haystack, const gchar *needle)
        return NULL;
 }
 
-/* this fuction was taken from gstrfuncs.c in glib. */
+gchar *strchr_parenthesis_close(const gchar *str, gchar op, gchar cl)
+{
+       const gchar *p;
+       gchar quote_chr = '"';
+       gint in_brace;
+       gboolean in_quote = FALSE;
+
+       p = str;
+
+       if ((p = strchr_with_skip_quote(p, quote_chr, op))) {
+               p++;
+               in_brace = 1;
+               while (*p) {
+                       if (*p == op && !in_quote)
+                               in_brace++;
+                       else if (*p == cl && !in_quote)
+                               in_brace--;
+                       else if (*p == quote_chr)
+                               in_quote ^= TRUE;
+
+                       if (in_brace == 0)
+                               return (gchar *)p;
+
+                       p++;
+               }
+       }
+
+       return NULL;
+}
+
+gchar **strsplit_parenthesis(const gchar *str, gchar op, gchar cl,
+                            gint max_tokens)
+{
+       GSList *string_list = NULL, *slist;
+       gchar **str_array;
+       const gchar *s_op, *s_cl;
+       guint i, n = 1;
+
+       g_return_val_if_fail(str != NULL, NULL);
+
+       if (max_tokens < 1)
+               max_tokens = G_MAXINT;
+
+       s_op = strchr_with_skip_quote(str, '"', op);
+       if (!s_op) return NULL;
+       str = s_op;
+       s_cl = strchr_parenthesis_close(str, op, cl);
+       if (s_cl) {
+               do {
+                       guint len;
+                       gchar *new_string;
+
+                       str++;
+                       len = s_cl - str;
+                       new_string = g_new(gchar, len + 1);
+                       strncpy(new_string, str, len);
+                       new_string[len] = 0;
+                       string_list = g_slist_prepend(string_list, new_string);
+                       n++;
+                       str = s_cl + 1;
+
+                       while (*str && isspace(*str)) str++;
+                       if (*str != op) {
+                               string_list = g_slist_prepend(string_list,
+                                                             g_strdup(""));
+                               n++;
+                               s_op = strchr_with_skip_quote(str, '"', op);
+                               if (!--max_tokens || !s_op) break;
+                               str = s_op;
+                       } else
+                               s_op = str;
+                       s_cl = strchr_parenthesis_close(str, op, cl);
+               } while (--max_tokens && s_cl);
+       }
+
+       str_array = g_new(gchar*, n);
+
+       i = n - 1;
+
+       str_array[i--] = NULL;
+       for (slist = string_list; slist; slist = slist->next)
+               str_array[i--] = slist->data;
+
+       g_slist_free(string_list);
+
+       return str_array;
+}
+
 gchar **strsplit_with_quote(const gchar *str, const gchar *delim,
                            gint max_tokens)
 {
@@ -1137,7 +1263,6 @@ gchar *get_abbrev_newsgroup_name(const gchar *group)
                if (strchr(p, '.')) {
                        *ap++ = *p++;
                        while (*p != '.') p++;
-                       *ap++ = *p++;
                } else {
                        strcpy(ap, p);
                        return abbrev_group;
@@ -1148,6 +1273,34 @@ gchar *get_abbrev_newsgroup_name(const gchar *group)
        return abbrev_group;
 }
 
+gchar *trim_string(const gchar *str, gint len)
+{
+       const gchar *p = str;
+       gint mb_len;
+       gchar *new_str;
+       gint new_len = 0;
+
+       if (!str) return NULL;
+       if (strlen(str) <= len)
+               return g_strdup(str);
+
+       while (*p != '\0') {
+               mb_len = mblen(p, MB_LEN_MAX);
+               if (mb_len == 0)
+                       break;
+               else if (mb_len < 0)
+                       return g_strdup(str);
+               else if (new_len + mb_len > len)
+                       break;
+               else
+                       new_len += mb_len;
+               p += mb_len;
+       }
+
+       Xstrndup_a(new_str, str, new_len, return g_strdup(str));
+       return g_strconcat(new_str, "...", NULL);
+}
+
 GList *uri_list_extract_filenames(const gchar *uri_list)
 {
        GList *result = NULL;
@@ -1318,6 +1471,7 @@ gchar *get_tmp_file(void)
 gchar *get_domain_name(void)
 {
        static gchar *domain_name = NULL;
+        struct hostent *myfqdn = NULL;
 
        if (!domain_name) {
                gchar buf[BUFFSIZE] = "";
@@ -1325,7 +1479,16 @@ gchar *get_domain_name(void)
                if (gethostname(buf, sizeof(buf)) < 0) {
                        perror("gethostname");
                        strcpy(buf, "unknown");
-               }
+               }  else  {
+                myfqdn = gethostbyname(buf);
+                if (myfqdn != NULL)  {
+                  memset(buf, '\0', strlen(buf));
+                  strcpy(buf, myfqdn->h_name);
+                  }  else  {
+                  perror("gethostbyname");
+                  strcpy(buf, "unknown");
+                  }
+                }
 
                domain_name = g_strdup(buf);
        }
@@ -1428,6 +1591,18 @@ gboolean is_dir_exist(const gchar *dir)
        return FALSE;
 }
 
+gboolean is_file_entry_exist(const gchar *file)
+{
+       struct stat s;
+
+       if (stat(file, &s) < 0) {
+               if (ENOENT != errno) FILE_OP_ERROR(file, "stat");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 gint change_dir(const gchar *dir)
 {
        gchar *prevdir = NULL;
@@ -1452,6 +1627,18 @@ gint change_dir(const gchar *dir)
        return 0;
 }
 
+gint make_dir(const gchar *dir)
+{
+       if (mkdir(dir, S_IRWXU) < 0) {
+               FILE_OP_ERROR(dir, "mkdir");
+               return -1;
+       }
+       if (chmod(dir, S_IRWXU) < 0)
+               FILE_OP_ERROR(dir, "chmod");
+
+       return 0;
+}
+
 gint make_dir_hier(const gchar *dir)
 {
        gchar *parent_dir;
@@ -1461,24 +1648,18 @@ gint make_dir_hier(const gchar *dir)
                parent_dir = g_strndup(dir, p - dir);
                if (*parent_dir != '\0') {
                        if (!is_dir_exist(parent_dir)) {
-                               if (mkdir(parent_dir, S_IRWXU) < 0) {
-                                       FILE_OP_ERROR(parent_dir, "mkdir");
+                               if (make_dir(parent_dir) < 0) {
                                        g_free(parent_dir);
                                        return -1;
                                }
-                               if (chmod(parent_dir, S_IRWXU) < 0)
-                                       FILE_OP_ERROR(parent_dir, "chmod");
                        }
                }
                g_free(parent_dir);
        }
+
        if (!is_dir_exist(dir)) {
-               if (mkdir(dir, S_IRWXU) < 0) {
-                       FILE_OP_ERROR(dir, "mkdir");
+               if (make_dir(dir) < 0)
                        return -1;
-               }
-               if (chmod(dir, S_IRWXU) < 0)
-                       FILE_OP_ERROR(dir, "chmod");
        }
 
        return 0;
@@ -1546,6 +1727,8 @@ gint remove_numbered_files(const gchar *dir, guint first, guint last)
        while ((d = readdir(dp)) != NULL) {
                fileno = to_number(d->d_name);
                if (fileno >= 0 && first <= fileno && fileno <= last) {
+                       if (is_dir_exist(d->d_name))
+                               continue;
                        if (unlink(d->d_name) < 0)
                                FILE_OP_ERROR(d->d_name, "unlink");
                }