fix 'underquoted definition' warnings in ac/*.m4; src/common/utils.c, subject_get_pre...
[claws.git] / src / common / utils.c
index d8a7d15eedcd2ee8420fdb7e00a8e4047f26b169..c94585de0dd1e76ea2bcbd51df503cdcd9dba101 100644 (file)
@@ -1039,6 +1039,12 @@ void subst_for_filename(gchar *str)
        subst_chars(str, " \t\r\n\"/\\", '_');
 }
 
+void subst_for_shellsafe_filename(gchar *str)
+{
+       subst_for_filename(str);
+       subst_chars(str, "|&;()<>'!{}[]",'_');
+}
+
 gboolean is_header_line(const gchar *str)
 {
        if (str[0] == ':') return FALSE;
@@ -1767,6 +1773,34 @@ gboolean is_file_entry_exist(const gchar *file)
        return TRUE;
 }
 
+gboolean dirent_is_regular_file(struct dirent *d)
+{
+       struct stat s;
+
+#ifdef HAVE_DIRENT_D_TYPE
+       if (d->d_type == DT_REG)
+               return TRUE;
+       else if (d->d_type != DT_UNKNOWN)
+               return FALSE;
+#endif
+
+       return (stat(d->d_name, &s) == 0 && S_ISREG(s.st_mode));
+}
+
+gboolean dirent_is_directory(struct dirent *d)
+{
+       struct stat s;
+
+#ifdef HAVE_DIRENT_D_TYPE
+       if (d->d_type == DT_DIR)
+               return TRUE;
+       else if (d->d_type != DT_UNKNOWN)
+               return FALSE;
+#endif
+
+       return (stat(d->d_name, &s) == 0 && S_ISDIR(s.st_mode));
+}
+
 gint change_dir(const gchar *dir)
 {
        gchar *prevdir = NULL;
@@ -2076,14 +2110,9 @@ gint remove_dir_recursive(const gchar *dir)
                    !strcmp(d->d_name, ".."))
                        continue;
 
-               if (stat(d->d_name, &s) < 0) {
-                       FILE_OP_ERROR(d->d_name, "stat");
-                       continue;
-               }
-
                /* g_print("removing %s\n", d->d_name); */
 
-               if (S_ISDIR(s.st_mode)) {
+               if (dirent_is_directory(d)) {
                        if (remove_dir_recursive(d->d_name) < 0) {
                                g_warning("can't remove directory\n");
                                return -1;
@@ -3357,7 +3386,8 @@ int subject_get_prefix_length(const gchar *subject)
                "Antwort\\:",                   /* "Antwort:" (German Lotus Notes) */
                "Res\\:",                       /* "Res:" (Brazilian Outlook) */
                "Fw\\:",                        /* "Fw:" Forward */
-               "Enc\\:"                        /* "Enc:" Forward (Brazilian Outlook) */
+               "Enc\\:",                       /* "Enc:" Forward (Brazilian Outlook) */
+               "Odp\\:"                        /* "Odp:" Re (Polish Outlook) */
                /* add more */
        };
        const int PREFIXES = sizeof prefixes / sizeof prefixes[0];
@@ -3454,6 +3484,7 @@ gchar *expand_search_string(const gchar *search_string)
                { "T",  "marked",                       0,      FALSE,  FALSE },
                { "U",  "unread",                       0,      FALSE,  FALSE },
                { "x",  "header \"References\"",        1,      TRUE,   TRUE  },
+               { "X",  "test",                         1,      FALSE,  FALSE }, 
                { "y",  "header \"X-Label\"",           1,      TRUE,   TRUE  },
                { "&",  "&",                            0,      FALSE,  FALSE },
                { "|",  "|",                            0,      FALSE,  FALSE },
@@ -3643,3 +3674,106 @@ gchar *generate_msgid(const gchar *address, gchar *buf, gint len)
        g_free(addr);
        return buf;
 }
+
+
+/*
+   quote_cmd_argument()
+   
+   return a quoted string safely usable in argument of a command.
+   
+   code is extracted and adapted from etPan! project -- DINH V. HoĆ .
+*/
+
+gint quote_cmd_argument(gchar * result, guint size,
+                       const gchar * path)
+{
+       const gchar * p;
+       gchar * result_p;
+       guint remaining;
+
+       result_p = result;
+       remaining = size;
+
+       for(p = path ; * p != '\0' ; p ++) {
+
+               if (isalnum(* p) || (* p == '/')) {
+                       if (remaining > 0) {
+                               * result_p = * p;
+                               result_p ++; 
+                               remaining --;
+                       }
+                       else {
+                               result[size - 1] = '\0';
+                               return -1;
+                       }
+               }
+               else { 
+                       if (remaining >= 2) {
+                               * result_p = '\\';
+                               result_p ++; 
+                               * result_p = * p;
+                               result_p ++; 
+                               remaining -= 2;
+                       }
+                       else {
+                               result[size - 1] = '\0';
+                               return -1;
+                       }
+               }
+       }
+       if (remaining > 0) {
+               * result_p = '\0';
+       }
+       else {
+               result[size - 1] = '\0';
+               return -1;
+       }
+  
+       return 0;
+}
+
+typedef struct 
+{
+       GNode           *parent;
+       GNodeMapFunc     func;
+       gpointer         data;
+} GNodeMapData;
+
+static void g_node_map_recursive(GNode *node, gpointer data)
+{
+       GNodeMapData *mapdata = (GNodeMapData *) data;
+       GNode *newnode;
+       GNodeMapData newmapdata;
+       gpointer newdata;
+
+       newdata = mapdata->func(node->data, mapdata->data);
+       if (newdata != NULL) {
+               newnode = g_node_new(newdata);
+               g_node_append(mapdata->parent, newnode);
+
+               newmapdata.parent = newnode;
+               newmapdata.func = mapdata->func;
+               newmapdata.data = mapdata->data;
+
+               g_node_children_foreach(node, G_TRAVERSE_ALL, g_node_map_recursive, &newmapdata);
+       }
+}
+
+GNode *g_node_map(GNode *node, GNodeMapFunc func, gpointer data)
+{
+       GNode *root;
+       GNodeMapData mapdata;
+
+       g_return_val_if_fail(node != NULL, NULL);
+       g_return_val_if_fail(func != NULL, NULL);
+
+       root = g_node_new(func(node->data, data));
+
+       mapdata.parent = root;
+       mapdata.func = func;
+       mapdata.data = data;
+
+       g_node_children_foreach(node, G_TRAVERSE_ALL, g_node_map_recursive, &mapdata);
+
+       return root;
+}