newsgroups dialog / enhanced mailto
[claws.git] / src / utils.c
index a742ed5702fe0beb4249365f9dd85ef124750c45..1f4dc6abdea4f70b71f470ad318055546be3acd6 100644 (file)
@@ -136,26 +136,15 @@ gchar *itos(gint n)
 gchar *to_human_readable(off_t size)
 {
        static gchar str[10];
-       gint count;
-       guint32 div = 1;
 
-       for (count = 0; count < 3; count++) {
-               if (size / div < 1024)
-                       break;
-               else
-                       div *= 1024;
-       }
-
-       switch (count) {
-       case 0: g_snprintf(str, sizeof(str), "%dB",    (gint)size);   break;
-       case 1: g_snprintf(str, sizeof(str), "%.1fKB", (gfloat)size / div);
-               break;
-       case 2: g_snprintf(str, sizeof(str), "%.2fMB", (gfloat)size / div);
-               break;
-       default:
-               g_snprintf(str, sizeof(str), "%.2fGB", (gfloat)size / div);
-               break;
-       }
+       if (size < 1024)
+               g_snprintf(str, sizeof(str), "%dB", (gint)size);
+       else if (size >> 10 < 1024)
+               g_snprintf(str, sizeof(str), "%.1fKB", (gfloat)size / (1 << 10));
+       else if (size >> 20 < 1024)
+               g_snprintf(str, sizeof(str), "%.2fMB", (gfloat)size / (1 << 20));
+       else
+               g_snprintf(str, sizeof(str), "%.2fGB", (gfloat)size / (1 << 30));
 
        return str;
 }
@@ -169,15 +158,12 @@ gint strcmp2(const gchar *s1, const gchar *s2)
                return strcmp(s1, s2);
 }
 /* strstr with NULL-checking */
-gint strstr2(const gchar *s1, const gchar *s2)
+gchar *strstr2(const gchar *s1, const gchar *s2)
 {
        if (s1 == NULL || s2 == NULL)
-               return -1;
+               return NULL;
        else
-               if( strstr(s1, s2) !=NULL) 
-                return 0;
-                else 
-                return -1;
+               return strstr(s1, s2);
 }
 /* compare paths */
 gint path_cmp(const gchar *s1, const gchar *s2)
@@ -472,7 +458,7 @@ gboolean is_next_mbs(const wchar_t *s)
 {
        gint mbl;
        const wchar_t *wp;
-       gchar tmp[MB_CUR_MAX];
+       gchar tmp[MB_LEN_MAX];
 
        /* skip head space */
        for (wp = s; *wp != (wchar_t)0 && iswspace(*wp); wp++)
@@ -503,7 +489,6 @@ wchar_t *find_wspace(const wchar_t *s)
 /* compare subjects */
 gint subject_compare(const gchar *s1, const gchar *s2)
 {
-       gint retval;
        gchar *str1, *str2;
 
        if (!s1 || !s2) return -1;
@@ -519,14 +504,7 @@ gint subject_compare(const gchar *s1, const gchar *s2)
 
        if (!*str1 || !*str2) return -1;
 
-       retval = strcmp(str1, str2);
-       /*
-       if (retval == 0)
-               g_print("\ns1 = %s\ns2 = %s\n"
-                       "str1 = %s\nstr2 = %s\nmatched.\n",
-                       s1, s2, str1, str2);
-       */
-       return retval;
+       return strcmp(str1, str2);
 }
 
 void trim_subject(gchar *str)
@@ -1441,7 +1419,7 @@ gint remove_dir_recursive(const gchar *dir)
        struct dirent *d;
        gchar *prev_dir;
 
-       /*g_print("dir = %s\n", dir);*/
+       /* g_print("dir = %s\n", dir); */
 
        if (stat(dir, &s) < 0) {
                FILE_OP_ERROR(dir, "stat");
@@ -1459,7 +1437,7 @@ gint remove_dir_recursive(const gchar *dir)
        }
 
        prev_dir = g_get_current_dir();
-       /*g_print("prev_dir = %s\n", prev_dir);*/
+       /* g_print("prev_dir = %s\n", prev_dir); */
 
        if (!path_cmp(prev_dir, dir)) {
                g_free(prev_dir);
@@ -1494,7 +1472,7 @@ gint remove_dir_recursive(const gchar *dir)
                        continue;
                }
 
-               /*g_print("removing %s\n", d->d_name);*/
+               /* g_print("removing %s\n", d->d_name); */
 
                if (S_ISDIR(s.st_mode)) {
                        if (remove_dir_recursive(d->d_name) < 0) {
@@ -1837,25 +1815,140 @@ gint execute_command_line(const gchar *cmdline, gboolean async)
        return ret;
 }
 
+static gint is_unchanged_uri_char(char c)
+{
+  switch (c) {
+    case '(':
+    case ')':
+    case ',':
+      return 0;
+    default:
+      return 1;
+    }
+}
+
+void encode_uri(gchar * encoded_uri, gint bufsize, const gchar * uri)
+{
+       int i;
+       int k;
+
+       k = 0;
+       for(i = 0; i < strlen(uri) ; i++) {
+               if (is_unchanged_uri_char(uri[i])) {
+                       if (k + 2 >= bufsize)
+                               break;
+                       encoded_uri[k++] = uri[i];
+               }
+               else {
+                       char * hexa = "0123456789ABCDEF";
+                       
+                       if (k + 4 >= bufsize)
+                               break;
+                       encoded_uri[k++] = '%';
+                       encoded_uri[k++] = hexa[uri[i] / 16];
+                       encoded_uri[k++] = hexa[uri[i] % 16];
+               }
+       }
+       encoded_uri[k] = 0;
+}
+
+/* Converts two-digit hexadecimal to decimal.  Used for unescaping escaped 
+ * characters
+ */
+static gint axtoi(const gchar *hexstr)
+{
+       gint Hi, Lo, Result;
+       
+       Hi = hexstr[0];
+       if ('0' <= Hi && Hi <= '9') {
+               Hi -= '0';
+       } else
+               if ('a' <= Hi && Hi <= 'f') {
+                       Hi -=('a'-10);
+               } else
+                       if ('A' <= Hi && Hi <= 'F') {
+                               Hi -= ('A'-10);
+                       }
+
+       Lo = hexstr[1];
+       if ('0' <= Lo && Lo <='9') {
+               Lo -= '0';
+       } else
+               if ('a' <= Lo && Lo <= 'f') {
+                       Lo -= ('a'-10);
+               } else
+                       if ('A' <= Lo && Lo <= 'F') {
+                               Lo -= ('A'-10);
+                       }
+       Result = Lo + (16 * Hi);
+       return (Result);
+}
+
+
+/* Decodes URL-Encoded strings (i.e. strings in which spaces are replaced by
+ * plusses, and escape characters are used)
+ */
+
+void decode_uri(gchar * decoded_uri, const gchar * encoded_uri)
+{
+       const gchar * encoded;
+       gchar * decoded;
+
+       //      strcpy(decoded_uri, encoded_uri);
+       //      subst_char(decoded_uri, '+', ' ');
+       
+       encoded = encoded_uri;
+       decoded = decoded_uri;
+
+       while (* encoded) {
+               if (* encoded == '%') {
+                       encoded ++;
+                       if (isxdigit(encoded[0])
+                           && isxdigit(encoded[1])) {
+                               * decoded = (gchar) axtoi(encoded);
+                               decoded ++;
+                               encoded += 2;
+                       }
+               }
+               else if (* encoded == '+') {
+                       * decoded = ' ';
+                       decoded ++;
+                       encoded ++;
+               }
+               else {
+                       * decoded = * encoded;
+                       decoded ++;
+                       encoded ++;
+               }
+       }
+
+       * decoded = '\0';
+}
+
+
 gint open_uri(const gchar *uri, const gchar *cmdline)
 {
        static gchar *default_cmdline = "netscape -remote openURL(%s,raise)";
        gchar buf[BUFFSIZE];
        gchar *p;
-
+       gchar encoded_uri[BUFFSIZE];
+       
        g_return_val_if_fail(uri != NULL, -1);
 
+       /* an option to choose whether to use encode_uri or not ? */
+       encode_uri(encoded_uri, BUFFSIZE, uri);
+       
        if (cmdline &&
            (p = strchr(cmdline, '%')) && *(p + 1) == 's' &&
            !strchr(p + 2, '%'))
-               g_snprintf(buf, sizeof(buf), cmdline, uri);
+               g_snprintf(buf, sizeof(buf), cmdline, encoded_uri);
        else {
                if (cmdline)
                        g_warning(_("Open URI command line is invalid: `%s'"),
                                  cmdline);
-               g_snprintf(buf, sizeof(buf), default_cmdline, uri);
+               g_snprintf(buf, sizeof(buf), default_cmdline, encoded_uri);
        }
-
+       
        execute_command_line(buf, TRUE);
 
        return 0;