sync with sylpheed 0.5.0pre1 release
[claws.git] / src / utils.c
index 5052db1d9dbb82741d5f9f1412b4a3d5bfda96fa..30fece025c03c93f311efdcd60a08728c87e37b5 100644 (file)
@@ -106,13 +106,20 @@ gint to_number(const gchar *nstr)
        return atoi(nstr);
 }
 
+/* convert integer into string,
+   nstr must be not lower than 11 characters length */
+gchar *itos_buf(gchar *nstr, gint n)
+{
+       g_snprintf(nstr, 11, "%d", n);
+       return nstr;
+}
+
 /* convert integer into string */
 gchar *itos(gint n)
 {
        static gchar nstr[11];
 
-       g_snprintf(nstr, 11, "%d", n);
-       return nstr;
+       return itos_buf(nstr, n);
 }
 
 gchar *to_human_readable(off_t size)
@@ -183,6 +190,21 @@ gchar *strretchomp(gchar *str)
        return str;
 }
 
+/* remove trailing character */
+gchar *strtailchomp(gchar *str, gchar tail_char)
+{
+       register gchar *s;
+
+       if (!*str) return str;
+       if (tail_char == '\0') return str;
+
+       for (s = str + strlen(str) - 1; s >= str && *s == tail_char; s--)
+               *s = '\0';
+
+       return str;
+}
+
+
 /* Similar to `strstr' but this function ignores the case of both strings.  */
 gchar *strcasestr(const gchar *haystack, const gchar *needle)
 {
@@ -551,6 +573,35 @@ void extract_parenthesis(gchar *str, gchar op, gchar cl)
        *destp = '\0';
 }
 
+void extract_one_parenthesis_with_skip_quote(gchar *str, gchar quote_chr,
+                                            gchar op, gchar cl)
+{
+       register gchar *srcp, *destp;
+       gint in_brace;
+       gboolean in_quote = FALSE;
+
+       srcp = destp = str;
+
+       if ((srcp = strchr_with_skip_quote(destp, quote_chr, op))) {
+               memmove(destp, srcp + 1, strlen(srcp));
+               in_brace = 1;
+               while(*destp) {
+                       if (*destp == op && !in_quote)
+                               in_brace++;
+                       else if (*destp == cl && !in_quote)
+                               in_brace--;
+                       else if (*destp == quote_chr)
+                               in_quote ^= TRUE;
+
+                       if (in_brace == 0)
+                               break;
+
+                       destp++;
+               }
+       }
+       *destp = '\0';
+}
+
 void extract_parenthesis_with_skip_quote(gchar *str, gchar quote_chr,
                                         gchar op, gchar cl)
 {
@@ -560,7 +611,7 @@ void extract_parenthesis_with_skip_quote(gchar *str, gchar quote_chr,
 
        srcp = destp = str;
 
-       while ((srcp = strchr_with_skip_quote(destp, '"', op))) {
+       while ((srcp = strchr_with_skip_quote(destp, quote_chr, op))) {
                if (destp > str)
                        *destp++ = ' ';
                memmove(destp, srcp + 1, strlen(srcp));
@@ -817,6 +868,24 @@ void remove_space(gchar *str)
        }
 }
 
+void unfold_line(gchar *str)
+{
+       register gchar *p = str;
+       register gint spc;
+
+       while (*p) {
+               if (*p == '\n' || *p == '\r') {
+                       *p++ = ' ';
+                       spc = 0;
+                       while (isspace(*(p + spc)))
+                               spc++;
+                       if (spc)
+                               memmove(p, p + spc, strlen(p + spc) + 1);
+               } else
+                       p++;
+       }
+}
+
 void subst_char(gchar *str, gchar orig, gchar subst)
 {
        register gchar *p = str;
@@ -1092,6 +1161,17 @@ gchar *get_imap_cache_dir(void)
        return imap_cache_dir;
 }
 
+gchar *get_mbox_cache_dir(void)
+{
+       static gchar *mbox_cache_dir = NULL;
+
+       if (!mbox_cache_dir)
+               mbox_cache_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+                                            MBOX_CACHE_DIR, NULL);
+
+       return mbox_cache_dir;
+}
+
 gchar *get_mime_tmp_dir(void)
 {
        static gchar *mime_tmp_dir = NULL;
@@ -1144,6 +1224,33 @@ off_t get_file_size(const gchar *file)
        return s.st_size;
 }
 
+off_t get_left_file_size(FILE *fp)
+{
+       glong pos;
+       glong end;
+       off_t size;
+
+       if ((pos = ftell(fp)) < 0) {
+               perror("ftell");
+               return -1;
+       }
+       if (fseek(fp, 0L, SEEK_END) < 0) {
+               perror("fseek");
+               return -1;
+       }
+       if ((end = ftell(fp)) < 0) {
+               perror("fseek");
+               return -1;
+       }
+       size = end - pos;
+       if (fseek(fp, pos, SEEK_SET) < 0) {
+               perror("fseek");
+               return -1;
+       }
+
+       return size;
+}
+
 gboolean file_exist(const gchar *file, gboolean allow_fifo)
 {
        struct stat s;
@@ -1270,6 +1377,51 @@ gint remove_all_files(const gchar *dir)
        return 0;
 }
 
+gint remove_numbered_files(const gchar *dir, guint first, guint last)
+{
+       DIR *dp;
+       struct dirent *d;
+       gchar *prev_dir;
+       gint fileno;
+
+       prev_dir = g_get_current_dir();
+
+       if (chdir(dir) < 0) {
+               FILE_OP_ERROR(dir, "chdir");
+               return -1;
+       }
+
+       if ((dp = opendir(".")) == NULL) {
+               FILE_OP_ERROR(dir, "opendir");
+               return -1;
+       }
+
+       while ((d = readdir(dp)) != NULL) {
+               fileno = to_number(d->d_name);
+               if (fileno >= 0 && first <= fileno && fileno <= last) {
+                       if (unlink(d->d_name) < 0)
+                               FILE_OP_ERROR(d->d_name, "unlink");
+               }
+       }
+
+       closedir(dp);
+
+       if (chdir(prev_dir) < 0) {
+               FILE_OP_ERROR(prev_dir, "chdir");
+               g_free(prev_dir);
+               return -1;
+       }
+
+       g_free(prev_dir);
+
+       return 0;
+}
+
+gint remove_all_numbered_files(const gchar *dir)
+{
+       return remove_numbered_files(dir, 0, UINT_MAX);
+}
+
 gint remove_dir_recursive(const gchar *dir)
 {
        struct stat s;
@@ -1519,6 +1671,27 @@ gint copy_file(const gchar *src, const gchar *dest)
        return 0;
 }
 
+gint move_file(const gchar *src, const gchar *dest)
+{
+       if (is_file_exist(dest)) {
+               g_warning(_("move_file(): file %s already exists."), dest);
+               return -1;
+       }
+
+       if (rename(src, dest) == 0) return 0;
+
+       if (EXDEV != errno) {
+               FILE_OP_ERROR(src, "rename");
+               return -1;
+       }
+
+       if (copy_file(src, dest) < 0) return -1;
+
+       unlink(src);
+
+       return 0;
+}
+
 gint change_file_mode_rw(FILE *fp, const gchar *file)
 {
 #if HAVE_FCHMOD