policy change and work with where file meta info is stored
so i've been thinking... yes it's annoying but there are reasons. it's a balance. time to change this as well as centralize it meta info is stuff like the xxx.meta.efm files that can store icon x,y and width x height (and any number of other things - they are .ini style files). thumbnails are extra meta files that contain relevant info that is auto-generated by efm's default backend. they can be large but as it's auto-generated they are xxx.thumb.efm in these separate files efm2 will now, if you own the dir and can write to it, store metadata in /path/to/dir/.efm/xxx.*.efm - so either xxx.meta.efm or xxx.thumb.efm with xxx being the matching filename in the dir. yes - this means efm will create .efm dirs in dirs you own. first - it's a hidden dir - what are you doing listing ALL files all the time and seeing it? dot files are hidden by default and convention for a reason. to allow extra metadata to live in your fs without you seeing it all the time! secondly - the data has to go somewhere and 'find ~/ -name .efm -delete' is about as easy (for such advanced users who are doing ls -a opr using find etc.) as 'rm -rf ~/.e/e/efm/*' if you want to nuke the metadata. now why do this? the principle of least surprise. you are a regular joe user who uses a filemanager and then you run some tool (from the gui) to zip/tar up some dir tree then unpack it somewhwre else... if efm doesnt store the data in that tree then then unpacked files lose their metadata. "suprise" for a user that they lost data they see visually. surprising the user less if possible by design is a good thing. creation of magic files automatically is also highly common - vim and emacs save new file~ files - and people accept it because it's been that way forever.. so a .efm dir is definitely directly in keeping with history, precedent and the principle of least surprise. not to mention .git, CVS and .svn dirs too. there is a long history of this elsewhere too. windows has Thumbs.db files. Macos has .DS_Store. AmigaOS had filename.info files. Good old xv had .xvpics dirs. it's almost expected. the reason this is done is to keep the metadata alongside the files where possible for least surprise. efm can also store it in ~/.e/e/efm/meta/ too. it will do this when the above conditions are not met (you don't own the dir or you cannot write to it). as the decision is made in one place with one function to decide if you can write, this is a single point now where policy could change this and ONLY EVER write metadata in ~/.e/e/efm/mneta no matter if you can write or not. but that'd have to be an opt-in as it then increases surprise loss of data for users as above. and i'ts a "deal with it later" thing. note - it may seem silly now like "just for some stupid thumbnails" or "stupid x/y location i never use". this WILL be used for more later. e.g. flagging files and/or dirs for use with rsync tooling later to sync files/dirs or syncthing or backup tools to auto-backup changes and so on etc. - actual functionality where you want more and more metadata stored in your filesys5tem so tools know what to do with your files. if i could use xattrs for this... i would. but i can't. they don't port between filesystems. they can't be set on symlinks and more. if i could use xattrs - you'd never SEE this data and wouldn't complain but as xattrs are limited this has to be stored in actual files. efm will "enforce" hiding of these dirs as they are highly advanced stuff in there and the only way you should (unless you like living on the cmdline and poking around) deal with these is via the efm ui (implicitly as you browse about and do things). if you live on a cmdline and like to poke - you can. oh .. i forgot.. this also adds the initla "mv" implementation... it doesn't handle all errors and cases yet... no status info and so on...
This commit is contained in:
parent
6c06a10ba5
commit
06cea493e8
|
@ -34,3 +34,12 @@ executable('thumb', [
|
|||
dependencies: deps,
|
||||
install: true,
|
||||
install_dir: dir)
|
||||
executable('mv', [
|
||||
'../../shared/sha.c',
|
||||
'mv.c',
|
||||
'meta.c'
|
||||
],
|
||||
include_directories: inc,
|
||||
dependencies: deps,
|
||||
install: true,
|
||||
install_dir: dir)
|
|
@ -3,6 +3,8 @@
|
|||
#include <Efreet.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_File.h>
|
||||
#include <fcntl.h>
|
||||
#include "eina_types.h"
|
||||
#include "sha.h"
|
||||
#include "meta.h"
|
||||
|
||||
|
@ -27,6 +29,8 @@
|
|||
// to allow scripts, tools etc. to work with and generate data etc. then
|
||||
// this is the compromise choice taken.
|
||||
|
||||
#define META_WRITE_TIMEOUT 0.2
|
||||
|
||||
typedef struct _Meta_File
|
||||
{
|
||||
const char *path; // path of original file this metadata is for
|
||||
|
@ -48,29 +52,41 @@ static Ecore_Timer *_meta_flush_timer = NULL;
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static char *
|
||||
_meta_personal_overlay_file_get(Meta_File *mf)
|
||||
{ // get secondary personal path to meta file for target path
|
||||
_meta_personal_overlay_file_path_get(const char *path, const char *extn)
|
||||
{
|
||||
unsigned char dst[20];
|
||||
char sha1[41], buf[PATH_MAX];
|
||||
|
||||
eina_sha1((unsigned char *)mf->path, strlen(mf->path), dst);
|
||||
eina_sha1((unsigned char *)path, strlen(path), dst);
|
||||
sha1_str(dst, sha1);
|
||||
snprintf(buf, sizeof(buf), "%s/efm/meta/%c%c/%s.efm", _config_dir, sha1[0],
|
||||
sha1[1], sha1 + 2);
|
||||
snprintf(buf, sizeof(buf), "%s/efm/meta/%c%c/%s.%s",
|
||||
_config_dir, sha1[0], sha1[1], sha1 + 2, extn);
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
static char *
|
||||
_meta_personal_overlay_file_get(Meta_File *mf)
|
||||
{ // get secondary personal path to meta file for target path
|
||||
return _meta_personal_overlay_file_path_get(mf->path, "meta.efm");
|
||||
}
|
||||
|
||||
static char *
|
||||
_meta_file_path_get(const char *path, const char *extn)
|
||||
{ // get primary meta file for the target path
|
||||
char *dir = ecore_file_dir_get(path);
|
||||
char buf[PATH_MAX];
|
||||
|
||||
if (!dir) return NULL;
|
||||
snprintf(buf, sizeof(buf), "%s/.efm/%s.%s",
|
||||
dir, ecore_file_file_get(path), extn);
|
||||
free(dir);
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
static char *
|
||||
_meta_file_get(Meta_File *mf)
|
||||
{ // get primy meta file for the target path
|
||||
char *dir = ecore_file_dir_get(mf->path);
|
||||
char buf[PATH_MAX];
|
||||
|
||||
if (!dir) return NULL;
|
||||
snprintf(buf, sizeof(buf), "%s/.efm/%s.efm", dir,
|
||||
ecore_file_file_get(mf->path));
|
||||
free(dir);
|
||||
return strdup(buf);
|
||||
{
|
||||
return _meta_file_path_get(mf->path, "meta.efm");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -162,7 +178,9 @@ static void
|
|||
_meta_file_write_queue(Meta_File *mf)
|
||||
{ // tag the meta file as changed and queue some writes
|
||||
if (_meta_flush_timer) ecore_timer_reset(_meta_flush_timer);
|
||||
else _meta_flush_timer = ecore_timer_add(0.2, _cb_meta_flush_timer, NULL);
|
||||
else _meta_flush_timer = ecore_timer_add(META_WRITE_TIMEOUT,
|
||||
_cb_meta_flush_timer,
|
||||
NULL);
|
||||
if (!mf->changed)
|
||||
{
|
||||
_meta_writes = eina_list_append(_meta_writes, mf);
|
||||
|
@ -298,7 +316,7 @@ meta_shutdown(void)
|
|||
|
||||
void
|
||||
meta_set(const char *path, const char *meta, const char *data)
|
||||
{ // data = NULL -> delete meta
|
||||
{ // set meta data key "meta" on ffile "Path", data = NULL -> delete meta
|
||||
Meta_File *mf = _meta_file_find(path);
|
||||
Eina_List *l;
|
||||
Meta *m;
|
||||
|
@ -332,7 +350,7 @@ meta_set(const char *path, const char *meta, const char *data)
|
|||
|
||||
Eina_Stringshare *
|
||||
meta_get(const char *path, const char *meta)
|
||||
{
|
||||
{ // get meta data key "meta" associated with file "path"
|
||||
Meta_File *mf = _meta_file_find(path);
|
||||
Eina_List *l;
|
||||
Meta *m;
|
||||
|
@ -344,3 +362,82 @@ meta_get(const char *path, const char *meta)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
meta_path_find(const char *path, const char *extn)
|
||||
{ // "path" is the file path to get the filesystem local meta file for
|
||||
return _meta_file_path_get(path, extn);
|
||||
}
|
||||
|
||||
char *
|
||||
meta_path_user_find(const char *path, const char *extn)
|
||||
{ // "path" is the target file path to get the user overlay file for
|
||||
return _meta_personal_overlay_file_path_get(path, extn);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
meta_path_prepare(const char *path)
|
||||
{ // "path" is the path returned by meta_path_user_find() or meta_path_find()
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
char *dir = ecore_file_dir_get(path);
|
||||
|
||||
if (!dir) return ret;
|
||||
if (ecore_file_is_dir(dir)) ret = EINA_TRUE;
|
||||
else
|
||||
{
|
||||
if (ecore_file_mkdir(dir)) ret = EINA_TRUE;
|
||||
else if (ecore_file_mkpath(dir)) ret = EINA_TRUE;
|
||||
}
|
||||
free(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
meta_path_can_write(const char *path)
|
||||
{ // can we write to the taget dir of "path" file for meta data?
|
||||
// yes - this is racey. but then again anything is. we could make a
|
||||
// .efm dir then have permission removed before we make the subdiors
|
||||
// or meta files. anything that involves more than a single file and
|
||||
// a single open is going to suffer - deal with it. as this is expensive
|
||||
// and modifies the fs just to test it it is a good idea to only call this
|
||||
// once when opening a dir (or doing something that may write to it)
|
||||
char buf[PATH_MAX];
|
||||
struct stat st;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
int res = 0;
|
||||
char *dir = ecore_file_dir_get(path);
|
||||
uid_t uid = getuid();
|
||||
|
||||
if (!dir) return ret;
|
||||
if (stat(dir, &st) == -1) goto err;
|
||||
// policy - we only cosider direst owned by the user writable. want to
|
||||
// avoid e.g. root browsing then modifying dirs owne by a user or dirs
|
||||
// that might have group write access being written to by multiple users
|
||||
if ((st.st_uid == uid) && (st.st_mode & S_IWUSR))
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%s/.efm", dir);
|
||||
res = mkdir(buf, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
if (res == 0)
|
||||
{ // we created the dir - remove it (if not empty) - might not need
|
||||
rmdir(buf);
|
||||
ret = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errno == EEXIST)
|
||||
{ // dir exists - test we can create a file in it
|
||||
snprintf(buf, sizeof(buf), "%s/.efm/.t", dir);
|
||||
res = open(buf, O_WRONLY | O_CREAT | O_CLOEXEC);
|
||||
if (res >= 0)
|
||||
{ // we can create and write to file - remove it now
|
||||
unlink(buf);
|
||||
close(res);
|
||||
ret = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err:
|
||||
free(dir);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,16 @@
|
|||
void meta_init(const char *config_dir);
|
||||
void meta_shutdown(void);
|
||||
void meta_set(const char *path, const char *meta, const char *data);
|
||||
#ifndef META_H
|
||||
#define META_H
|
||||
#include <Eina.h>
|
||||
|
||||
void meta_init(const char *config_dir);
|
||||
void meta_shutdown(void);
|
||||
|
||||
void meta_set(const char *path, const char *meta, const char *data);
|
||||
Eina_Stringshare *meta_get(const char *path, const char *meta);
|
||||
|
||||
char *meta_path_find(const char *path, const char *extn);
|
||||
char *meta_path_user_find(const char *path, const char *extn);
|
||||
Eina_Bool meta_path_prepare(const char *path);
|
||||
Eina_Bool meta_path_can_write(const char *path);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,176 @@
|
|||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_File.h>
|
||||
#include <Efreet.h>
|
||||
#include <Efreet_Mime.h>
|
||||
#include <Eet.h>
|
||||
|
||||
#include <asm-generic/errno-base.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "cmd.h"
|
||||
#include "eina_strbuf.h"
|
||||
#include "sha.h"
|
||||
#include "meta.h"
|
||||
|
||||
static const char *config_dir = NULL;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
// mv [src] [dst]
|
||||
const char *src, *dst, *fname, *home_dir;
|
||||
char *fdir;
|
||||
Eina_Strbuf *buf = NULL, *buf2 = NULL;
|
||||
|
||||
if (argc < 3) return -1;
|
||||
src = argv[1];
|
||||
dst = argv[2];
|
||||
eina_init();
|
||||
eet_init();
|
||||
ecore_init();
|
||||
efreet_init();
|
||||
|
||||
config_dir = getenv("E_HOME_DIR");
|
||||
home_dir = getenv("HOME");
|
||||
if (!home_dir) return 77; // no $HOME? definitely an error!
|
||||
if (!config_dir)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/.e/e", home_dir);
|
||||
config_dir = eina_stringshare_add(buf);
|
||||
}
|
||||
meta_init(config_dir);
|
||||
|
||||
// src = SDIR/SFILE
|
||||
// dst = DDIR/
|
||||
//
|
||||
// mv SDIR/SFILE DDIR/SFILE
|
||||
// if errno == EXDEV
|
||||
// cp SDIR/SFILE DDIR/SFILE
|
||||
// rm SDIR/SFILE
|
||||
// else if errno == 0
|
||||
// if exists SDIR/.efm/SFILE.efm
|
||||
// mkdir DDIR/.efm
|
||||
// mv SDIR/.efm/SFILE.efm DDIR/.efm/SFILE.efm
|
||||
|
||||
// status in
|
||||
// EFMDIR/status/uuid.status
|
||||
//
|
||||
// status file:
|
||||
// uuid (UUID) # uuid repeated from filename
|
||||
// pid (PID) @ pid of task
|
||||
// type (operation type - mv, cp, rm, ...) # op type
|
||||
// busy (0/1) # show a busy spinner instead of progress
|
||||
// progress (0-100) # show a progress bar 0-100 percent
|
||||
// title (some title string to show)
|
||||
// label (somt string to show) # show this string
|
||||
// icon (some icon name or full path to file)
|
||||
// ---
|
||||
//
|
||||
// check /proc/PID/cmdline so argv[1] is same uuid
|
||||
// write status in one write() as it'll be less than 4k
|
||||
|
||||
fname = ecore_file_file_get(src);
|
||||
if (!fname) goto err;
|
||||
buf = eina_strbuf_new();
|
||||
// XXX: if buf is null?
|
||||
eina_strbuf_append(buf, dst);
|
||||
eina_strbuf_append(buf, "/");
|
||||
eina_strbuf_append(buf, fname);
|
||||
// XXX: write out status file and update it
|
||||
// XXX: ecore_file_mv() ? <- look at it
|
||||
if (rename(src, eina_strbuf_string_get(buf)) == -1)
|
||||
{
|
||||
fprintf(stderr, "MV: %s\n", strerror(errno));
|
||||
switch (errno)
|
||||
{
|
||||
case EACCES:
|
||||
case EPERM: // permission denied
|
||||
break;
|
||||
case EBUSY: // file or dir is busy
|
||||
break;
|
||||
case EDQUOT: // no quota left
|
||||
break;
|
||||
case EFAULT: // should not happen - but src or dst outside addr space
|
||||
break;
|
||||
case EINVAL: // moving into a sub path of itsefl - invalid
|
||||
break;
|
||||
case EISDIR: // moving file on top of dir
|
||||
break;
|
||||
case ELOOP: // too many symlinks in a loop
|
||||
break;
|
||||
case EMLINK: // max links exceeded
|
||||
break;
|
||||
case ENAMETOOLONG: // path too long (src or dst)
|
||||
break;
|
||||
case ENOENT: // src or dst doesn't exist
|
||||
break;
|
||||
case ENOMEM: // out of mem
|
||||
break;
|
||||
case ENOSPC: // out of space on disk
|
||||
break;
|
||||
case ENOTDIR: // moving dir on top of file
|
||||
break;
|
||||
case ENOTEMPTY:
|
||||
case EEXIST: // dst is not an empty dir
|
||||
break;
|
||||
case EROFS: // read only disk
|
||||
break;
|
||||
case EXDEV: // revert to cp -par
|
||||
break;
|
||||
default: // WAT???
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "MV: OK\n");
|
||||
// XXX: use meta_path_find() or meta_path_user_find() based on
|
||||
// XXX: meta_path_can_write() and prep the dest with meta_path_prepare()
|
||||
fdir = ecore_file_dir_get(src);
|
||||
if (fdir)
|
||||
{
|
||||
// mv the efm meta file if it exists...
|
||||
buf2 = eina_strbuf_new();
|
||||
|
||||
// XXX" if buf2 is null?
|
||||
eina_strbuf_append(buf2, dst);
|
||||
eina_strbuf_append(buf2, "/.efm");
|
||||
ecore_file_mkdir(eina_strbuf_string_get(buf2));
|
||||
|
||||
eina_strbuf_reset(buf2);
|
||||
eina_strbuf_append(buf2, fdir);
|
||||
eina_strbuf_append(buf2, "/.efm/");
|
||||
eina_strbuf_append(buf2, fname);
|
||||
eina_strbuf_append(buf2, ".efm");
|
||||
|
||||
eina_strbuf_reset(buf);
|
||||
eina_strbuf_append(buf, dst);
|
||||
eina_strbuf_append(buf, "/.efm/");
|
||||
eina_strbuf_append(buf, fname);
|
||||
eina_strbuf_append(buf, ".efm");
|
||||
// XXX: what if the target meta file already exists???
|
||||
rename(eina_strbuf_string_get(buf2), eina_strbuf_string_get(buf));
|
||||
free(fdir);
|
||||
// XXX: mv meta if in ~/.e/e/efm/meta
|
||||
// XXX: mv thumb files in /.e/e/efm/thumbs
|
||||
}
|
||||
}
|
||||
err:
|
||||
if (buf) eina_strbuf_free(buf);
|
||||
if (buf2) eina_strbuf_free(buf2);
|
||||
// XXX: delete status file
|
||||
|
||||
meta_shutdown();
|
||||
|
||||
efreet_shutdown();
|
||||
ecore_shutdown();
|
||||
eet_shutdown();
|
||||
eina_shutdown();
|
||||
return 0;
|
||||
}
|
|
@ -6,12 +6,8 @@
|
|||
// the front end that consumes the output of this should do NO file access
|
||||
// itself at all and do everything via fs handlers for open, delete, rename
|
||||
// copy, import, export etc.
|
||||
#include "cmd.h"
|
||||
#include "ecore_exe_eo.legacy.h"
|
||||
#include "eina_stringshare.h"
|
||||
#include "eina_types.h"
|
||||
#include "sha.h"
|
||||
#include "meta.h"
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_File.h>
|
||||
#include <Efreet.h>
|
||||
#include <Efreet_Mime.h>
|
||||
|
@ -21,6 +17,10 @@
|
|||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "cmd.h"
|
||||
#include "eina_strbuf.h"
|
||||
#include "sha.h"
|
||||
#include "meta.h"
|
||||
#include "thumb_check.h"
|
||||
|
||||
static const char *icon_theme = NULL;
|
||||
|
@ -28,6 +28,7 @@ static const char *config_dir = NULL;
|
|||
static const char *home_dir = NULL;
|
||||
|
||||
static Ecore_File_Monitor *mon = NULL;
|
||||
static Eina_Bool can_write = EINA_FALSE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -381,14 +382,13 @@ _file_thumb(const char *path EINA_UNUSED, const char *mime)
|
|||
static char *
|
||||
_file_thumb_find(const char *path, const char *mime EINA_UNUSED)
|
||||
{ // find the thumb file
|
||||
unsigned char sha[20];
|
||||
char buf[PATH_MAX], shastr[41];
|
||||
char *thumb;
|
||||
|
||||
eina_sha1((const unsigned char *)path, strlen(path), sha);
|
||||
sha1_str(sha, shastr);
|
||||
snprintf(buf, sizeof(buf), "%s/efm/thumbs/%c%c/%s.eet", config_dir, shastr[0],
|
||||
shastr[1], shastr + 2);
|
||||
return strdup(buf);
|
||||
if (can_write) thumb = meta_path_find(path, "thumb.efm");
|
||||
else thumb = meta_path_user_find(path, "thumb.efm");
|
||||
if (!thumb) return NULL;
|
||||
meta_path_prepare(thumb);
|
||||
return thumb;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
@ -491,7 +491,13 @@ _file_thumb_handle(Eina_Strbuf *strbuf, const char *path, const char *mime,
|
|||
if (!_file_thumb(path, mime)) return;
|
||||
|
||||
// get what the path to the target thumb should be
|
||||
thumb = _file_thumb_find(path, mime);
|
||||
thumb = meta_path_user_find(path, "thumb.efm");
|
||||
if (!ecore_file_exists(thumb))
|
||||
{
|
||||
free(thumb);
|
||||
thumb = meta_path_find(path, "thumb.efm");
|
||||
}
|
||||
|
||||
if (thumb)
|
||||
{ // open the thumb and let's see if the stat info is up to date
|
||||
Eet_File *ef = eet_open(thumb, EET_FILE_MODE_READ);
|
||||
|
@ -1185,12 +1191,18 @@ _monitor(const char *path)
|
|||
|
||||
if (abort_list) return;
|
||||
|
||||
strbuf = eina_strbuf_new();
|
||||
eina_strbuf_append(strbuf, path);
|
||||
eina_strbuf_append(strbuf, ".efm");
|
||||
can_write = meta_path_can_write(eina_strbuf_string_get(strbuf));
|
||||
if (strbuf) eina_strbuf_free(strbuf);
|
||||
|
||||
// tell the front end out listing is beginning
|
||||
strbuf = cmd_strbuf_new("list-begin");
|
||||
cmd_strbuf_print_consume(strbuf);
|
||||
|
||||
mon = ecore_file_monitor_add(path, _cb_mon, NULL);
|
||||
it = eina_file_direct_ls(path);
|
||||
it = eina_file_direct_ls(path);
|
||||
if (!it)
|
||||
{
|
||||
// XXX: error output
|
||||
|
@ -1209,7 +1221,7 @@ _path_in_mon_dir(const char *path)
|
|||
{
|
||||
Eina_Bool res = EINA_FALSE;
|
||||
const char *mondir;
|
||||
char *filedir = ecore_file_dir_get(path);
|
||||
char *filedir = ecore_file_dir_get(path);
|
||||
|
||||
if (!filedir) return res;
|
||||
if (!mon) goto done;
|
||||
|
@ -1221,6 +1233,30 @@ _path_in_mon_dir(const char *path)
|
|||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
_op_run(const char *op, const char *src, const char *dst)
|
||||
{
|
||||
Eina_Strbuf *buf;
|
||||
const char *s;
|
||||
|
||||
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);
|
||||
eina_strbuf_free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
_handle_drop_paste(const char *over, const char *action, const char *path)
|
||||
{
|
||||
|
@ -1248,8 +1284,26 @@ _handle_drop_paste(const char *over, const char *action, const char *path)
|
|||
{
|
||||
fprintf(stderr, "DROP in [%s] action=[%s] > [%s]\n", mondir, action,
|
||||
path);
|
||||
// XXX: do the real operation here
|
||||
// XXX: action = copy, move, ask, list, link, description
|
||||
if ((!action) || (!strcmp(action, "copy")))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(action, "move"))
|
||||
_op_run("mv", path, mondir);
|
||||
else if (!strcmp(action, "ask"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(action, "list"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(action, "link"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(action, "description"))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "thumb.h"
|
||||
#include "meta.h"
|
||||
|
||||
Evas_Object *win = NULL;
|
||||
Evas_Object *subwin = NULL;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifndef THUMB_H
|
||||
#define THUMB_H
|
||||
#include <Elementary.h>
|
||||
#include "efm_config.h"
|
||||
#include "sha.h"
|
||||
|
@ -83,3 +85,4 @@ scale_out(int *w, int *h, int maxw, int maxh, Eina_Bool no_scale_up)
|
|||
*w = ww;
|
||||
*h = hh;
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue