sync with 0.7.4cvs49
[claws.git] / src / utils.c
index e09be04f7bfe9028dfd16cea018e77b2b46af46f..140f5f3a4abb1ad375ed0ece697a9775d604521c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2001 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2002 Hiroyuki Yamamoto
  *
  * 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
@@ -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>
@@ -940,6 +941,22 @@ void subst_char(gchar *str, gchar orig, gchar subst)
        }
 }
 
+void subst_chars(gchar *str, gchar *orig, gchar subst)
+{
+       register gchar *p = str;
+
+       while (*p) {
+               if (strchr(orig, *p) != NULL)
+                       *p = subst;
+               p++;
+       }
+}
+
+void subst_for_filename(gchar *str)
+{
+       subst_chars(str, " \t\r\n\"/\\", '_');
+}
+
 gboolean is_header_line(const gchar *str)
 {
        if (str[0] == ':') return FALSE;
@@ -1051,8 +1068,8 @@ gchar **strsplit_with_quote(const gchar *str, const gchar *delim,
                            gint max_tokens)
 {
        GSList *string_list = NULL, *slist;
-       gchar **str_array, *s;
-       guint i, n = 1;
+       gchar **str_array, *s, *new_str;
+       guint i, n = 1, len;
 
        g_return_val_if_fail(str != NULL, NULL);
        g_return_val_if_fail(delim != NULL, NULL);
@@ -1065,13 +1082,15 @@ gchar **strsplit_with_quote(const gchar *str, const gchar *delim,
                guint delimiter_len = strlen(delim);
 
                do {
-                       guint len;
-                       gchar *new_str;
-
                        len = s - str;
-                       new_str = g_new(gchar, len + 1);
-                       strncpy(new_str, str, len);
-                       new_str[len] = 0;
+                       new_str = g_strndup(str, len);
+
+                       if (new_str[0] == '\'' || new_str[0] == '\"') {
+                               if (new_str[len - 1] == new_str[0]) {
+                                       new_str[len - 1] = '\0';
+                                       memmove(new_str, new_str + 1, len - 1);
+                               }
+                       }
                        string_list = g_slist_prepend(string_list, new_str);
                        n++;
                        str = s + delimiter_len;
@@ -1080,8 +1099,16 @@ gchar **strsplit_with_quote(const gchar *str, const gchar *delim,
        }
 
        if (*str) {
+               new_str = g_strdup(str);
+               if (new_str[0] == '\'' || new_str[0] == '\"') {
+                       len = strlen(str);
+                       if (new_str[len - 1] == new_str[0]) {
+                               new_str[len - 1] = '\0';
+                               memmove(new_str, new_str + 1, len - 1);
+                       }
+               }
+               string_list = g_slist_prepend(string_list, new_str);
                n++;
-               string_list = g_slist_prepend(string_list, g_strdup(str));
        }
 
        str_array = g_new(gchar*, n);
@@ -1097,6 +1124,30 @@ gchar **strsplit_with_quote(const gchar *str, const gchar *delim,
        return str_array;
 }
 
+gchar *get_abbrev_newsgroup_name(const gchar *group)
+{
+       gchar *abbrev_group;
+       gchar *ap;
+       const gchar *p = group;
+
+       abbrev_group = ap = g_malloc(strlen(group) + 1);
+
+       while (*p) {
+               while (*p == '.')
+                       *ap++ = *p++;
+               if (strchr(p, '.')) {
+                       *ap++ = *p++;
+                       while (*p != '.') p++;
+               } else {
+                       strcpy(ap, p);
+                       return abbrev_group;
+               }
+       }
+
+       *ap = '\0';
+       return abbrev_group;
+}
+
 GList *uri_list_extract_filenames(const gchar *uri_list)
 {
        GList *result = NULL;
@@ -1242,6 +1293,17 @@ gchar *get_template_dir(void)
        return template_dir;
 }
 
+gchar *get_header_cache_dir(void)
+{
+       static gchar *header_dir = NULL;
+
+       if (!header_dir)
+               header_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+                                        HEADER_CACHE_DIR, NULL);
+
+       return header_dir;
+}
+
 gchar *get_tmp_file(void)
 {
        static gchar *tmp_file = NULL;
@@ -1256,6 +1318,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] = "";
@@ -1263,7 +1326,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);
        }
@@ -1283,6 +1355,32 @@ off_t get_file_size(const gchar *file)
        return s.st_size;
 }
 
+off_t get_file_size_as_crlf(const gchar *file)
+{
+       FILE *fp;
+       off_t size = 0;
+       gchar buf[BUFFSIZE];
+
+       if ((fp = fopen(file, "rb")) == NULL) {
+               FILE_OP_ERROR(file, "fopen");
+               return -1;
+       }
+
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
+               strretchomp(buf);
+               size += strlen(buf) + 2;
+       }
+
+       if (ferror(fp)) {
+               FILE_OP_ERROR(file, "fgets");
+               size = -1;
+       }
+
+       fclose(fp);
+
+       return size;
+}
+
 off_t get_left_file_size(FILE *fp)
 {
        glong pos;
@@ -1340,6 +1438,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;
@@ -1658,7 +1768,7 @@ gint copy_file(const gchar *src, const gchar *dest)
        gchar *dest_bak = NULL;
        gboolean err = FALSE;
 
-       if ((src_fp = fopen(src, "r")) == NULL) {
+       if ((src_fp = fopen(src, "rb")) == NULL) {
                FILE_OP_ERROR(src, "fopen");
                return -1;
        }
@@ -1672,7 +1782,7 @@ gint copy_file(const gchar *src, const gchar *dest)
                }
        }
 
-       if ((dest_fp = fopen(dest, "w")) == NULL) {
+       if ((dest_fp = fopen(dest, "wb")) == NULL) {
                FILE_OP_ERROR(dest, "fopen");
                fclose(src_fp);
                if (dest_bak) {
@@ -1800,6 +1910,32 @@ FILE *my_tmpfile(void)
        return tmpfile();
 }
 
+FILE *str_open_as_stream(const gchar *str)
+{
+       FILE *fp;
+       size_t len;
+
+       g_return_val_if_fail(str != NULL, NULL);
+
+       fp = my_tmpfile();
+       if (!fp) {
+               FILE_OP_ERROR("str_open_as_stream", "my_tmpfile");
+               return NULL;
+       }
+
+       len = strlen(str);
+       if (len == 0) return fp;
+
+       if (fwrite(str, len, 1, fp) != 1) {
+               FILE_OP_ERROR("str_open_as_stream", "fwrite");
+               fclose(fp);
+               return NULL;
+       }
+
+       rewind(fp);
+       return fp;
+}
+
 gint execute_async(gchar *const argv[])
 {
        pid_t pid;
@@ -1856,25 +1992,10 @@ gint execute_sync(gchar *const argv[])
 gint execute_command_line(const gchar *cmdline, gboolean async)
 {
        gchar **argv;
-       gint i;
        gint ret;
 
        argv = strsplit_with_quote(cmdline, " ", 0);
 
-       for (i = 0; argv[i] != NULL; i++) {
-               gchar *str = argv[i];
-
-               if (str[0] == '\'' || str[0] == '\"') {
-                       gint len;
-
-                       len = strlen(str);
-                       if (str[len - 1] == str[0]) {
-                               str[len - 1] = '\0';
-                               memmove(str, str + 1, len - 1);
-                       }
-               }
-       }
-
        if (async)
                ret = execute_async(argv);
        else
@@ -2027,16 +2148,16 @@ time_t remote_tzoffset_sec(const gchar *zone)
        gchar *p;
        gchar c;
        gint iustz;
-       gint h, m;
+       gint offset;
        time_t remoteoffset;
 
        strncpy(zone3, zone, 3);
        zone3[3] = '\0';
        remoteoffset = 0;
 
-       if (sscanf(zone, "%c%2d%2d", &c, &h, &m) == 3 &&
+       if (sscanf(zone, "%c%d", &c, &offset) == 2 &&
            (c == '+' || c == '-')) {
-               remoteoffset = ((h * 60) + m) * 60;
+               remoteoffset = ((offset / 100) * 60 + (offset % 100)) * 60;
                if (c == '-')
                        remoteoffset = -remoteoffset;
        } else if (!strncmp(zone, "UT" , 2) ||
@@ -2169,7 +2290,7 @@ static FILE *log_fp = NULL;
 void set_log_file(const gchar *filename)
 {
        if (log_fp) return;
-       log_fp = fopen(filename, "w");
+       log_fp = fopen(filename, "wb");
        if (!log_fp)
                FILE_OP_ERROR(filename, "fopen");
 }