This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository efm2.
View the commit online.
commit 3e70c488c48a8f48ee55b7cf687ebde681377843
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
AuthorDate: Tue May 21 17:41:39 2024 +0100
move file list to stdin to fs op cmd
---
src/backends/default/fs.c | 13 ++--
src/backends/default/fs.h | 8 +--
src/backends/default/meson.build | 2 +
src/backends/default/mv.c | 141 ++++++++++++++++++++++++++++-----------
src/backends/default/open.c | 71 ++++++++++++++------
src/backends/default/status.c | 2 +
src/shared/esc.c | 66 ++++++++++++++++++
src/shared/esc.h | 7 ++
8 files changed, 239 insertions(+), 71 deletions(-)
diff --git a/src/backends/default/fs.c b/src/backends/default/fs.c
index 06f6216..491037e 100644
--- a/src/backends/default/fs.c
+++ b/src/backends/default/fs.c
@@ -70,7 +70,7 @@ _err: \
}
static void
-error_ok_pos(const char *src, const char *op, const char *str)
+error_ok_pos(const char *src EINA_UNUSED, const char *op, const char *str)
{
Eina_Strbuf *buf = error_strbuf_new(op);
@@ -247,12 +247,9 @@ fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err, Eina_Bool cp,
if ((!src) || (!dst) || (strlen(src) < 1)) return EINA_FALSE;
- // first count how much work needs doing
- if (!fs_scan(src)) return EINA_FALSE;
-
- if (rm && cp) op = "Move";
- else if (!rm && cp) op = "Copy";
- else if (rm && !cp) op = "Delete";
+ if ( rm && cp) op = "Move";
+ else if (!rm && cp) op = "Copy";
+ else if ( rm && !cp) op = "Delete";
old_umask = umask(0);
if (lstat(src, &st) != 0)
@@ -466,3 +463,5 @@ fs_mv(const char *src, const char *dst, Eina_Bool report_err)
status_pos(1, src);
return res;
}
+
+// add fs_cp() fs_rm() fs_trash() fs_rename()
\ No newline at end of file
diff --git a/src/backends/default/fs.h b/src/backends/default/fs.h
index cb50630..c60b212 100644
--- a/src/backends/default/fs.h
+++ b/src/backends/default/fs.h
@@ -2,9 +2,9 @@
#define FS_H
#include <Eina.h>
-Eina_Bool fs_scan(const char *src);
-Eina_Bool fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err,
- Eina_Bool cp, Eina_Bool rm);
-Eina_Bool fs_mv(const char *src, const char *dst, Eina_Bool report_err);
+Eina_Bool fs_scan(const char *src);
+Eina_Bool fs_cp_rm(const char *src, const char *dst, Eina_Bool report_err,
+ Eina_Bool cp, Eina_Bool rm);
+Eina_Bool fs_mv(const char *src, const char *dst, Eina_Bool report_err);
#endif
\ No newline at end of file
diff --git a/src/backends/default/meson.build b/src/backends/default/meson.build
index c464309..b2f1749 100644
--- a/src/backends/default/meson.build
+++ b/src/backends/default/meson.build
@@ -9,6 +9,7 @@ inc = include_directories(
executable('open', [
'../../shared/cmd.c',
'../../shared/sha.c',
+ '../../shared/esc.c',
'../../backends/common/fs_backend_core.c',
'open.c',
'meta.c'
@@ -36,6 +37,7 @@ executable('thumb', [
install_dir: dir)
executable('mv', [
'../../shared/sha.c',
+ '../../shared/esc.c',
'fs.c',
'mv.c',
'meta.c',
diff --git a/src/backends/default/mv.c b/src/backends/default/mv.c
index 3cfe971..73b4b0c 100644
--- a/src/backends/default/mv.c
+++ b/src/backends/default/mv.c
@@ -14,23 +14,76 @@
#include "meta.h"
#include "status.h"
#include "fs.h"
+#include "esc.h"
static const char *config_dir = NULL;
+typedef struct _File_Set
+{
+ const char *src, *dst;
+} File_Set;
+
+static void
+mem_abort(void)
+{
+ fprintf(stderr, "Out of memory!\n");
+ abort();
+}
+
+static Eina_List *
+file_set_add(Eina_List *files, const char *src, const char *dst)
+{
+ File_Set *fs = calloc(1, sizeof(File_Set));
+ if (!fs) mem_abort();
+ fs->src = ""
+ fs->dst = eina_stringshare_add(dst);
+ if ((!fs->src) || (!fs->dst)) mem_abort();
+ files = eina_list_append(files, fs);
+ return files;
+}
+
int
main(int argc, char **argv)
-{ // mv [src] [dst]
- const char *src, *dst, *fname, *home_dir;
+{ // mv [src] [dstdir]
+ const char *fname, *home_dir;
Eina_Strbuf *buf = NULL;
+ Eina_List *files = NULL, *l;
+ File_Set *fs;
+ size_t sz;
+ char *src = "" *dst = NULL;
+ char sbuf[4096 + 256];
- if (argc < 3) return -1;
- src = ""
- dst = argv[2];
eina_init();
eet_init();
ecore_init();
efreet_init();
+ for (;;)
+ { // read stdin of key=val\n ... or end\n
+ if (!fgets(sbuf, sizeof(sbuf), stdin)) break;
+ sz = strlen(sbuf);
+ if (sz < 1) break; // too small
+ if (sbuf[sz - 1] == '\n') sbuf[sz - 1] = '\0'; // remove \n if there
+ if (!strncmp(sbuf, "src="" 4))
+ {
+ if (src) free(src);
+ src = "" + 4);
+ }
+ else if (!strncmp(sbuf, "dst=", 4))
+ {
+ if (dst) free(dst);
+ dst = unescape(sbuf + 4);
+ if ((src) && (dst)) files = file_set_add(files, src, dst);
+ if (src) free(src);
+ if (dst) free(dst);
+ src = ""
+ dst = NULL;
+ }
+ else if (!strcmp(sbuf, "end")) break;
+ }
+ if (src) free(src);
+ if (dst) free(dst);
+
config_dir = getenv("E_HOME_DIR");
home_dir = getenv("HOME");
if (!home_dir) return 77; // no $HOME? definitely an error!
@@ -43,47 +96,59 @@ main(int argc, char **argv)
}
meta_init(config_dir);
- fname = ecore_file_file_get(src);
- if (!fname) goto err;
buf = eina_strbuf_new();
if (!buf) goto err;
- eina_strbuf_append(buf, dst);
- eina_strbuf_append(buf, "/");
- eina_strbuf_append(buf, fname);
+
status_begin();
- if (fs_mv(src, eina_strbuf_string_get(buf), EINA_TRUE))
- {
- Eina_Bool src_can_write, dst_can_write;
- const char *dstfile;
- char *src_meta, *dst_meta;
+ EINA_LIST_FOREACH(files, l, fs)
+ {
+ if (strlen(fs->src) < 1) goto err2;
+ if (!fs_scan(fs->src)) goto err2;
+ }
- dstfile = eina_strbuf_string_get(buf);
-
- src_can_write = meta_path_can_write(src);
- dst_can_write = meta_path_can_write(eina_strbuf_string_get(buf));
+ EINA_LIST_FOREACH(files, l, fs)
+ {
+ fname = ecore_file_file_get(fs->src);
+ if (!fname) break;
+ eina_strbuf_reset(buf);
+ eina_strbuf_append(buf, fs->dst);
+ eina_strbuf_append(buf, "/");
+ eina_strbuf_append(buf, fname);
+ if (fs_mv(fs->src, eina_strbuf_string_get(buf), EINA_TRUE))
+ {
+ Eina_Bool src_can_write, dst_can_write;
+ const char *dstfile;
+ char *src_meta, *dst_meta;
- if (src_can_write) src_meta = meta_path_find(src, "meta.efm");
- else src_meta = meta_path_user_find(src, "meta.efm");
- if (dst_can_write) dst_meta = meta_path_find(dstfile, "meta.efm");
- else dst_meta = meta_path_user_find(dstfile, "meta.efm");
- if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
- fs_mv(src_meta, dst_meta, EINA_FALSE);
- free(src_meta);
- free(dst_meta);
- if (src_can_write) src_meta = meta_path_find(src, "thumb.efm");
- else src_meta = meta_path_user_find(src, "thumb.efm");
- if (dst_can_write) dst_meta = meta_path_find(dstfile, "thumb.efm");
- else dst_meta = meta_path_user_find(dstfile, "thumb.efm");
- if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
- fs_mv(src_meta, dst_meta, EINA_FALSE);
- free(src_meta);
- free(dst_meta);
- }
- else status_end();
+ dstfile = eina_strbuf_string_get(buf);
+
+ src_can_write = meta_path_can_write(fs->src);
+ dst_can_write = meta_path_can_write(eina_strbuf_string_get(buf));
+
+ if (src_can_write) src_meta = meta_path_find(fs->src, "meta.efm");
+ else src_meta = meta_path_user_find(fs->src, "meta.efm");
+ if (dst_can_write) dst_meta = meta_path_find(dstfile, "meta.efm");
+ else dst_meta = meta_path_user_find(dstfile, "meta.efm");
+ if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
+ fs_mv(src_meta, dst_meta, EINA_FALSE);
+ free(src_meta);
+ free(dst_meta);
+ if (src_can_write) src_meta = meta_path_find(fs->src, "thumb.efm");
+ else src_meta = meta_path_user_find(fs->src, "thumb.efm");
+ if (dst_can_write) dst_meta = meta_path_find(dstfile, "thumb.efm");
+ else dst_meta = meta_path_user_find(dstfile, "thumb.efm");
+ if ((src_meta) && (dst_meta) && (meta_path_prepare(dstfile)))
+ fs_mv(src_meta, dst_meta, EINA_FALSE);
+ free(src_meta);
+ free(dst_meta);
+ }
+ else break;
+ }
+err2:
+ status_end();
err:
if (buf) eina_strbuf_free(buf);
- status_end();
meta_shutdown();
diff --git a/src/backends/default/open.c b/src/backends/default/open.c
index 6e97f87..0ea4de8 100644
--- a/src/backends/default/open.c
+++ b/src/backends/default/open.c
@@ -21,6 +21,7 @@
#include "sha.h"
#include "meta.h"
#include "thumb_check.h"
+#include "esc.h"
static const char *icon_theme = NULL;
static const char *config_dir = NULL;
@@ -1233,33 +1234,48 @@ _path_in_mon_dir(const char *path)
}
static void
-_op_run(const char *op, const char *src, const char *dst)
+_op_run(const char *op, Eina_List *files, const char *dst)
{
Eina_Strbuf *buf;
const char *s;
+ char *str;
+ Eina_List *l;
+ Ecore_Exe *exe;
- buf = eina_strbuf_new();
- s = getenv("EFM_BACKEND_DIR");
+ buf = eina_strbuf_new();
+ s = getenv("EFM_BACKEND_DIR");
if (!s) return;
eina_strbuf_append(buf, s);
eina_strbuf_append(buf, "/");
eina_strbuf_append(buf, op);
- eina_strbuf_append(buf, " ");
- _strbuf_append_file_escaped(buf, src);
- if (dst)
- {
- eina_strbuf_append(buf, " ");
- _strbuf_append_file_escaped(buf, dst);
- }
- fprintf(stderr, "OP: [%s]\n", eina_strbuf_string_get(buf));
- ecore_exe_run(eina_strbuf_string_get(buf), NULL);
+ fprintf(stderr, "OP: op [%s]\n", eina_strbuf_string_get(buf));
+ exe = ecore_exe_pipe_run(eina_strbuf_string_get(buf), ECORE_EXE_PIPE_WRITE,
+ NULL);
+ eina_strbuf_reset(buf);
+ EINA_LIST_FOREACH(files, l, s)
+ {
+ fprintf(stderr, "OP [%s] -> [%s]\n", s, dst);
+ eina_strbuf_append(buf, "src=""
+ str = escape(s);
+ eina_strbuf_append(buf, str);
+ free(str);
+ eina_strbuf_append(buf, "\ndst=");
+ str = escape(dst);
+ eina_strbuf_append(buf, str);
+ free(str);
+ eina_strbuf_append(buf, "\n");
+ }
+ eina_strbuf_append(buf, "end\n");
+ ecore_exe_send(exe, eina_strbuf_string_get(buf), eina_strbuf_length_get(buf));
eina_strbuf_free(buf);
}
static void
-_handle_drop_paste(const char *over, const char *action, const char *path)
+_handle_drop_paste(const char *over, const char *action, Eina_List *files)
{
+ const char *path;
const char *mondir;
+ Eina_List *l;
if (!mon) return;
mondir = ecore_file_monitor_path_get(mon);
@@ -1268,26 +1284,29 @@ _handle_drop_paste(const char *over, const char *action, const char *path)
{ // if you are dropping over a dir then spin up a sub open and pass
// the dnd to it
Eina_Strbuf *strbuf;
- Sub *sub;
+ Sub *sub;
sub = _sub_find(over);
if (!sub) sub = _sub_open(over, "default");
strbuf = cmd_strbuf_new("dnd-drop");
cmd_strbuf_append(strbuf, "action", action);
- cmd_strbuf_append(strbuf, "path", path);
+ EINA_LIST_FOREACH(files, l, path)
+ {
+ fprintf(stderr, "DROP in [%s] over=[%s] action="" > [%s]\n", mondir,
+ over, action, path);
+ cmd_strbuf_append(strbuf, "path", path);
+ }
_sub_cmd_send(sub, strbuf);
- fprintf(stderr, "DROP in [%s] over=[%s] action="" > [%s]\n",
- mondir, over, action, path);
}
else
{
- fprintf(stderr, "DROP in [%s] action="" > [%s]\n", mondir, action,
- path);
if ((!action) || (!strcmp(action, "copy")))
{ // XXX: implement
}
else if (!strcmp(action, "move"))
- _op_run("mv", path, mondir);
+ {
+ _op_run("mv", files, mondir);
+ }
else if (!strcmp(action, "ask"))
{ // XXX: implement
}
@@ -1409,6 +1428,8 @@ do_handle_cmd(Cmd *c)
{ // "over" key means dnd was on that dir
const char *over = cmd_key_find(c, "over");
const char *action = "" "action");
+ Eina_List *files = NULL;
+ const char *s;
KEY_WALK_BEGIN
{
@@ -1417,12 +1438,18 @@ do_handle_cmd(Cmd *c)
if (!over)
{
if (!_path_in_mon_dir(data))
- _handle_drop_paste(over, action, data);
+ files = eina_list_append(files, eina_stringshare_add(data));
}
- else _handle_drop_paste(over, action, data);
+ else
+ files = eina_list_append(files, eina_stringshare_add(data));
}
}
KEY_WALK_END
+ if (files)
+ {
+ _handle_drop_paste(over, action, files);
+ EINA_LIST_FREE(files, s) eina_stringshare_del(s);
+ }
}
else if (!strcmp(c->command, "cnp-paste"))
{ // XXX: implement
diff --git a/src/backends/default/status.c b/src/backends/default/status.c
index 973e275..8501e39 100644
--- a/src/backends/default/status.c
+++ b/src/backends/default/status.c
@@ -2,7 +2,9 @@
#define EFL_BETA_API_SUPPORT 1
// for vasprintf()
#define _GNU_SOURCE
+
#include "status.h"
+
#include <Eina.h>
#include <Ecore_File.h>
#include <fcntl.h>
diff --git a/src/shared/esc.c b/src/shared/esc.c
new file mode 100644
index 0000000..27a8493
--- /dev/null
+++ b/src/shared/esc.c
@@ -0,0 +1,66 @@
+#include <Eina.h>
+#include <ctype.h>
+
+#include "esc.h"
+
+
+static inline int
+_xtov(char x)
+{
+ if ((x >= '0') && (x <= '9')) return x - '0';
+ if ((x >= 'a') && (x <= 'f')) return 10 + (x - 'a');
+ if ((x >= 'A') && (x <= 'F')) return 10 + (x - 'A');
+ return 0;
+}
+
+char *
+escape(const char *src_in)
+{
+ Eina_Strbuf *strbuf = eina_strbuf_new();
+ char *str;
+ const char *s;
+
+ for (s = src_in; *s; s++)
+ {
+ if ((*s <= ',') || (*s == '%') || ((*s >= ':') && (*s <= '@'))
+ || ((*s >= '[') && (*s <= '`')) || (*s >= '{'))
+ {
+ unsigned char tmp;
+
+ tmp = s[0];
+ eina_strbuf_append_printf(strbuf, "%%%02x", tmp);
+ }
+ else eina_strbuf_append_char(strbuf, *s);
+ }
+ str = eina_strbuf_string_steal(strbuf);
+ eina_strbuf_free(strbuf);
+ return str;
+}
+
+char *
+unescape(const char *src_in)
+{
+ char *dest = malloc(strlen(src_in) + 1);
+ char *d;
+ const char *s;
+
+ for (d = dest, s = src_in; *s; d++)
+ {
+ if ((s[0] == '%') && (!isspace(s[1])))
+ {
+ if ((s[1]) && (s[2]))
+ {
+ *d = (_xtov(s[1]) << 4) | (_xtov(s[2]));
+ s += 3;
+ }
+ else s++;
+ }
+ else
+ {
+ *d = s[0];
+ s++;
+ }
+ }
+ *d = 0;
+ return dest;
+}
\ No newline at end of file
diff --git a/src/shared/esc.h b/src/shared/esc.h
new file mode 100644
index 0000000..a2effe7
--- /dev/null
+++ b/src/shared/esc.h
@@ -0,0 +1,7 @@
+#ifndef ESC_H
+#define ESC_H 1
+
+char *escape(const char *src_in);
+char *unescape(const char *src_in);
+
+#endif
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.