aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_file
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-04 18:41:13 +1000
committerDavid Walter Seikel2012-01-04 18:41:13 +1000
commitdd7595a3475407a7fa96a97393bae8c5220e8762 (patch)
treee341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/ecore/src/lib/ecore_file
parentAdd the skeleton. (diff)
downloadSledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to '')
-rw-r--r--libraries/ecore/src/lib/ecore_file/Ecore_File.h190
-rw-r--r--libraries/ecore/src/lib/ecore_file/Makefile.am41
-rw-r--r--libraries/ecore/src/lib/ecore_file/Makefile.in837
-rw-r--r--libraries/ecore/src/lib/ecore_file/ecore_file.c1110
-rw-r--r--libraries/ecore/src/lib/ecore_file/ecore_file_download.c440
-rw-r--r--libraries/ecore/src/lib/ecore_file/ecore_file_monitor.c180
-rw-r--r--libraries/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c369
-rw-r--r--libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c339
-rw-r--r--libraries/ecore/src/lib/ecore_file/ecore_file_monitor_win32.c310
-rw-r--r--libraries/ecore/src/lib/ecore_file/ecore_file_path.c184
-rw-r--r--libraries/ecore/src/lib/ecore_file/ecore_file_private.h129
11 files changed, 4129 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_file/Ecore_File.h b/libraries/ecore/src/lib/ecore_file/Ecore_File.h
new file mode 100644
index 0000000..e4b8851
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/Ecore_File.h
@@ -0,0 +1,190 @@
1#ifndef ECORE_FILE_H
2#define ECORE_FILE_H
3
4/*
5 * TODO:
6 * - More events, move/rename of directory file
7 */
8
9#include <Eina.h>
10
11#ifdef EAPI
12# undef EAPI
13#endif
14
15#ifdef _WIN32
16# ifdef EFL_ECORE_FILE_BUILD
17# ifdef DLL_EXPORT
18# define EAPI __declspec(dllexport)
19# else
20# define EAPI
21# endif /* ! DLL_EXPORT */
22# else
23# define EAPI __declspec(dllimport)
24# endif /* ! EFL_ECORE_FILE_BUILD */
25#else
26# ifdef __GNUC__
27# if __GNUC__ >= 4
28# define EAPI __attribute__ ((visibility("default")))
29# else
30# define EAPI
31# endif
32# else
33# define EAPI
34# endif
35#endif /* ! _WIN32 */
36
37/**
38 * @file Ecore_File.h
39 * @brief Files utility functions
40 */
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/**
47 * @defgroup Ecore_File_Group Ecore_File - Files and directories convenience functions
48 *
49 * @{
50 */
51
52/**
53 * @typedef Ecore_File_Monitor
54 * Abstract type used when monitoring a directory.
55 */
56typedef struct _Ecore_File_Monitor Ecore_File_Monitor;
57
58/**
59 * @typedef Ecore_File_Download_Job
60 * Abstract type used when aborting a download.
61 */
62typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job;
63
64/**
65 * @typedef Ecore_File_Event
66 * The event type returned when a file or directory is monitored.
67 */
68typedef enum _Ecore_File_Event
69{
70 ECORE_FILE_EVENT_NONE, /**< No event. */
71 ECORE_FILE_EVENT_CREATED_FILE, /**< Created file event. */
72 ECORE_FILE_EVENT_CREATED_DIRECTORY, /**< Created directory event. */
73 ECORE_FILE_EVENT_DELETED_FILE, /**< Deleted file event. */
74 ECORE_FILE_EVENT_DELETED_DIRECTORY, /**< Deleted directory event. */
75 ECORE_FILE_EVENT_DELETED_SELF, /**< Deleted monitored directory event. */
76 ECORE_FILE_EVENT_MODIFIED, /**< Modified file or directory event. */
77 ECORE_FILE_EVENT_CLOSED /**< Closed file event */
78} Ecore_File_Event;
79
80/**
81 * @typedef Ecore_File_Monitor_Cb
82 * Callback type used when a monitored directory has changes.
83 */
84typedef void (*Ecore_File_Monitor_Cb)(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path);
85
86/**
87 * @typedef Ecore_File_Download_Completion_Cb
88 * Callback type used when a download is finished.
89 */
90typedef void (*Ecore_File_Download_Completion_Cb)(void *data, const char *file, int status);
91
92/**
93 * @typedef Ecore_File_Progress_Return
94 * What to do with the download as a return from the
95 * Ecore_File_Download_Progress_Cb function, if provided.
96 */
97typedef enum _Ecore_File_Progress_Return
98{
99 ECORE_FILE_PROGRESS_CONTINUE = 0, /**< Continue the download. */
100 ECORE_FILE_PROGRESS_ABORT = 1 /**< Abort the download. */
101} Ecore_File_Progress_Return;
102
103/**
104 * @typedef Ecore_File_Download_Progress_Cb
105 * Callback type used while a download is in progress.
106 */
107typedef int (*Ecore_File_Download_Progress_Cb)(void *data,
108 const char *file,
109 long int dltotal,
110 long int dlnow,
111 long int ultotal,
112 long int ulnow);
113
114/* File operations */
115
116EAPI int ecore_file_init (void);
117EAPI int ecore_file_shutdown (void);
118EAPI long long ecore_file_mod_time (const char *file);
119EAPI long long ecore_file_size (const char *file);
120EAPI Eina_Bool ecore_file_exists (const char *file);
121EAPI Eina_Bool ecore_file_is_dir (const char *file);
122EAPI Eina_Bool ecore_file_mkdir (const char *dir);
123EAPI int ecore_file_mkdirs (const char **dirs);
124EAPI int ecore_file_mksubdirs (const char *base, const char **subdirs);
125EAPI Eina_Bool ecore_file_rmdir (const char *dir);
126EAPI Eina_Bool ecore_file_recursive_rm (const char *dir);
127EAPI Eina_Bool ecore_file_mkpath (const char *path);
128EAPI int ecore_file_mkpaths (const char **paths);
129EAPI Eina_Bool ecore_file_cp (const char *src, const char *dst);
130EAPI Eina_Bool ecore_file_mv (const char *src, const char *dst);
131EAPI Eina_Bool ecore_file_symlink (const char *src, const char *dest);
132EAPI char *ecore_file_realpath (const char *file);
133EAPI Eina_Bool ecore_file_unlink (const char *file);
134EAPI Eina_Bool ecore_file_remove (const char *file);
135EAPI const char *ecore_file_file_get (const char *path);
136EAPI char *ecore_file_dir_get (const char *path);
137EAPI Eina_Bool ecore_file_can_read (const char *file);
138EAPI Eina_Bool ecore_file_can_write (const char *file);
139EAPI Eina_Bool ecore_file_can_exec (const char *file);
140EAPI char *ecore_file_readlink (const char *link);
141EAPI Eina_List *ecore_file_ls (const char *dir);
142EAPI Eina_Iterator *ecore_file_ls_iterator (const char *dir);
143EAPI char *ecore_file_app_exe_get (const char *app);
144EAPI char *ecore_file_escape_name (const char *filename);
145EAPI char *ecore_file_strip_ext (const char *file);
146EAPI int ecore_file_dir_is_empty (const char *dir);
147
148/* Monitoring */
149
150EAPI Ecore_File_Monitor *ecore_file_monitor_add(const char *path,
151 Ecore_File_Monitor_Cb func,
152 void *data);
153EAPI void ecore_file_monitor_del(Ecore_File_Monitor *ecore_file_monitor);
154EAPI const char *ecore_file_monitor_path_get(Ecore_File_Monitor *ecore_file_monitor);
155
156/* Path */
157
158EAPI Eina_Bool ecore_file_path_dir_exists(const char *in_dir);
159EAPI Eina_Bool ecore_file_app_installed(const char *exe);
160EAPI Eina_List *ecore_file_app_list(void);
161
162/* Download */
163
164EAPI Eina_Bool ecore_file_download(const char *url,
165 const char *dst,
166 Ecore_File_Download_Completion_Cb completion_cb,
167 Ecore_File_Download_Progress_Cb progress_cb,
168 void *data,
169 Ecore_File_Download_Job **job_ret);
170EAPI Eina_Bool ecore_file_download_full(const char *url,
171 const char *dst,
172 Ecore_File_Download_Completion_Cb completion_cb,
173 Ecore_File_Download_Progress_Cb progress_cb,
174 void *data,
175 Ecore_File_Download_Job **job_ret,
176 Eina_Hash *headers);
177
178EAPI void ecore_file_download_abort_all(void);
179EAPI void ecore_file_download_abort(Ecore_File_Download_Job *job);
180EAPI Eina_Bool ecore_file_download_protocol_available(const char *protocol);
181
182/**
183 * @}
184 */
185
186#ifdef __cplusplus
187}
188#endif
189
190#endif
diff --git a/libraries/ecore/src/lib/ecore_file/Makefile.am b/libraries/ecore/src/lib/ecore_file/Makefile.am
new file mode 100644
index 0000000..ab23ace
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/Makefile.am
@@ -0,0 +1,41 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/lib/ecore \
5-I$(top_srcdir)/src/lib/ecore_con \
6-I$(top_builddir)/src/lib/ecore \
7@EFL_ECORE_FILE_BUILD@ \
8@CURL_CFLAGS@ \
9@EVIL_CFLAGS@ \
10@EINA_CFLAGS@ \
11@WIN32_CPPFLAGS@
12
13AM_CFLAGS = @WIN32_CFLAGS@
14
15if BUILD_ECORE_CON
16lib_ecore_con_la = $(top_builddir)/src/lib/ecore_con/libecore_con.la
17endif
18
19lib_LTLIBRARIES = libecore_file.la
20includes_HEADERS = Ecore_File.h
21includesdir = $(includedir)/ecore-@VMAJ@
22
23libecore_file_la_SOURCES = \
24ecore_file.c \
25ecore_file_monitor.c \
26ecore_file_monitor_inotify.c \
27ecore_file_monitor_win32.c \
28ecore_file_monitor_poll.c \
29ecore_file_path.c \
30ecore_file_download.c
31
32libecore_file_la_LIBADD = \
33$(top_builddir)/src/lib/ecore/libecore.la \
34$(lib_ecore_con_la) \
35@EVIL_LIBS@ \
36@EINA_LIBS@
37
38libecore_file_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
39
40EXTRA_DIST = ecore_file_private.h
41
diff --git a/libraries/ecore/src/lib/ecore_file/Makefile.in b/libraries/ecore/src/lib/ecore_file/Makefile.in
new file mode 100644
index 0000000..34945b3
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/Makefile.in
@@ -0,0 +1,837 @@
1# Makefile.in generated by automake 1.11.1 from Makefile.am.
2# @configure_input@
3
4# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
5# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
6# Inc.
7# This Makefile.in is free software; the Free Software Foundation
8# gives unlimited permission to copy and/or distribute it,
9# with or without modifications, as long as this notice is preserved.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
13# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14# PARTICULAR PURPOSE.
15
16@SET_MAKE@
17
18
19VPATH = @srcdir@
20pkgdatadir = $(datadir)/@PACKAGE@
21pkgincludedir = $(includedir)/@PACKAGE@
22pkglibdir = $(libdir)/@PACKAGE@
23pkglibexecdir = $(libexecdir)/@PACKAGE@
24am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
25install_sh_DATA = $(install_sh) -c -m 644
26install_sh_PROGRAM = $(install_sh) -c
27install_sh_SCRIPT = $(install_sh) -c
28INSTALL_HEADER = $(INSTALL_DATA)
29transform = $(program_transform_name)
30NORMAL_INSTALL = :
31PRE_INSTALL = :
32POST_INSTALL = :
33NORMAL_UNINSTALL = :
34PRE_UNINSTALL = :
35POST_UNINSTALL = :
36build_triplet = @build@
37host_triplet = @host@
38subdir = src/lib/ecore_file
39DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \
40 $(srcdir)/Makefile.in
41ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
42am__aclocal_m4_deps = $(top_srcdir)/m4/ac_attribute.m4 \
43 $(top_srcdir)/m4/ac_path_generic.m4 \
44 $(top_srcdir)/m4/check_x_extension.m4 \
45 $(top_srcdir)/m4/ecore_check_module.m4 \
46 $(top_srcdir)/m4/ecore_check_options.m4 \
47 $(top_srcdir)/m4/efl_compiler_flag.m4 \
48 $(top_srcdir)/m4/efl_doxygen.m4 \
49 $(top_srcdir)/m4/efl_examples.m4 \
50 $(top_srcdir)/m4/efl_path_max.m4 $(top_srcdir)/m4/efl_tests.m4 \
51 $(top_srcdir)/m4/efl_threads.m4 $(top_srcdir)/m4/gettext.m4 \
52 $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
53 $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/lib-ld.m4 \
54 $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
55 $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
56 $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
57 $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
58 $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
59 $(top_srcdir)/configure.ac
60am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
61 $(ACLOCAL_M4)
62mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
63CONFIG_HEADER = $(top_builddir)/config.h
64CONFIG_CLEAN_FILES =
65CONFIG_CLEAN_VPATH_FILES =
66am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
67am__vpath_adj = case $$p in \
68 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
69 *) f=$$p;; \
70 esac;
71am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
72am__install_max = 40
73am__nobase_strip_setup = \
74 srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
75am__nobase_strip = \
76 for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
77am__nobase_list = $(am__nobase_strip_setup); \
78 for p in $$list; do echo "$$p $$p"; done | \
79 sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
80 $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
81 if (++n[$$2] == $(am__install_max)) \
82 { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
83 END { for (dir in files) print dir, files[dir] }'
84am__base_list = \
85 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
86 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
87am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"
88LTLIBRARIES = $(lib_LTLIBRARIES)
89libecore_file_la_DEPENDENCIES = \
90 $(top_builddir)/src/lib/ecore/libecore.la $(lib_ecore_con_la)
91am_libecore_file_la_OBJECTS = ecore_file.lo ecore_file_monitor.lo \
92 ecore_file_monitor_inotify.lo ecore_file_monitor_win32.lo \
93 ecore_file_monitor_poll.lo ecore_file_path.lo \
94 ecore_file_download.lo
95libecore_file_la_OBJECTS = $(am_libecore_file_la_OBJECTS)
96AM_V_lt = $(am__v_lt_$(V))
97am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
98am__v_lt_0 = --silent
99libecore_file_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
100 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
101 $(AM_CFLAGS) $(CFLAGS) $(libecore_file_la_LDFLAGS) $(LDFLAGS) \
102 -o $@
103DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
104depcomp = $(SHELL) $(top_srcdir)/depcomp
105am__depfiles_maybe = depfiles
106am__mv = mv -f
107COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
108 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
109LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
110 $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
111 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
112 $(AM_CFLAGS) $(CFLAGS)
113AM_V_CC = $(am__v_CC_$(V))
114am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
115am__v_CC_0 = @echo " CC " $@;
116AM_V_at = $(am__v_at_$(V))
117am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
118am__v_at_0 = @
119CCLD = $(CC)
120LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
121 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
122 $(AM_LDFLAGS) $(LDFLAGS) -o $@
123AM_V_CCLD = $(am__v_CCLD_$(V))
124am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
125am__v_CCLD_0 = @echo " CCLD " $@;
126AM_V_GEN = $(am__v_GEN_$(V))
127am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
128am__v_GEN_0 = @echo " GEN " $@;
129SOURCES = $(libecore_file_la_SOURCES)
130DIST_SOURCES = $(libecore_file_la_SOURCES)
131HEADERS = $(includes_HEADERS)
132ETAGS = etags
133CTAGS = ctags
134DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
135ACLOCAL = @ACLOCAL@
136ALLOCA = @ALLOCA@
137AMTAR = @AMTAR@
138AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
139AR = @AR@
140AS = @AS@
141AUTOCONF = @AUTOCONF@
142AUTOHEADER = @AUTOHEADER@
143AUTOMAKE = @AUTOMAKE@
144AWK = @AWK@
145CARES_CFLAGS = @CARES_CFLAGS@
146CARES_LIBS = @CARES_LIBS@
147CC = @CC@
148CCDEPMODE = @CCDEPMODE@
149CFLAGS = @CFLAGS@
150CHECK_CFLAGS = @CHECK_CFLAGS@
151CHECK_LIBS = @CHECK_LIBS@
152CPP = @CPP@
153CPPFLAGS = @CPPFLAGS@
154CURL_CFLAGS = @CURL_CFLAGS@
155CURL_LIBS = @CURL_LIBS@
156CXX = @CXX@
157CXXCPP = @CXXCPP@
158CXXDEPMODE = @CXXDEPMODE@
159CXXFLAGS = @CXXFLAGS@
160CYGPATH_W = @CYGPATH_W@
161DEFS = @DEFS@
162DEPDIR = @DEPDIR@
163DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@
164DIRECTFB_LIBS = @DIRECTFB_LIBS@
165DLLTOOL = @DLLTOOL@
166DSYMUTIL = @DSYMUTIL@
167DUMPBIN = @DUMPBIN@
168ECHO_C = @ECHO_C@
169ECHO_N = @ECHO_N@
170ECHO_T = @ECHO_T@
171ECORE_XCB_CFLAGS = @ECORE_XCB_CFLAGS@
172ECORE_XCB_LIBS = @ECORE_XCB_LIBS@
173EFL_ECORE_BUILD = @EFL_ECORE_BUILD@
174EFL_ECORE_CON_BUILD = @EFL_ECORE_CON_BUILD@
175EFL_ECORE_EVAS_BUILD = @EFL_ECORE_EVAS_BUILD@
176EFL_ECORE_FILE_BUILD = @EFL_ECORE_FILE_BUILD@
177EFL_ECORE_IMF_BUILD = @EFL_ECORE_IMF_BUILD@
178EFL_ECORE_IMF_EVAS_BUILD = @EFL_ECORE_IMF_EVAS_BUILD@
179EFL_ECORE_INPUT_BUILD = @EFL_ECORE_INPUT_BUILD@
180EFL_ECORE_INPUT_EVAS_BUILD = @EFL_ECORE_INPUT_EVAS_BUILD@
181EFL_ECORE_IPC_BUILD = @EFL_ECORE_IPC_BUILD@
182EFL_ECORE_PSL1GHT_BUILD = @EFL_ECORE_PSL1GHT_BUILD@
183EFL_ECORE_SDL_BUILD = @EFL_ECORE_SDL_BUILD@
184EFL_ECORE_WIN32_BUILD = @EFL_ECORE_WIN32_BUILD@
185EFL_ECORE_WINCE_BUILD = @EFL_ECORE_WINCE_BUILD@
186EFL_PTHREAD_CFLAGS = @EFL_PTHREAD_CFLAGS@
187EFL_PTHREAD_LIBS = @EFL_PTHREAD_LIBS@
188EGREP = @EGREP@
189EINA_CFLAGS = @EINA_CFLAGS@
190EINA_LIBS = @EINA_LIBS@
191ESCAPE_CFLAGS = @ESCAPE_CFLAGS@
192ESCAPE_LIBS = @ESCAPE_LIBS@
193EVAS_CFLAGS = @EVAS_CFLAGS@
194EVAS_LIBS = @EVAS_LIBS@
195EVIL_CFLAGS = @EVIL_CFLAGS@
196EVIL_LIBS = @EVIL_LIBS@
197EXEEXT = @EXEEXT@
198FGREP = @FGREP@
199GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
200GLIB_CFLAGS = @GLIB_CFLAGS@
201GLIB_LIBS = @GLIB_LIBS@
202GMSGFMT = @GMSGFMT@
203GMSGFMT_015 = @GMSGFMT_015@
204GREP = @GREP@
205INSTALL = @INSTALL@
206INSTALL_DATA = @INSTALL_DATA@
207INSTALL_PROGRAM = @INSTALL_PROGRAM@
208INSTALL_SCRIPT = @INSTALL_SCRIPT@
209INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
210INTLLIBS = @INTLLIBS@
211INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
212KEYSYMDEFS = @KEYSYMDEFS@
213LD = @LD@
214LDFLAGS = @LDFLAGS@
215LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
216LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
217LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
218LIBICONV = @LIBICONV@
219LIBINTL = @LIBINTL@
220LIBOBJS = @LIBOBJS@
221LIBS = @LIBS@
222LIBTOOL = @LIBTOOL@
223LIPO = @LIPO@
224LN_S = @LN_S@
225LTLIBICONV = @LTLIBICONV@
226LTLIBINTL = @LTLIBINTL@
227LTLIBOBJS = @LTLIBOBJS@
228MAKEINFO = @MAKEINFO@
229MKDIR_P = @MKDIR_P@
230MSGFMT = @MSGFMT@
231MSGFMT_015 = @MSGFMT_015@
232MSGMERGE = @MSGMERGE@
233NM = @NM@
234NMEDIT = @NMEDIT@
235OBJC = @OBJC@
236OBJCDEPMODE = @OBJCDEPMODE@
237OBJCFLAGS = @OBJCFLAGS@
238OBJDUMP = @OBJDUMP@
239OBJEXT = @OBJEXT@
240OTOOL = @OTOOL@
241OTOOL64 = @OTOOL64@
242PACKAGE = @PACKAGE@
243PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
244PACKAGE_NAME = @PACKAGE_NAME@
245PACKAGE_STRING = @PACKAGE_STRING@
246PACKAGE_TARNAME = @PACKAGE_TARNAME@
247PACKAGE_URL = @PACKAGE_URL@
248PACKAGE_VERSION = @PACKAGE_VERSION@
249PATH_SEPARATOR = @PATH_SEPARATOR@
250PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
251PIXMAN_LIBS = @PIXMAN_LIBS@
252PKG_CONFIG = @PKG_CONFIG@
253PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
254PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
255POSUB = @POSUB@
256RANLIB = @RANLIB@
257SDL_CFLAGS = @SDL_CFLAGS@
258SDL_CONFIG = @SDL_CONFIG@
259SDL_LIBS = @SDL_LIBS@
260SED = @SED@
261SET_MAKE = @SET_MAKE@
262SHELL = @SHELL@
263SSL_CFLAGS = @SSL_CFLAGS@
264SSL_LIBS = @SSL_LIBS@
265STRIP = @STRIP@
266TLS2_CFLAGS = @TLS2_CFLAGS@
267TLS2_LIBS = @TLS2_LIBS@
268TLS_CFLAGS = @TLS_CFLAGS@
269TLS_LIBS = @TLS_LIBS@
270TSLIB_CFLAGS = @TSLIB_CFLAGS@
271TSLIB_LIBS = @TSLIB_LIBS@
272USE_NLS = @USE_NLS@
273VERSION = @VERSION@
274VMAJ = @VMAJ@
275WIN32_CFLAGS = @WIN32_CFLAGS@
276WIN32_CPPFLAGS = @WIN32_CPPFLAGS@
277WIN32_LIBS = @WIN32_LIBS@
278XCB_COMPOSITE_CFLAGS = @XCB_COMPOSITE_CFLAGS@
279XCB_COMPOSITE_LIBS = @XCB_COMPOSITE_LIBS@
280XCB_CURSOR_CFLAGS = @XCB_CURSOR_CFLAGS@
281XCB_CURSOR_LIBS = @XCB_CURSOR_LIBS@
282XCB_DAMAGE_CFLAGS = @XCB_DAMAGE_CFLAGS@
283XCB_DAMAGE_LIBS = @XCB_DAMAGE_LIBS@
284XCB_DPMS_CFLAGS = @XCB_DPMS_CFLAGS@
285XCB_DPMS_LIBS = @XCB_DPMS_LIBS@
286XCB_RANDR_CFLAGS = @XCB_RANDR_CFLAGS@
287XCB_RANDR_LIBS = @XCB_RANDR_LIBS@
288XCB_RENDER_CFLAGS = @XCB_RENDER_CFLAGS@
289XCB_RENDER_LIBS = @XCB_RENDER_LIBS@
290XCB_SCREENSAVER_CFLAGS = @XCB_SCREENSAVER_CFLAGS@
291XCB_SCREENSAVER_LIBS = @XCB_SCREENSAVER_LIBS@
292XCB_SHAPE_CFLAGS = @XCB_SHAPE_CFLAGS@
293XCB_SHAPE_LIBS = @XCB_SHAPE_LIBS@
294XCB_SYNC_CFLAGS = @XCB_SYNC_CFLAGS@
295XCB_SYNC_LIBS = @XCB_SYNC_LIBS@
296XCB_X11_CFLAGS = @XCB_X11_CFLAGS@
297XCB_X11_LIBS = @XCB_X11_LIBS@
298XCB_XFIXES_CFLAGS = @XCB_XFIXES_CFLAGS@
299XCB_XFIXES_LIBS = @XCB_XFIXES_LIBS@
300XCB_XGESTURE_CFLAGS = @XCB_XGESTURE_CFLAGS@
301XCB_XGESTURE_LIBS = @XCB_XGESTURE_LIBS@
302XCB_XINERAMA_CFLAGS = @XCB_XINERAMA_CFLAGS@
303XCB_XINERAMA_LIBS = @XCB_XINERAMA_LIBS@
304XCB_XINPUT_CFLAGS = @XCB_XINPUT_CFLAGS@
305XCB_XINPUT_LIBS = @XCB_XINPUT_LIBS@
306XCB_XPRINT_CFLAGS = @XCB_XPRINT_CFLAGS@
307XCB_XPRINT_LIBS = @XCB_XPRINT_LIBS@
308XCB_XTEST_CFLAGS = @XCB_XTEST_CFLAGS@
309XCB_XTEST_LIBS = @XCB_XTEST_LIBS@
310XCOMPOSITE_CFLAGS = @XCOMPOSITE_CFLAGS@
311XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@
312XDAMAGE_CFLAGS = @XDAMAGE_CFLAGS@
313XDAMAGE_LIBS = @XDAMAGE_LIBS@
314XDPMS_CFLAGS = @XDPMS_CFLAGS@
315XDPMS_LIBS = @XDPMS_LIBS@
316XFIXES_CFLAGS = @XFIXES_CFLAGS@
317XFIXES_LIBS = @XFIXES_LIBS@
318XGESTURE_CFLAGS = @XGESTURE_CFLAGS@
319XGESTURE_LIBS = @XGESTURE_LIBS@
320XGETTEXT = @XGETTEXT@
321XGETTEXT_015 = @XGETTEXT_015@
322XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
323XI2_CFLAGS = @XI2_CFLAGS@
324XI2_LIBS = @XI2_LIBS@
325XINERAMA_CFLAGS = @XINERAMA_CFLAGS@
326XINERAMA_LIBS = @XINERAMA_LIBS@
327XKB_CFLAGS = @XKB_CFLAGS@
328XKB_LIBS = @XKB_LIBS@
329XMKMF = @XMKMF@
330XPRINT_CFLAGS = @XPRINT_CFLAGS@
331XPRINT_LIBS = @XPRINT_LIBS@
332XRANDR_CFLAGS = @XRANDR_CFLAGS@
333XRANDR_LIBS = @XRANDR_LIBS@
334XRENDER_CFLAGS = @XRENDER_CFLAGS@
335XRENDER_LIBS = @XRENDER_LIBS@
336XSS_CFLAGS = @XSS_CFLAGS@
337XSS_LIBS = @XSS_LIBS@
338XTEST_CFLAGS = @XTEST_CFLAGS@
339XTEST_LIBS = @XTEST_LIBS@
340X_CFLAGS = @X_CFLAGS@
341X_EXTRA_LIBS = @X_EXTRA_LIBS@
342X_LIBS = @X_LIBS@
343X_PRE_LIBS = @X_PRE_LIBS@
344Xcursor_cflags = @Xcursor_cflags@
345Xcursor_libs = @Xcursor_libs@
346abs_builddir = @abs_builddir@
347abs_srcdir = @abs_srcdir@
348abs_top_builddir = @abs_top_builddir@
349abs_top_srcdir = @abs_top_srcdir@
350ac_ct_CC = @ac_ct_CC@
351ac_ct_CXX = @ac_ct_CXX@
352ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
353ac_ct_OBJC = @ac_ct_OBJC@
354am__include = @am__include@
355am__leading_dot = @am__leading_dot@
356am__quote = @am__quote@
357am__tar = @am__tar@
358am__untar = @am__untar@
359bindir = @bindir@
360build = @build@
361build_alias = @build_alias@
362build_cpu = @build_cpu@
363build_os = @build_os@
364build_vendor = @build_vendor@
365builddir = @builddir@
366cocoa_ldflags = @cocoa_ldflags@
367datadir = @datadir@
368datarootdir = @datarootdir@
369dlopen_libs = @dlopen_libs@
370docdir = @docdir@
371dvidir = @dvidir@
372ecore_cocoa_cflags = @ecore_cocoa_cflags@
373ecore_cocoa_libs = @ecore_cocoa_libs@
374ecore_con_cflags = @ecore_con_cflags@
375ecore_con_libs = @ecore_con_libs@
376ecore_directfb_cflags = @ecore_directfb_cflags@
377ecore_directfb_libs = @ecore_directfb_libs@
378ecore_evas_cflags = @ecore_evas_cflags@
379ecore_evas_libs = @ecore_evas_libs@
380ecore_fb_cflags = @ecore_fb_cflags@
381ecore_fb_libs = @ecore_fb_libs@
382ecore_file_cflags = @ecore_file_cflags@
383ecore_file_libs = @ecore_file_libs@
384ecore_imf_cflags = @ecore_imf_cflags@
385ecore_imf_evas_cflags = @ecore_imf_evas_cflags@
386ecore_imf_evas_libs = @ecore_imf_evas_libs@
387ecore_imf_libs = @ecore_imf_libs@
388ecore_imf_xim_cflags = @ecore_imf_xim_cflags@
389ecore_imf_xim_libs = @ecore_imf_xim_libs@
390ecore_input_cflags = @ecore_input_cflags@
391ecore_input_evas_cflags = @ecore_input_evas_cflags@
392ecore_input_evas_libs = @ecore_input_evas_libs@
393ecore_input_libs = @ecore_input_libs@
394ecore_ipc_cflags = @ecore_ipc_cflags@
395ecore_ipc_libs = @ecore_ipc_libs@
396ecore_psl1ght_cflags = @ecore_psl1ght_cflags@
397ecore_psl1ght_libs = @ecore_psl1ght_libs@
398ecore_sdl_cflags = @ecore_sdl_cflags@
399ecore_sdl_libs = @ecore_sdl_libs@
400ecore_win32_cflags = @ecore_win32_cflags@
401ecore_win32_libs = @ecore_win32_libs@
402ecore_wince_cflags = @ecore_wince_cflags@
403ecore_wince_libs = @ecore_wince_libs@
404ecore_x_cflags = @ecore_x_cflags@
405ecore_x_libs = @ecore_x_libs@
406ecore_x_libs_private = @ecore_x_libs_private@
407efl_doxygen = @efl_doxygen@
408efl_have_doxygen = @efl_have_doxygen@
409exec_prefix = @exec_prefix@
410have_ecore_x_xcb_define = @have_ecore_x_xcb_define@
411host = @host@
412host_alias = @host_alias@
413host_cpu = @host_cpu@
414host_os = @host_os@
415host_vendor = @host_vendor@
416htmldir = @htmldir@
417includedir = @includedir@
418infodir = @infodir@
419install_sh = @install_sh@
420libdir = @libdir@
421libexecdir = @libexecdir@
422localedir = @localedir@
423localstatedir = @localstatedir@
424lt_ECHO = @lt_ECHO@
425lt_enable_auto_import = @lt_enable_auto_import@
426mandir = @mandir@
427mkdir_p = @mkdir_p@
428oldincludedir = @oldincludedir@
429pdfdir = @pdfdir@
430pkgconfig_requires_private = @pkgconfig_requires_private@
431prefix = @prefix@
432program_transform_name = @program_transform_name@
433psdir = @psdir@
434release_info = @release_info@
435requirements_ecore = @requirements_ecore@
436requirements_ecore_cocoa = @requirements_ecore_cocoa@
437requirements_ecore_con = @requirements_ecore_con@
438requirements_ecore_directfb = @requirements_ecore_directfb@
439requirements_ecore_evas = @requirements_ecore_evas@
440requirements_ecore_fb = @requirements_ecore_fb@
441requirements_ecore_file = @requirements_ecore_file@
442requirements_ecore_imf = @requirements_ecore_imf@
443requirements_ecore_imf_evas = @requirements_ecore_imf_evas@
444requirements_ecore_imf_xim = @requirements_ecore_imf_xim@
445requirements_ecore_input = @requirements_ecore_input@
446requirements_ecore_input_evas = @requirements_ecore_input_evas@
447requirements_ecore_ipc = @requirements_ecore_ipc@
448requirements_ecore_psl1ght = @requirements_ecore_psl1ght@
449requirements_ecore_sdl = @requirements_ecore_sdl@
450requirements_ecore_win32 = @requirements_ecore_win32@
451requirements_ecore_wince = @requirements_ecore_wince@
452requirements_ecore_x = @requirements_ecore_x@
453rt_libs = @rt_libs@
454sbindir = @sbindir@
455sharedstatedir = @sharedstatedir@
456srcdir = @srcdir@
457sysconfdir = @sysconfdir@
458target_alias = @target_alias@
459top_build_prefix = @top_build_prefix@
460top_builddir = @top_builddir@
461top_srcdir = @top_srcdir@
462version_info = @version_info@
463x_cflags = @x_cflags@
464x_includes = @x_includes@
465x_libs = @x_libs@
466MAINTAINERCLEANFILES = Makefile.in
467AM_CPPFLAGS = \
468-I$(top_srcdir)/src/lib/ecore \
469-I$(top_srcdir)/src/lib/ecore_con \
470-I$(top_builddir)/src/lib/ecore \
471@EFL_ECORE_FILE_BUILD@ \
472@CURL_CFLAGS@ \
473@EVIL_CFLAGS@ \
474@EINA_CFLAGS@ \
475@WIN32_CPPFLAGS@
476
477AM_CFLAGS = @WIN32_CFLAGS@
478@BUILD_ECORE_CON_TRUE@lib_ecore_con_la = $(top_builddir)/src/lib/ecore_con/libecore_con.la
479lib_LTLIBRARIES = libecore_file.la
480includes_HEADERS = Ecore_File.h
481includesdir = $(includedir)/ecore-@VMAJ@
482libecore_file_la_SOURCES = \
483ecore_file.c \
484ecore_file_monitor.c \
485ecore_file_monitor_inotify.c \
486ecore_file_monitor_win32.c \
487ecore_file_monitor_poll.c \
488ecore_file_path.c \
489ecore_file_download.c
490
491libecore_file_la_LIBADD = \
492$(top_builddir)/src/lib/ecore/libecore.la \
493$(lib_ecore_con_la) \
494@EVIL_LIBS@ \
495@EINA_LIBS@
496
497libecore_file_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
498EXTRA_DIST = ecore_file_private.h
499all: all-am
500
501.SUFFIXES:
502.SUFFIXES: .c .lo .o .obj
503$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
504 @for dep in $?; do \
505 case '$(am__configure_deps)' in \
506 *$$dep*) \
507 ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
508 && { if test -f $@; then exit 0; else break; fi; }; \
509 exit 1;; \
510 esac; \
511 done; \
512 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lib/ecore_file/Makefile'; \
513 $(am__cd) $(top_srcdir) && \
514 $(AUTOMAKE) --gnu src/lib/ecore_file/Makefile
515.PRECIOUS: Makefile
516Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
517 @case '$?' in \
518 *config.status*) \
519 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
520 *) \
521 echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
522 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
523 esac;
524
525$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
526 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
527
528$(top_srcdir)/configure: $(am__configure_deps)
529 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
530$(ACLOCAL_M4): $(am__aclocal_m4_deps)
531 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
532$(am__aclocal_m4_deps):
533install-libLTLIBRARIES: $(lib_LTLIBRARIES)
534 @$(NORMAL_INSTALL)
535 test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
536 @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
537 list2=; for p in $$list; do \
538 if test -f $$p; then \
539 list2="$$list2 $$p"; \
540 else :; fi; \
541 done; \
542 test -z "$$list2" || { \
543 echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
544 $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
545 }
546
547uninstall-libLTLIBRARIES:
548 @$(NORMAL_UNINSTALL)
549 @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
550 for p in $$list; do \
551 $(am__strip_dir) \
552 echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
553 $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
554 done
555
556clean-libLTLIBRARIES:
557 -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
558 @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
559 dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
560 test "$$dir" != "$$p" || dir=.; \
561 echo "rm -f \"$${dir}/so_locations\""; \
562 rm -f "$${dir}/so_locations"; \
563 done
564libecore_file.la: $(libecore_file_la_OBJECTS) $(libecore_file_la_DEPENDENCIES)
565 $(AM_V_CCLD)$(libecore_file_la_LINK) -rpath $(libdir) $(libecore_file_la_OBJECTS) $(libecore_file_la_LIBADD) $(LIBS)
566
567mostlyclean-compile:
568 -rm -f *.$(OBJEXT)
569
570distclean-compile:
571 -rm -f *.tab.c
572
573@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_file.Plo@am__quote@
574@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_file_download.Plo@am__quote@
575@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_file_monitor.Plo@am__quote@
576@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_file_monitor_inotify.Plo@am__quote@
577@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_file_monitor_poll.Plo@am__quote@
578@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_file_monitor_win32.Plo@am__quote@
579@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_file_path.Plo@am__quote@
580
581.c.o:
582@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
583@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
584@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
585@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
586@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
587@am__fastdepCC_FALSE@ $(COMPILE) -c $<
588
589.c.obj:
590@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
591@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
592@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
593@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
594@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
595@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
596
597.c.lo:
598@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
599@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
600@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
601@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
602@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
603@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
604
605mostlyclean-libtool:
606 -rm -f *.lo
607
608clean-libtool:
609 -rm -rf .libs _libs
610install-includesHEADERS: $(includes_HEADERS)
611 @$(NORMAL_INSTALL)
612 test -z "$(includesdir)" || $(MKDIR_P) "$(DESTDIR)$(includesdir)"
613 @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \
614 for p in $$list; do \
615 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
616 echo "$$d$$p"; \
617 done | $(am__base_list) | \
618 while read files; do \
619 echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includesdir)'"; \
620 $(INSTALL_HEADER) $$files "$(DESTDIR)$(includesdir)" || exit $$?; \
621 done
622
623uninstall-includesHEADERS:
624 @$(NORMAL_UNINSTALL)
625 @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \
626 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
627 test -n "$$files" || exit 0; \
628 echo " ( cd '$(DESTDIR)$(includesdir)' && rm -f" $$files ")"; \
629 cd "$(DESTDIR)$(includesdir)" && rm -f $$files
630
631ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
632 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
633 unique=`for i in $$list; do \
634 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
635 done | \
636 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
637 END { if (nonempty) { for (i in files) print i; }; }'`; \
638 mkid -fID $$unique
639tags: TAGS
640
641TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
642 $(TAGS_FILES) $(LISP)
643 set x; \
644 here=`pwd`; \
645 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
646 unique=`for i in $$list; do \
647 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
648 done | \
649 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
650 END { if (nonempty) { for (i in files) print i; }; }'`; \
651 shift; \
652 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
653 test -n "$$unique" || unique=$$empty_fix; \
654 if test $$# -gt 0; then \
655 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
656 "$$@" $$unique; \
657 else \
658 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
659 $$unique; \
660 fi; \
661 fi
662ctags: CTAGS
663CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
664 $(TAGS_FILES) $(LISP)
665 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
666 unique=`for i in $$list; do \
667 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
668 done | \
669 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
670 END { if (nonempty) { for (i in files) print i; }; }'`; \
671 test -z "$(CTAGS_ARGS)$$unique" \
672 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
673 $$unique
674
675GTAGS:
676 here=`$(am__cd) $(top_builddir) && pwd` \
677 && $(am__cd) $(top_srcdir) \
678 && gtags -i $(GTAGS_ARGS) "$$here"
679
680distclean-tags:
681 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
682
683distdir: $(DISTFILES)
684 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
685 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
686 list='$(DISTFILES)'; \
687 dist_files=`for file in $$list; do echo $$file; done | \
688 sed -e "s|^$$srcdirstrip/||;t" \
689 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
690 case $$dist_files in \
691 */*) $(MKDIR_P) `echo "$$dist_files" | \
692 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
693 sort -u` ;; \
694 esac; \
695 for file in $$dist_files; do \
696 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
697 if test -d $$d/$$file; then \
698 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
699 if test -d "$(distdir)/$$file"; then \
700 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
701 fi; \
702 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
703 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
704 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
705 fi; \
706 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
707 else \
708 test -f "$(distdir)/$$file" \
709 || cp -p $$d/$$file "$(distdir)/$$file" \
710 || exit 1; \
711 fi; \
712 done
713check-am: all-am
714check: check-am
715all-am: Makefile $(LTLIBRARIES) $(HEADERS)
716installdirs:
717 for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"; do \
718 test -z "$$dir" || $(MKDIR_P) "$$dir"; \
719 done
720install: install-am
721install-exec: install-exec-am
722install-data: install-data-am
723uninstall: uninstall-am
724
725install-am: all-am
726 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
727
728installcheck: installcheck-am
729install-strip:
730 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
731 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
732 `test -z '$(STRIP)' || \
733 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
734mostlyclean-generic:
735
736clean-generic:
737
738distclean-generic:
739 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
740 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
741
742maintainer-clean-generic:
743 @echo "This command is intended for maintainers to use"
744 @echo "it deletes files that may require special tools to rebuild."
745 -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
746clean: clean-am
747
748clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
749 mostlyclean-am
750
751distclean: distclean-am
752 -rm -rf ./$(DEPDIR)
753 -rm -f Makefile
754distclean-am: clean-am distclean-compile distclean-generic \
755 distclean-tags
756
757dvi: dvi-am
758
759dvi-am:
760
761html: html-am
762
763html-am:
764
765info: info-am
766
767info-am:
768
769install-data-am: install-includesHEADERS
770
771install-dvi: install-dvi-am
772
773install-dvi-am:
774
775install-exec-am: install-libLTLIBRARIES
776
777install-html: install-html-am
778
779install-html-am:
780
781install-info: install-info-am
782
783install-info-am:
784
785install-man:
786
787install-pdf: install-pdf-am
788
789install-pdf-am:
790
791install-ps: install-ps-am
792
793install-ps-am:
794
795installcheck-am:
796
797maintainer-clean: maintainer-clean-am
798 -rm -rf ./$(DEPDIR)
799 -rm -f Makefile
800maintainer-clean-am: distclean-am maintainer-clean-generic
801
802mostlyclean: mostlyclean-am
803
804mostlyclean-am: mostlyclean-compile mostlyclean-generic \
805 mostlyclean-libtool
806
807pdf: pdf-am
808
809pdf-am:
810
811ps: ps-am
812
813ps-am:
814
815uninstall-am: uninstall-includesHEADERS uninstall-libLTLIBRARIES
816
817.MAKE: install-am install-strip
818
819.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
820 clean-libLTLIBRARIES clean-libtool ctags distclean \
821 distclean-compile distclean-generic distclean-libtool \
822 distclean-tags distdir dvi dvi-am html html-am info info-am \
823 install install-am install-data install-data-am install-dvi \
824 install-dvi-am install-exec install-exec-am install-html \
825 install-html-am install-includesHEADERS install-info \
826 install-info-am install-libLTLIBRARIES install-man install-pdf \
827 install-pdf-am install-ps install-ps-am install-strip \
828 installcheck installcheck-am installdirs maintainer-clean \
829 maintainer-clean-generic mostlyclean mostlyclean-compile \
830 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
831 tags uninstall uninstall-am uninstall-includesHEADERS \
832 uninstall-libLTLIBRARIES
833
834
835# Tell versions [3.59,3.63) of GNU make to not export all variables.
836# Otherwise a system limit (for SysV at least) may be exceeded.
837.NOEXPORT:
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file.c b/libraries/ecore/src/lib/ecore_file/ecore_file.c
new file mode 100644
index 0000000..2546f2f
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/ecore_file.c
@@ -0,0 +1,1110 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <string.h>
7
8#ifndef _MSC_VER
9# include <unistd.h>
10# include <libgen.h>
11#endif
12
13#ifdef _WIN32
14# include <direct.h>
15#endif
16
17#ifdef HAVE_FEATURES_H
18# include <features.h>
19#endif
20#include <ctype.h>
21#include <errno.h>
22
23#ifdef HAVE_ATFILE_SOURCE
24# include <dirent.h>
25#endif
26
27#include "ecore_file_private.h"
28
29int _ecore_file_log_dom = -1;
30static int _ecore_file_init_count = 0;
31
32/* externally accessible functions */
33
34/**
35 * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions
36 *
37 * @{
38 */
39
40/**
41 * @brief Initialize the Ecore_File library.
42 *
43 * @return 1 or greater on success, 0 on error.
44 *
45 * This function sets up Ecore_File and the services it will use
46 * (monitoring, downloading, PATH related feature). It returns 0 on
47 * failure, otherwise it returns the number of times it has already
48 * been called.
49 *
50 * When Ecore_File is not used anymore, call ecore_file_shutdown()
51 * to shut down the Ecore_File library.
52 */
53EAPI int
54ecore_file_init()
55{
56 if (++_ecore_file_init_count != 1)
57 return _ecore_file_init_count;
58
59 if (!ecore_init())
60 return --_ecore_file_init_count;
61
62 _ecore_file_log_dom = eina_log_domain_register
63 ("ecore_file", ECORE_FILE_DEFAULT_LOG_COLOR);
64 if(_ecore_file_log_dom < 0)
65 {
66 EINA_LOG_ERR("Impossible to create a log domain for the ecore file module.");
67 return --_ecore_file_init_count;
68 }
69 ecore_file_path_init();
70 ecore_file_monitor_init();
71 ecore_file_download_init();
72
73 /* FIXME: were the tests disabled for a good reason ? */
74
75 /*
76 if (!ecore_file_monitor_init())
77 goto shutdown_ecore_file_path;
78
79 if (!ecore_file_download_init())
80 goto shutdown_ecore_file_monitor;
81 */
82
83 return _ecore_file_init_count;
84
85 /*
86 shutdown_ecore_file_monitor:
87 ecore_file_monitor_shutdown();
88 shutdown_ecore_file_path:
89 ecore_file_path_shutdown();
90
91 return --_ecore_file_init_count;
92 */
93}
94
95/**
96 * @brief Shut down the Ecore_File library.
97 *
98 * @return 0 when the library is completely shut down, 1 or
99 * greater otherwise.
100 *
101 * This function shuts down the Ecore_File library. It returns 0 when it has
102 * been called the same number of times than ecore_file_init(). In that case
103 * it shuts down all the services it uses.
104 */
105EAPI int
106ecore_file_shutdown()
107{
108 if (--_ecore_file_init_count != 0)
109 return _ecore_file_init_count;
110
111 ecore_file_download_shutdown();
112 ecore_file_monitor_shutdown();
113 ecore_file_path_shutdown();
114
115 eina_log_domain_unregister(_ecore_file_log_dom);
116 _ecore_file_log_dom = -1;
117
118 ecore_shutdown();
119
120 return _ecore_file_init_count;
121}
122
123/**
124 * @brief Get the time of the last modification to the given file.
125 *
126 * @param file The name of the file.
127 * @return Return the time of the last data modification, or 0 on
128 * failure.
129 *
130 * This function returns the time of the last modification of
131 * @p file. On failure, it returns 0.
132 */
133EAPI long long
134ecore_file_mod_time(const char *file)
135{
136 struct stat st;
137
138 if (stat(file, &st) < 0) return 0;
139 return st.st_mtime;
140}
141
142/**
143 * @brief Get the size of the given file.
144 *
145 * @param file The name of the file.
146 * @return Return the size of the file in bytes, or 0 on failure.
147 *
148 * This function returns the size of @p file in bytes. On failure, it
149 * returns 0.
150 */
151EAPI long long
152ecore_file_size(const char *file)
153{
154 struct stat st;
155
156 if (stat(file, &st) < 0) return 0;
157 return st.st_size;
158}
159
160/**
161 * @brief Check if the given file exists.
162 *
163 * @param file The name of the file.
164 * @return Return EINA_TRUE if the file exists, EINA_FALSE otherwise.
165 *
166 * This function returns EINA_TRUE if @p file exists on local filesystem,
167 * EINA_FALSE otherwise.
168 */
169EAPI Eina_Bool
170ecore_file_exists(const char *file)
171{
172 struct stat st;
173 if (!file) return EINA_FALSE;
174
175 /*Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor*/
176 if (stat(file, &st) < 0 && strcmp(file, "/")) return EINA_FALSE;
177 return EINA_TRUE;
178}
179
180/**
181 * @brief Check if the given file is a directory.
182 *
183 * @param file The name of the file.
184 * @return Return EINA_TRUE if the file exists and is a directory,
185 * EINA_FALSE otherwise.
186 *
187 * This function returns EINA_TRUE if @p file exists exists and is a
188 * directory on local filesystem, EINA_FALSE otherwise.
189 */
190EAPI Eina_Bool
191ecore_file_is_dir(const char *file)
192{
193 struct stat st;
194
195 if (stat(file, &st) < 0) return EINA_FALSE;
196 if (S_ISDIR(st.st_mode)) return EINA_TRUE;
197 return EINA_FALSE;
198}
199
200static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
201
202/**
203 * @brief Create a new directory.
204 *
205 * @param dir The name of the directory to create
206 * @return EINA_TRUE on successful creation, EINA_FALSE otherwise.
207 *
208 * This function creates the directory @p dir with the mode S_IRUSR |
209 * S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH. On
210 * success, it returns EINA_TRUE, EINA_FALSE otherwise.
211 */
212EAPI Eina_Bool
213ecore_file_mkdir(const char *dir)
214{
215 if (mkdir(dir, default_mode) < 0) return EINA_FALSE;
216 return EINA_TRUE;
217}
218
219/**
220 * @brief Create complete directory in a batch.
221 *
222 * @param dirs The list of directories, null terminated.
223 * @return The number of successful directories created, -1 if dirs is
224 * @c NULL.
225 *
226 * This function creates all the directories that are in the null
227 * terminated array @p dirs. The function loops over the directories
228 * and call ecore_file_mkdir(). This function returns -1 if @p dirs is
229 * @c NULL, otherwise if returns the number of suceesfully created
230 * directories.
231 */
232EAPI int
233ecore_file_mkdirs(const char **dirs)
234{
235 int i = 0;
236
237 if (!dirs) return -1;
238
239 for (; *dirs; dirs++)
240 if (ecore_file_mkdir(*dirs))
241 i++;
242 return i;
243}
244
245/**
246 * @brief Create complete list of sub-directories in a batch (optimized).
247 *
248 * @param base The base directory to act on.
249 * @param subdirs The list of directories, null terminated.
250 * @return number of successful directories created, -1 on failure.
251 *
252 * This function creates all the directories that are in the null
253 * terminated array @p dirs in the @p base directory. If @p base does
254 * not exist, it will be created. The function loops over the directories
255 * and call ecore_file_mkdir(). The whole path of the directories must
256 * exist. So if base/a/b/c wants to be created, @p subdirs must
257 * contain "a", "a/b" and "a/b/c", in that order. This function
258 * returns -1 if @p dirs or @p base are @c NULL, or if @p base is
259 * empty ("\0"). It returns 0 is @p base is not a directory or
260 * invalid, or if it can't be created. Otherwise if returns the number
261 * of suceesfully created directories.
262 */
263EAPI int
264ecore_file_mksubdirs(const char *base, const char **subdirs)
265{
266#ifndef HAVE_ATFILE_SOURCE
267 char buf[PATH_MAX];
268 int baselen;
269#else
270 int fd;
271 DIR *dir;
272#endif
273 int i;
274
275 if (!subdirs) return -1;
276 if ((!base) || (base[0] == '\0')) return -1;
277
278 if ((!ecore_file_is_dir(base)) && (!ecore_file_mkpath(base)))
279 return 0;
280
281#ifndef HAVE_ATFILE_SOURCE
282 baselen = eina_strlcpy(buf, base, sizeof(buf));
283 if ((baselen < 1) || (baselen + 1 >= (int)sizeof(buf)))
284 return 0;
285
286 if (buf[baselen - 1] != '/')
287 {
288 buf[baselen] = '/';
289 baselen++;
290 }
291#else
292 dir = opendir(base);
293 if (!dir)
294 return 0;
295 fd = dirfd(dir);
296#endif
297
298 i = 0;
299 for (; *subdirs; subdirs++)
300 {
301 struct stat st;
302
303#ifndef HAVE_ATFILE_SOURCE
304 eina_strlcpy(buf + baselen, *subdirs, sizeof(buf) - baselen);
305 if (stat(buf, &st) == 0)
306#else
307 if (fstatat(fd, *subdirs, &st, 0) == 0)
308#endif
309 {
310 if (S_ISDIR(st.st_mode))
311 {
312 i++;
313 continue;
314 }
315 }
316 else
317 {
318 if (errno == ENOENT)
319 {
320#ifndef HAVE_ATFILE_SOURCE
321 if (mkdir(buf, default_mode) == 0)
322#else
323 if (mkdirat(fd, *subdirs, default_mode) == 0)
324#endif
325 {
326 i++;
327 continue;
328 }
329 }
330 }
331 }
332
333#ifdef HAVE_ATFILE_SOURCE
334 closedir(dir);
335#endif
336
337 return i;
338}
339
340/**
341 * @brief Delete the given directory.
342 *
343 * @param dir The name of the directory to delete.
344 * @return EINA_TRUE on success, EINA_FALSE otherwise.
345 *
346 * This function deletes @p dir. It returns EINA_TRUE on success,
347 * EINA_FALSE otherwise.
348 */
349EAPI Eina_Bool
350ecore_file_rmdir(const char *dir)
351{
352 if (rmdir(dir) < 0) return EINA_FALSE;
353 return EINA_TRUE;
354}
355
356/**
357 * @brief Delete the given file.
358 *
359 * @param file The name of the file to delete.
360 * @return EINA_TRUE on success, EINA_FALSE otherwise.
361 *
362 * This function deletes @p file. It returns EINA_TRUE on success,
363 * EINA_FALSE otherwise.
364 */
365EAPI Eina_Bool
366ecore_file_unlink(const char *file)
367{
368 if (unlink(file) < 0) return EINA_FALSE;
369 return EINA_TRUE;
370}
371
372/**
373 * @brief Remove the given file or directory.
374 *
375 * @param file The name of the file or directory to delete.
376 * @return EINA_TRUE on success, EINA_FALSE otherwise.
377 *
378 * This function removes @p file. It returns EINA_TRUE on success,
379 * EINA_FALSE otherwise.
380 */
381EAPI Eina_Bool
382ecore_file_remove(const char *file)
383{
384 if (remove(file) < 0) return EINA_FALSE;
385 return EINA_TRUE;
386}
387
388/**
389 * @brief Delete the given directory and all its contents.
390 *
391 * @param dir The name of the directory to delete.
392 * @return EINA_TRUE on success, EINA_FALSE otherwise.
393 *
394 * This function delete @p dir and all its contents. If @p dir is a
395 * link only the link is removed. It returns EINA_TRUE on success,
396 * EINA_FALSE otherwise.
397 */
398EAPI Eina_Bool
399ecore_file_recursive_rm(const char *dir)
400{
401 Eina_Iterator *it;
402 char buf[PATH_MAX];
403 struct stat st;
404 int ret;
405
406 if (readlink(dir, buf, sizeof(buf)) > 0)
407 return ecore_file_unlink(dir);
408
409 ret = stat(dir, &st);
410 if ((ret == 0) && (S_ISDIR(st.st_mode)))
411 {
412 Eina_File_Direct_Info *info;
413
414 ret = 1;
415 if (stat(dir, &st) == -1) return EINA_FALSE; /* WOOT: WHY ARE WE CALLING STAT TWO TIMES ??? */
416
417 it = eina_file_direct_ls(dir);
418 EINA_ITERATOR_FOREACH(it, info)
419 {
420 if (!ecore_file_recursive_rm(info->path))
421 ret = 0;
422 }
423 eina_iterator_free(it);
424
425 if (!ecore_file_rmdir(dir)) ret = 0;
426 if (ret)
427 return EINA_TRUE;
428 else
429 return EINA_FALSE;
430 }
431 else
432 {
433 if (ret == -1) return EINA_FALSE;
434 return ecore_file_unlink(dir);
435 }
436}
437
438static inline Eina_Bool
439_ecore_file_mkpath_if_not_exists(const char *path)
440{
441 struct stat st;
442
443 /* Windows: path like C: or D: etc are valid, but stat() returns an error */
444#ifdef _WIN32
445 if ((strlen(path) == 2) &&
446 ((path[0] >= 'a' && path[0] <= 'z') ||
447 (path[0] >= 'A' && path[0] <= 'Z')) &&
448 (path[1] == ':'))
449 return EINA_TRUE;
450#endif
451
452 if (stat(path, &st) < 0)
453 return ecore_file_mkdir(path);
454 else if (!S_ISDIR(st.st_mode))
455 return EINA_FALSE;
456 else
457 return EINA_TRUE;
458}
459
460/**
461 * @brief Create a complete path.
462 *
463 * @param path The path to create
464 * @return EINA_TRUE on success, EINA_FALSE otherwise.
465 *
466 * This function creates @p path and all the subdirectories it
467 * contains. The separator is '/' or '\'. If @p path exists, this
468 * function returns EINA_TRUE immediately. It returns EINA_TRUE on
469 * success, EINA_FALSE otherwise.
470 */
471EAPI Eina_Bool
472ecore_file_mkpath(const char *path)
473{
474 char ss[PATH_MAX];
475 unsigned int i;
476
477 if (ecore_file_is_dir(path))
478 return EINA_TRUE;
479
480 for (i = 0; path[i] != '\0'; ss[i] = path[i], i++)
481 {
482 if (i == sizeof(ss) - 1) return EINA_FALSE;
483 if (((path[i] == '/') || (path[i] == '\\')) && (i > 0))
484 {
485 ss[i] = '\0';
486 if (!_ecore_file_mkpath_if_not_exists(ss))
487 return EINA_FALSE;
488 }
489 }
490 ss[i] = '\0';
491 return _ecore_file_mkpath_if_not_exists(ss);
492}
493
494/**
495 * @brief Create complete paths in a batch.
496 *
497 * @param paths list of paths, null terminated.
498 * @return number of successful paths created, -1 if paths is NULL.
499 *
500 * This function creates all the directories that are in the null
501 * terminated array @p paths. The function loops over the directories
502 * and call ecore_file_mkpath(), hence on Windows, '\' must be
503 * replaced by '/' before calling that function. This function
504 * returns -1 if @p paths is @c NULL. Otherwise if returns the number
505 * of suceesfully created directories.
506 */
507EAPI int
508ecore_file_mkpaths(const char **paths)
509{
510 int i = 0;
511
512 if (!paths) return -1;
513
514 for (; *paths; paths++)
515 if (ecore_file_mkpath(*paths))
516 i++;
517 return i;
518}
519
520/**
521 * @brief Copy the given file to the given destination.
522 *
523 * @param src The name of the source file.
524 * @param dst The name of the destination file.
525 * @return EINA_TRUE on success, EINA_FALSE otherwise.
526 *
527 * This function copies @p src to @p dst. If the absolute path name of
528 * @p src and @p dst can not be computed, or if they are equal, or if
529 * the copy fails, the function returns EINA_FALSE, otherwise it
530 * returns EINA_TRUE.
531 */
532EAPI Eina_Bool
533ecore_file_cp(const char *src, const char *dst)
534{
535 FILE *f1, *f2;
536 char buf[16384];
537 char realpath1[PATH_MAX], realpath2[PATH_MAX];
538 size_t num;
539 Eina_Bool ret = EINA_TRUE;
540
541 if (!realpath(src, realpath1)) return EINA_FALSE;
542 if (realpath(dst, realpath2) && !strcmp(realpath1, realpath2)) return EINA_FALSE;
543
544 f1 = fopen(src, "rb");
545 if (!f1) return EINA_FALSE;
546 f2 = fopen(dst, "wb");
547 if (!f2)
548 {
549 fclose(f1);
550 return EINA_FALSE;
551 }
552 while ((num = fread(buf, 1, sizeof(buf), f1)) > 0)
553 {
554 if (fwrite(buf, 1, num, f2) != num) ret = EINA_FALSE;
555 }
556 fclose(f1);
557 fclose(f2);
558 return ret;
559}
560
561/**
562 * @brief Move the given file to the given destination.
563 *
564 * @param src The name of the source file.
565 * @param dst The name of the destination file.
566 * @return EINA_TRUE on success, EINA_FALSE otherwise.
567 *
568 * This function moves @p src to @p dst. It returns EINA_TRUE on
569 * success, EINA_FALSE otherwise.
570 */
571EAPI Eina_Bool
572ecore_file_mv(const char *src, const char *dst)
573{
574 char buf[PATH_MAX];
575 int fd;
576
577 if (rename(src, dst))
578 {
579 // File cannot be moved directly because
580 // it resides on a different mount point.
581 if (errno == EXDEV)
582 {
583 struct stat st;
584
585 // Make sure this is a regular file before
586 // we do anything fancy.
587 stat(src, &st);
588 if (S_ISREG(st.st_mode))
589 {
590 char *dir;
591
592 dir = ecore_file_dir_get(dst);
593 // Since we can't directly rename, try to
594 // copy to temp file in the dst directory
595 // and then rename.
596 snprintf(buf, sizeof(buf), "%s/.%s.tmp.XXXXXX",
597 dir, ecore_file_file_get(dst));
598 free(dir);
599 fd = mkstemp(buf);
600 if (fd < 0)
601 {
602 perror("mkstemp");
603 goto FAIL;
604 }
605 close(fd);
606
607 // Copy to temp file
608 if (!ecore_file_cp(src, buf))
609 goto FAIL;
610
611 // Set file permissions of temp file to match src
612 chmod(buf, st.st_mode);
613
614 // Try to atomically move temp file to dst
615 if (rename(buf, dst))
616 {
617 // If we still cannot atomically move
618 // do a normal copy and hope for the best.
619 if (!ecore_file_cp(buf, dst))
620 goto FAIL;
621 }
622
623 // Delete temporary file and src
624 ecore_file_unlink(buf);
625 ecore_file_unlink(src);
626 goto PASS;
627 }
628 }
629 goto FAIL;
630 }
631
632PASS:
633 return EINA_TRUE;
634
635FAIL:
636 return EINA_FALSE;
637}
638
639/**
640 * @brief Create a symbolic link.
641 *
642 * @param src The name of the file to link.
643 * @param dest The name of link.
644 * @return EINA_TRUE on success, EINA_FALSE otherwise.
645 *
646 * This function create the symbolic link @p dest of @p src. This
647 * function does not work on Windows. It returns EINA_TRUE on success,
648 * EINA_FALSE otherwise.
649 */
650EAPI Eina_Bool
651ecore_file_symlink(const char *src, const char *dest)
652{
653 if (!symlink(src, dest)) return EINA_TRUE;
654
655 return EINA_FALSE;
656}
657
658/**
659 * @brief Get the canonicalized absolute path name.
660 *
661 * @param file The file path.
662 * @return The canonicalized absolute pathname or an empty string on
663 * failure.
664 *
665 * This function returns the absolute path name of @p file as a newly
666 * allocated string. If @p file is @c NULL, or on error, this function
667 * returns an empty string. Otherwise, it returns the absolute path
668 * name. When not needed anymore, the returned value must be freed.
669 */
670EAPI char *
671ecore_file_realpath(const char *file)
672{
673 char buf[PATH_MAX];
674
675 /*
676 * Some implementations of realpath do not conform to the SUS.
677 * And as a result we must prevent a null arg from being passed.
678 */
679 if (!file) return strdup("");
680 if (!realpath(file, buf)) return strdup("");
681
682 return strdup(buf);
683}
684
685/**
686 * Get the filename from a given path.
687 *
688 * @param path The complete path.
689 * @return The file name.
690 *
691 * This function returns the file name of @p path. If @p path is
692 * @c NULL, the functions returns @c NULL.
693 */
694EAPI const char *
695ecore_file_file_get(const char *path)
696{
697 char *result = NULL;
698
699 if (!path) return NULL;
700 if ((result = strrchr(path, '/'))) result++;
701 else result = (char *)path;
702 return result;
703}
704
705/**
706 * @brief Get the directory where the given file resides.
707 *
708 * @param file The name of the file.
709 * @return The directory name.
710 *
711 * This function returns the directory where @p file resides as anewly
712 * allocated string. If @p file is @c NULL or on error, this function
713 * returns @c NULL. When not needed anymore, the returned value must
714 * be freed.
715 */
716EAPI char *
717ecore_file_dir_get(const char *file)
718{
719 char *p;
720 char buf[PATH_MAX];
721
722 if (!file) return NULL;
723 strncpy(buf, file, PATH_MAX);
724 buf[PATH_MAX - 1] = 0;
725 p = dirname(buf);
726 return strdup(p);
727}
728
729/**
730 * @brief Check if the given file can be read.
731 *
732 * @param file The name of the file.
733 * @return EINA_TRUE if the file is readable, EINA_FALSE otherwise.
734 *
735 * This function returns EINA_TRUE if @p file can be read, EINA_FALSE
736 * otherwise.
737 */
738EAPI Eina_Bool
739ecore_file_can_read(const char *file)
740{
741 if (!file) return EINA_FALSE;
742 if (!access(file, R_OK)) return EINA_TRUE;
743 return EINA_FALSE;
744}
745
746/**
747 * @brief Check if the given file can be written.
748 *
749 * @param file The name of the file.
750 * @return EINA_TRUE if the file is writable, EINA_FALSE otherwise.
751 *
752 * This function returns EINA_TRUE if @p file can be written, EINA_FALSE
753 * otherwise.
754 */
755EAPI Eina_Bool
756ecore_file_can_write(const char *file)
757{
758 if (!file) return EINA_FALSE;
759 if (!access(file, W_OK)) return EINA_TRUE;
760 return EINA_FALSE;
761}
762
763/**
764 * @bbrief Check if the given file can be executed.
765 *
766 * @param file The name of the file.
767 * @return EINA_TRUE if the file can be executed, EINA_FALSE otherwise.
768 *
769 * This function returns EINA_TRUE if @p file can be executed, EINA_FALSE
770 * otherwise.
771 */
772EAPI Eina_Bool
773ecore_file_can_exec(const char *file)
774{
775 if (!file) return EINA_FALSE;
776 if (!access(file, X_OK)) return EINA_TRUE;
777 return EINA_FALSE;
778}
779
780/**
781 * @brief Get the path pointed by the given link.
782 *
783 * @param lnk The name of the link.
784 * @return The path pointed by link or NULL.
785 *
786 * This function returns the path pointed by @p link as a newly
787 * allocated string. This function does not work on Windows. On
788 * failure, the function returns @c NULL. When not needed anymore, the
789 * returned value must be freed.
790 */
791EAPI char *
792ecore_file_readlink(const char *lnk)
793{
794 char buf[PATH_MAX];
795 int count;
796
797 if ((count = readlink(lnk, buf, sizeof(buf) - 1)) < 0) return NULL;
798 buf[count] = 0;
799 return strdup(buf);
800}
801
802/**
803 * @brief Get the list of the files and directories in the given
804 * directory.
805 *
806 * @param dir The name of the directory to list
807 * @return Return an Eina_List containing all the files in the directory;
808 * on failure it returns NULL.
809 *
810 * This function returns a list of allocated strings of all the files
811 * and directories contained in @p dir. The list will be sorted with
812 * strcoll as compare function. That means that you may want to set
813 * the current locale for the category LC_COLLATE with
814 * setlocale(). For more information see the manual pages of strcoll
815 * and setlocale. The list will not contain the directory entries for
816 * '.' and '..'. On failure, @c NULL is returned. When not needed
817 * anymore, the list elements must be freed.
818 */
819EAPI Eina_List *
820ecore_file_ls(const char *dir)
821{
822 Eina_File_Direct_Info *info;
823 Eina_Iterator *ls;
824 Eina_List *list = NULL;
825
826 ls = eina_file_direct_ls(dir);
827 EINA_ITERATOR_FOREACH(ls, info)
828 {
829 char *f;
830
831 f = strdup(info->path + info->name_start);
832 list = eina_list_append(list, f);
833 }
834 eina_iterator_free(ls);
835
836 list = eina_list_sort(list, eina_list_count(list), EINA_COMPARE_CB(strcoll));
837
838 return list;
839}
840
841/**
842 * @brief Return the executable from the given command.
843 *
844 * @param app The application command, with parameters.
845 *
846 * This function returns the executable from @p app as a newly
847 * allocated string. Arguments are removed and escae characters are
848 * handled. If @p app is @c NULL, or on failure, the function returns
849 * @c NULL. When not needed anymore, the returned value must be freed.
850 */
851EAPI char *
852ecore_file_app_exe_get(const char *app)
853{
854 char *p, *pp, *exe1 = NULL, *exe2 = NULL;
855 char *exe = NULL;
856 int in_quot_dbl = 0, in_quot_sing = 0, restart = 0;
857
858 if (!app) return NULL;
859
860 p = (char *)app;
861restart:
862 while ((*p) && (isspace(*p))) p++;
863 exe1 = p;
864 while (*p)
865 {
866 if (in_quot_sing)
867 {
868 if (*p == '\'')
869 in_quot_sing = 0;
870 }
871 else if (in_quot_dbl)
872 {
873 if (*p == '\"')
874 in_quot_dbl = 0;
875 }
876 else
877 {
878 if (*p == '\'')
879 in_quot_sing = 1;
880 else if (*p == '\"')
881 in_quot_dbl = 1;
882 if ((isspace(*p)) && (!((p > app) && (p[-1] != '\\'))))
883 break;
884 }
885 p++;
886 }
887 exe2 = p;
888 if (exe2 == exe1) return NULL;
889 if (*exe1 == '~')
890 {
891 char *homedir;
892 int len;
893
894 /* Skip ~ */
895 exe1++;
896
897 homedir = getenv("HOME");
898 if (!homedir) return NULL;
899 len = strlen(homedir);
900 if (exe) free(exe);
901 exe = malloc(len + exe2 - exe1 + 2);
902 if (!exe) return NULL;
903 pp = exe;
904 if (len)
905 {
906 strcpy(exe, homedir);
907 pp += len;
908 if (*(pp - 1) != '/')
909 {
910 *pp = '/';
911 pp++;
912 }
913 }
914 }
915 else
916 {
917 if (exe) free(exe);
918 exe = malloc(exe2 - exe1 + 1);
919 if (!exe) return NULL;
920 pp = exe;
921 }
922 p = exe1;
923 restart = 0;
924 in_quot_dbl = 0;
925 in_quot_sing = 0;
926 while (*p)
927 {
928 if (in_quot_sing)
929 {
930 if (*p == '\'')
931 in_quot_sing = 0;
932 else
933 {
934 *pp = *p;
935 pp++;
936 }
937 }
938 else if (in_quot_dbl)
939 {
940 if (*p == '\"')
941 in_quot_dbl = 0;
942 else
943 {
944 /* technically this is wrong. double quotes also accept
945 * special chars:
946 *
947 * $, `, \
948 */
949 *pp = *p;
950 pp++;
951 }
952 }
953 else
954 {
955 /* technically we should handle special chars:
956 *
957 * $, `, \, etc.
958 */
959 if ((p > exe1) && (p[-1] == '\\'))
960 {
961 if (*p != '\n')
962 {
963 *pp = *p;
964 pp++;
965 }
966 }
967 else if ((p > exe1) && (*p == '='))
968 {
969 restart = 1;
970 *pp = *p;
971 pp++;
972 }
973 else if (*p == '\'')
974 in_quot_sing = 1;
975 else if (*p == '\"')
976 in_quot_dbl = 1;
977 else if (isspace(*p))
978 {
979 if (restart)
980 goto restart;
981 else
982 break;
983 }
984 else
985 {
986 *pp = *p;
987 pp++;
988 }
989 }
990 p++;
991 }
992 *pp = 0;
993 return exe;
994}
995
996/**
997 * @brief Add the escape sequence ('\\') to the given file name.
998 *
999 * @param filename The file name.
1000 * @return The file name with special characters escaped.
1001 *
1002 * This function adds the escape sequence ('\\') to the given file
1003 * name and returns the result as a newly allocated string. If the
1004 * length of the returned string is longer than PATH_MAX, or on
1005 * failure, @c NULL is returned. When not needed anymore, the returned
1006 * value must be freed.
1007 */
1008EAPI char *
1009ecore_file_escape_name(const char *filename)
1010{
1011 const char *p;
1012 char *q;
1013 char buf[PATH_MAX];
1014
1015 p = filename;
1016 q = buf;
1017 while (*p)
1018 {
1019 if ((q - buf) > (PATH_MAX - 6)) return NULL;
1020 if (
1021 (*p == ' ') || (*p == '\t') || (*p == '\n') ||
1022 (*p == '\\') || (*p == '\'') || (*p == '\"') ||
1023 (*p == ';') || (*p == '!') || (*p == '#') ||
1024 (*p == '$') || (*p == '%') || (*p == '&') ||
1025 (*p == '*') || (*p == '(') || (*p == ')') ||
1026 (*p == '[') || (*p == ']') || (*p == '{') ||
1027 (*p == '}') || (*p == '|') || (*p == '<') ||
1028 (*p == '>') || (*p == '?')
1029 )
1030 {
1031 *q = '\\';
1032 q++;
1033 }
1034 *q = *p;
1035 q++;
1036 p++;
1037 }
1038 *q = 0;
1039 return strdup(buf);
1040}
1041
1042/**
1043 * @bried Remove the extension from the given file name.
1044 *
1045 * @param path The name of the file.
1046 * @return A newly allocated string with the extension stripped out or
1047 * NULL on errors.
1048 *
1049 * This function removes the extension from @p path and returns the
1050 * result as a newly allocated string. If @p path is @c NULL, or on
1051 * failure, the function returns @c NULL. When not needed anymore, the
1052 * returned value must be freed.
1053 */
1054EAPI char *
1055ecore_file_strip_ext(const char *path)
1056{
1057 char *p, *file = NULL;
1058
1059 if (!path)
1060 return NULL;
1061
1062 p = strrchr(path, '.');
1063 if (!p)
1064 file = strdup(path);
1065 else if (p != path)
1066 {
1067 file = malloc(((p - path) + 1) * sizeof(char));
1068 if (file)
1069 {
1070 memcpy(file, path, (p - path));
1071 file[p - path] = 0;
1072 }
1073 }
1074
1075 return file;
1076}
1077
1078/**
1079 * @brief Check if the given directory is empty.
1080 *
1081 * @param dir The name of the directory to check.
1082 * @return 1 if directory is empty, 0 if it has at least one file or
1083 * -1 in case of errors.
1084 *
1085 * This functions checks if @p dir is empty. The '.' and '..' files
1086 * will be ignored. If @p dir is empty, 1 is returned, if it contains
1087 * at least 1 file, 0 is returned. On failure, -1 is returned.
1088 */
1089EAPI int
1090ecore_file_dir_is_empty(const char *dir)
1091{
1092 Eina_File_Direct_Info *info;
1093 Eina_Iterator *it;
1094
1095 it = eina_file_direct_ls(dir);
1096 if (!it) return -1;
1097
1098 EINA_ITERATOR_FOREACH(it, info)
1099 {
1100 eina_iterator_free(it);
1101 return 0;
1102 }
1103
1104 eina_iterator_free(it);
1105 return 1;
1106}
1107
1108/**
1109 * @}
1110 */
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file_download.c b/libraries/ecore/src/lib/ecore_file/ecore_file_download.c
new file mode 100644
index 0000000..c7efc4d
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/ecore_file_download.c
@@ -0,0 +1,440 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <string.h>
7
8#ifdef BUILD_ECORE_CON
9# include "Ecore_Con.h"
10#endif
11
12#include "ecore_file_private.h"
13
14#ifdef BUILD_ECORE_CON
15
16#define ECORE_MAGIC_FILE_DOWNLOAD_JOB 0xf7427cb8
17
18struct _Ecore_File_Download_Job
19{
20 ECORE_MAGIC;
21
22 Ecore_Con_Url *url_con;
23 FILE *file;
24
25 char *dst;
26
27 Ecore_File_Download_Completion_Cb completion_cb;
28 Ecore_File_Download_Progress_Cb progress_cb;
29};
30
31#ifdef HAVE_CURL
32Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst,
33 Ecore_File_Download_Completion_Cb completion_cb,
34 Ecore_File_Download_Progress_Cb progress_cb,
35 void *data,
36 Eina_Hash *headers);
37
38static Eina_Bool _ecore_file_download_url_complete_cb(void *data, int type, void *event);
39static Eina_Bool _ecore_file_download_url_progress_cb(void *data, int type, void *event);
40#endif
41
42static Ecore_Event_Handler *_url_complete_handler = NULL;
43static Ecore_Event_Handler *_url_progress_download = NULL;
44static Eina_List *_job_list;
45
46#endif /* BUILD_ECORE_CON */
47
48int
49ecore_file_download_init(void)
50{
51#ifdef BUILD_ECORE_CON
52 if (!ecore_con_url_init())
53 return 0;
54
55# ifdef HAVE_CURL
56 _url_complete_handler = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _ecore_file_download_url_complete_cb, NULL);
57 _url_progress_download = ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _ecore_file_download_url_progress_cb, NULL);
58# endif
59
60#endif /* BUILD_ECORE_CON */
61
62 return 1;
63}
64
65void
66ecore_file_download_shutdown(void)
67{
68#ifdef BUILD_ECORE_CON
69 if (_url_complete_handler)
70 ecore_event_handler_del(_url_complete_handler);
71 if (_url_progress_download)
72 ecore_event_handler_del(_url_progress_download);
73 _url_complete_handler = NULL;
74 _url_progress_download = NULL;
75 ecore_file_download_abort_all();
76
77 ecore_con_url_shutdown();
78#endif /* BUILD_ECORE_CON */
79}
80
81#ifdef BUILD_ECORE_CON
82# ifdef HAVE_CURL
83static Eina_Bool
84_ecore_file_download_headers_foreach_cb(const Eina_Hash *hash __UNUSED__, const void *key, void *data, void *fdata)
85{
86 Ecore_File_Download_Job *job = fdata;
87 ecore_con_url_additional_header_add(job->url_con, key, data);
88
89 return EINA_TRUE;
90}
91# endif
92#endif
93
94static Eina_Bool
95_ecore_file_download(const char *url,
96 const char *dst,
97 Ecore_File_Download_Completion_Cb completion_cb,
98 Ecore_File_Download_Progress_Cb progress_cb,
99 void *data,
100 Ecore_File_Download_Job **job_ret,
101 Eina_Hash *headers)
102{
103#ifdef BUILD_ECORE_CON
104 char *dir = ecore_file_dir_get(dst);
105
106 if (!ecore_file_is_dir(dir))
107 {
108 ERR("%s is not a directory", dir);
109 free(dir);
110 return EINA_FALSE;
111 }
112 free(dir);
113 if (ecore_file_exists(dst))
114 {
115 WRN("%s already exists", dst);
116 return EINA_FALSE;
117 }
118
119 if (!strncmp(url, "file://", 7))
120 {
121 /* FIXME: Maybe fork? Might take a while to copy.
122 * Check filesize? */
123 /* Just copy it */
124
125 url += 7;
126 /* skip hostname */
127 url = strchr(url, '/');
128 return ecore_file_cp(url, dst);
129 }
130# ifdef HAVE_CURL
131 else if ((!strncmp(url, "http://", 7)) || (!strncmp(url, "https://", 8)) ||
132 (!strncmp(url, "ftp://", 6)))
133 {
134 /* download */
135 Ecore_File_Download_Job *job;
136
137 job = _ecore_file_download_curl(url, dst, completion_cb, progress_cb, data, headers);
138 if(job_ret) *job_ret = job;
139 if(job)
140 return EINA_TRUE;
141 else
142 {
143 ERR("no job returned\n");
144 return EINA_FALSE;
145 }
146 return job ? EINA_TRUE : EINA_FALSE;
147 }
148# else
149 else if ((!strncmp(url, "http://", 7)) || (!strncmp(url, "https://", 8)) ||
150 (!strncmp(url, "ftp://", 6)))
151 {
152 (void)completion_cb;
153 (void)progress_cb;
154 (void)data;
155 (void)job_ret;
156 (void)headers;
157 return EINA_FALSE;
158 }
159# endif
160 else
161 {
162 return EINA_FALSE;
163 }
164#else
165 (void)url;
166 (void)dst;
167 (void)completion_cb;
168 (void)progress_cb;
169 (void)data;
170 (void)job_ret;
171 (void)headers;
172 return EINA_FALSE;
173#endif /* BUILD_ECORE_CON */
174}
175
176/**
177 * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions
178 *
179 * @{
180 */
181
182/**
183 * @brief Download the given url to the given destination.
184 *
185 * @param url The complete url to download.
186 * @param dst The local file to save the downloaded to.
187 * @param completion_cb A callback called on download complete.
188 * @param progress_cb A callback called during the download operation.
189 * @param data User data passed to both callbacks.
190 * @param job_ret Job used to abort the download.
191 * @return EINA_TRUE if the download start or EINA_FALSE on failure
192 *
193 * This function starts the download of the URL @p url and saves it to
194 * @p dst. @p url must provide the protocol, including 'http://',
195 * 'ftp://' or 'file://'. Ecore_File must be compiled with CURL to
196 * download using http and ftp protocols. If @p dst is ill-formed, or
197 * if it already exists, the function returns EINA_FALSE. When the
198 * download is complete, the callback @p completion_cb is called and
199 * @p data is passed to it. The @p status parameter of @p completion_cb
200 * will be filled with the status of the download (200, 404,...). The
201 * @p progress_cb is called during the download operation, each time a
202 * packet is received or when CURL wants. It can be used to display the
203 * percentage of the downloaded file. Return 0 from this callback, if provided,
204 * to continue the operation or anything else to abort the download. The only
205 * operations that can be aborted are those with protocol 'http' or 'ftp'. In
206 * that case @p job_ret can be filled. It can be used with
207 * ecore_file_download_abort() or ecore_file_download_abort_all() to
208 * respectively abort one or all download operations. This function returns
209 * EINA_TRUE if the download starts, EINA_FALSE otherwise.
210 */
211EAPI Eina_Bool
212ecore_file_download(const char *url,
213 const char *dst,
214 Ecore_File_Download_Completion_Cb completion_cb,
215 Ecore_File_Download_Progress_Cb progress_cb,
216 void *data,
217 Ecore_File_Download_Job **job_ret)
218{
219 return _ecore_file_download(url, dst, completion_cb, progress_cb, data, job_ret, NULL);
220}
221
222/**
223 * @brief Download the given url to the given destination with additional headers.
224 *
225 * @param url The complete url to download.
226 * @param dst The local file to save the downloaded to.
227 * @param completion_cb A callback called on download complete.
228 * @param progress_cb A callback called during the download operation.
229 * @param data User data passed to both callbacks.
230 * @param job_ret Job used to abort the download.
231 * @param headers pointer of header lists.
232 * @return EINA_TRUE if the download start or EINA_FALSE on failure
233 */
234EAPI Eina_Bool
235ecore_file_download_full(const char *url,
236 const char *dst,
237 Ecore_File_Download_Completion_Cb completion_cb,
238 Ecore_File_Download_Progress_Cb progress_cb,
239 void *data,
240 Ecore_File_Download_Job **job_ret,
241 Eina_Hash *headers)
242{
243 return _ecore_file_download(url, dst, completion_cb, progress_cb, data, job_ret, headers);
244}
245
246/**
247 * @brief Check if the given protocol is available.
248 *
249 * @param protocol The protocol to check.
250 * @return EINA_TRUE if protocol is handled, EINA_FALSE otherwise.
251 *
252 * This function returns EINA_TRUE if @p protocol is supported,
253 * EINA_FALSE otherwise. @p protocol can be 'http://', 'ftp://' or
254 * 'file://'. Ecore_FILE must be compiled with CURL to handle http and
255 * ftp protocols.
256 */
257EAPI Eina_Bool
258ecore_file_download_protocol_available(const char *protocol)
259{
260#ifdef BUILD_ECORE_CON
261 if (!strncmp(protocol, "file://", 7)) return EINA_TRUE;
262# ifdef HAVE_CURL
263 else if (!strncmp(protocol, "http://", 7)) return EINA_TRUE;
264 else if (!strncmp(protocol, "ftp://", 6)) return EINA_TRUE;
265# endif
266#else
267 (void)protocol;
268#endif /* BUILD_ECORE_CON */
269
270 return EINA_FALSE;
271}
272
273#ifdef BUILD_ECORE_CON
274
275# ifdef HAVE_CURL
276static int
277_ecore_file_download_url_compare_job(const void *data1, const void *data2)
278{
279 const Ecore_File_Download_Job *job = data1;
280 const Ecore_Con_Url *url = data2;
281
282 if (job->url_con == url) return 0;
283 return -1;
284}
285
286static Eina_Bool
287_ecore_file_download_url_complete_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
288{
289 Ecore_Con_Event_Url_Complete *ev = event;
290 Ecore_File_Download_Job *job;
291
292 job = eina_list_search_unsorted(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
293 if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return ECORE_CALLBACK_PASS_ON;
294
295 fclose(job->file);
296 if (job->completion_cb)
297 job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, ev->status);
298
299 _job_list = eina_list_remove(_job_list, job);
300 free(job->dst);
301 ecore_con_url_free(job->url_con);
302 free(job);
303
304 return ECORE_CALLBACK_DONE;
305}
306
307static Eina_Bool
308_ecore_file_download_url_progress_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
309{
310/* this reports the downloads progress. if we return 0, then download
311 * continues, if we return anything else, then the download stops */
312 Ecore_Con_Event_Url_Progress *ev = event;
313 Ecore_File_Download_Job *job;
314
315 job = eina_list_search_unsorted(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
316 if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return ECORE_CALLBACK_PASS_ON;
317
318 if (job->progress_cb)
319 if (job->progress_cb(ecore_con_url_data_get(job->url_con), job->dst,
320 (long int) ev->down.total, (long int) ev->down.now,
321 (long int) ev->up.total, (long int) ev->up.now) != 0)
322 {
323 _job_list = eina_list_remove(_job_list, job);
324 fclose(job->file);
325 free(job->dst);
326 free(job);
327
328 return ECORE_CALLBACK_PASS_ON;
329 }
330
331 return ECORE_CALLBACK_DONE;
332}
333
334Ecore_File_Download_Job *
335_ecore_file_download_curl(const char *url, const char *dst,
336 Ecore_File_Download_Completion_Cb completion_cb,
337 Ecore_File_Download_Progress_Cb progress_cb,
338 void *data,
339 Eina_Hash *headers)
340{
341 Ecore_File_Download_Job *job;
342
343 job = calloc(1, sizeof(Ecore_File_Download_Job));
344 if (!job) return NULL;
345
346 ECORE_MAGIC_SET(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB);
347
348 job->file = fopen(dst, "wb");
349 if (!job->file)
350 {
351 free(job);
352 return NULL;
353 }
354 job->url_con = ecore_con_url_new(url);
355 if (!job->url_con)
356 {
357 fclose(job->file);
358 free(job);
359 return NULL;
360 }
361
362 if (headers) eina_hash_foreach(headers, _ecore_file_download_headers_foreach_cb, job);
363 ecore_con_url_fd_set(job->url_con, fileno(job->file));
364 ecore_con_url_data_set(job->url_con, data);
365
366 job->dst = strdup(dst);
367
368 job->completion_cb = completion_cb;
369 job->progress_cb = progress_cb;
370 _job_list = eina_list_append(_job_list, job);
371
372 if (!ecore_con_url_get(job->url_con))
373 {
374 ecore_con_url_free(job->url_con);
375 _job_list = eina_list_remove(_job_list, job);
376 fclose(job->file);
377 ecore_file_remove(job->dst);
378 free(job->dst);
379 free(job);
380 return NULL;
381 }
382
383 return job;
384}
385# endif
386#endif
387
388/**
389 * @brief Abort the given download job and call the completion_cb
390 * callbck with a status of 1 (error).
391 *
392 * @param job The download job to abort.
393 *
394 * This function aborts a download operation started by
395 * ecore_file_download(). @p job is the #Ecore_File_Download_Job
396 * structure filled by ecore_file_download(). If it is @c NULL, this
397 * function does nothing. To abort all the currently downloading
398 * operations, call ecore_file_download_abort_all().
399 */
400EAPI void
401ecore_file_download_abort(Ecore_File_Download_Job *job)
402{
403 if (!job)
404 return;
405
406#ifdef BUILD_ECORE_CON
407 if (job->completion_cb)
408 job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, 1);
409# ifdef HAVE_CURL
410 ecore_con_url_free(job->url_con);
411# endif
412 _job_list = eina_list_remove(_job_list, job);
413 fclose(job->file);
414 free(job->dst);
415 free(job);
416#endif /* BUILD_ECORE_CON */
417}
418
419/**
420 * @brief Abort all downloads.
421 *
422 * This function aborts all the downloads that have been started by
423 * ecore_file_download(). It loops over the started downloads and call
424 * ecore_file_download_abort() for each of them. To abort only one
425 * specific download operation, call ecore_file_download_abort().
426 */
427EAPI void
428ecore_file_download_abort_all(void)
429{
430#ifdef BUILD_ECORE_CON
431 Ecore_File_Download_Job *job;
432
433 EINA_LIST_FREE(_job_list, job)
434 ecore_file_download_abort(job);
435#endif /* BUILD_ECORE_CON */
436}
437
438/**
439 * @}
440 */
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file_monitor.c b/libraries/ecore/src/lib/ecore_file/ecore_file_monitor.c
new file mode 100644
index 0000000..7c334c0
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/ecore_file_monitor.c
@@ -0,0 +1,180 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecore_file_private.h"
6
7typedef enum {
8 ECORE_FILE_MONITOR_TYPE_NONE,
9#ifdef HAVE_INOTIFY
10 ECORE_FILE_MONITOR_TYPE_INOTIFY,
11#endif
12#ifdef HAVE_NOTIFY_WIN32
13 ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32,
14#endif
15#ifdef HAVE_POLL
16 ECORE_FILE_MONITOR_TYPE_POLL
17#endif
18} Ecore_File_Monitor_Type;
19
20static Ecore_File_Monitor_Type monitor_type = ECORE_FILE_MONITOR_TYPE_NONE;
21
22int
23ecore_file_monitor_init(void)
24{
25#ifdef HAVE_INOTIFY
26 monitor_type = ECORE_FILE_MONITOR_TYPE_INOTIFY;
27 if (ecore_file_monitor_inotify_init())
28 return 1;
29#endif
30#ifdef HAVE_NOTIFY_WIN32
31 monitor_type = ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32;
32 if (ecore_file_monitor_win32_init())
33 return 1;
34#endif
35#ifdef HAVE_POLL
36 monitor_type = ECORE_FILE_MONITOR_TYPE_POLL;
37 if (ecore_file_monitor_poll_init())
38 return 1;
39#endif
40 monitor_type = ECORE_FILE_MONITOR_TYPE_NONE;
41 return 0;
42}
43
44void
45ecore_file_monitor_shutdown(void)
46{
47 switch (monitor_type)
48 {
49 case ECORE_FILE_MONITOR_TYPE_NONE:
50 break;
51#ifdef HAVE_INOTIFY
52 case ECORE_FILE_MONITOR_TYPE_INOTIFY:
53 ecore_file_monitor_inotify_shutdown();
54 break;
55#endif
56#ifdef HAVE_NOTIFY_WIN32
57 case ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32:
58 ecore_file_monitor_win32_shutdown();
59 break;
60#endif
61#ifdef HAVE_POLL
62 case ECORE_FILE_MONITOR_TYPE_POLL:
63 ecore_file_monitor_poll_shutdown();
64 break;
65#endif
66 }
67}
68
69/**
70 * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions
71 *
72 * @{
73 */
74
75/**
76 * @brief Monitor the given path using inotify, Windows notification, or polling.
77 *
78 * @param path The path to monitor.
79 * @param func The function to call on changes.
80 * @param data The data passed to func.
81 * @return An Ecore_File_Monitor pointer or NULL on failure.
82 *
83 * This function monitors @p path. If @p path is @c NULL, or is an
84 * empty string, or none of the notify methods (Inotify, Windows
85 * notification or polling) is available, or if @p path is not a file,
86 * the function returns @c NULL. Otherwise, it returns a newly
87 * allocated Ecore_File_Monitor object and the monitoring begins. When
88 * one of the #Ecore_File_Event event is notified, @p func is called
89 * and @p data is passed to @p func. Call ecore_file_monitor_del() to
90 * stop the monitoring.
91 */
92EAPI Ecore_File_Monitor *
93ecore_file_monitor_add(const char *path,
94 Ecore_File_Monitor_Cb func,
95 void *data)
96{
97 if (!path || !*path)
98 return NULL;
99
100 switch (monitor_type)
101 {
102 case ECORE_FILE_MONITOR_TYPE_NONE:
103 return NULL;
104#ifdef HAVE_INOTIFY
105 case ECORE_FILE_MONITOR_TYPE_INOTIFY:
106 return ecore_file_monitor_inotify_add(path, func, data);
107#endif
108#ifdef HAVE_NOTIFY_WIN32
109 case ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32:
110 return ecore_file_monitor_win32_add(path, func, data);
111#endif
112#ifdef HAVE_POLL
113 case ECORE_FILE_MONITOR_TYPE_POLL:
114 return ecore_file_monitor_poll_add(path, func, data);
115#endif
116 }
117 return NULL;
118}
119
120/**
121 * @brief Stop the monitoring of the given path.
122 *
123 * @param em The Ecore_File_Monitor to stop.
124 *
125 * This function stops the the monitoring of the path that has been
126 * monitored by ecore_file_monitor_add(). @p em must be the value
127 * returned by ecore_file_monitor_add(). If @p em is @c NULL, or none
128 * of the notify methods (Inotify, Windows notification or polling) is
129 * availablethis function does nothing.
130 */
131EAPI void
132ecore_file_monitor_del(Ecore_File_Monitor *em)
133{
134 if (!em)
135 return;
136
137 switch (monitor_type)
138 {
139 case ECORE_FILE_MONITOR_TYPE_NONE:
140 break;
141#ifdef HAVE_INOTIFY
142 case ECORE_FILE_MONITOR_TYPE_INOTIFY:
143 ecore_file_monitor_inotify_del(em);
144 break;
145#endif
146#ifdef HAVE_NOTIFY_WIN32
147 case ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32:
148 ecore_file_monitor_win32_del(em);
149 break;
150#endif
151#ifdef HAVE_POLL
152 case ECORE_FILE_MONITOR_TYPE_POLL:
153 ecore_file_monitor_poll_del(em);
154 break;
155#endif
156 }
157}
158
159/**
160 * @brief Get the monitored path.
161 *
162 * @param em The Ecore_File_Monitor to query.
163 * @return The path that is monitored by @p em.
164 *
165 * This function returns the monitored path that has been
166 * monitored by ecore_file_monitor_add(). @p em must be the value
167 * returned by ecore_file_monitor_add(). If @p em is @c NULL, the
168 * function returns @c NULL.
169 */
170EAPI const char *
171ecore_file_monitor_path_get(Ecore_File_Monitor *em)
172{
173 if (!em)
174 return NULL;
175 return em->path;
176}
177
178/**
179 * @}
180 */
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c b/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c
new file mode 100644
index 0000000..c3533ad
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c
@@ -0,0 +1,369 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <string.h>
7#include <sys/types.h>
8#include <unistd.h>
9
10#include "ecore_file_private.h"
11
12/*
13 * TODO:
14 *
15 * - Listen to these events:
16 * IN_ACCESS, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_OPEN
17 * - Read all events first, then call the callbacks. This will prevent several
18 * callbacks with the typic save cycle (delete file, new file)
19 * - Listen to IN_IGNORED, emitted when the watch is removed
20 */
21
22#ifdef HAVE_INOTIFY
23
24#ifdef HAVE_SYS_INOTIFY
25# include <sys/inotify.h>
26#else
27# include <asm/unistd.h>
28# include <linux/inotify.h>
29#endif
30
31#ifndef HAVE_SYS_INOTIFY
32static inline int inotify_init(void);
33static inline int inotify_add_watch(int fd, const char *name, __u32 mask);
34static inline int inotify_rm_watch(int fd, __u32 wd);
35#endif
36
37
38typedef struct _Ecore_File_Monitor_Inotify Ecore_File_Monitor_Inotify;
39
40#define ECORE_FILE_MONITOR_INOTIFY(x) ((Ecore_File_Monitor_Inotify *)(x))
41
42struct _Ecore_File_Monitor_Inotify
43{
44 Ecore_File_Monitor monitor;
45 int wd;
46};
47
48static Ecore_Fd_Handler *_fdh = NULL;
49static Ecore_File_Monitor *_monitors = NULL;
50static pid_t _inotify_fd_pid = -1;
51
52static Eina_Bool _ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh);
53static Ecore_File_Monitor *_ecore_file_monitor_inotify_monitor_find(int wd);
54static void _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask);
55static int _ecore_file_monitor_inotify_monitor(Ecore_File_Monitor *em, const char *path);
56#if 0
57static void _ecore_file_monitor_inotify_print(char *file, int mask);
58#endif
59
60int
61ecore_file_monitor_inotify_init(void)
62{
63 int fd;
64
65 fd = inotify_init();
66 if (fd < 0)
67 return 0;
68
69 _fdh = ecore_main_fd_handler_add(fd, ECORE_FD_READ, _ecore_file_monitor_inotify_handler,
70 NULL, NULL, NULL);
71 if (!_fdh)
72 {
73 close(fd);
74 return 0;
75 }
76
77 _inotify_fd_pid = getpid();
78 return 1;
79}
80
81int
82ecore_file_monitor_inotify_shutdown(void)
83{
84 int fd;
85
86 while(_monitors)
87 ecore_file_monitor_inotify_del(_monitors);
88
89 if (_fdh)
90 {
91 fd = ecore_main_fd_handler_fd_get(_fdh);
92 ecore_main_fd_handler_del(_fdh);
93 close(fd);
94 }
95 _inotify_fd_pid = -1;
96 return 1;
97}
98
99Ecore_File_Monitor *
100ecore_file_monitor_inotify_add(const char *path,
101 void (*func) (void *data, Ecore_File_Monitor *em,
102 Ecore_File_Event event,
103 const char *path),
104 void *data)
105{
106 Ecore_File_Monitor *em;
107 int len;
108
109 if (_inotify_fd_pid == -1) return NULL;
110
111 if (_inotify_fd_pid != getpid())
112 {
113 ecore_file_monitor_inotify_shutdown();
114 ecore_file_monitor_inotify_init();
115 }
116
117 em = calloc(1, sizeof(Ecore_File_Monitor_Inotify));
118 if (!em) return NULL;
119
120 em->func = func;
121 em->data = data;
122
123 em->path = strdup(path);
124 len = strlen(em->path);
125 if (em->path[len - 1] == '/' && strcmp(em->path, "/"))
126 em->path[len - 1] = 0;
127
128 _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
129
130 if (ecore_file_exists(em->path))
131 {
132 if (!_ecore_file_monitor_inotify_monitor(em, em->path))
133 return NULL;
134 }
135 else
136 {
137 ecore_file_monitor_inotify_del(em);
138 return NULL;
139 }
140
141 return em;
142}
143
144void
145ecore_file_monitor_inotify_del(Ecore_File_Monitor *em)
146{
147 int fd;
148
149 if (_monitors)
150 _monitors = ECORE_FILE_MONITOR(eina_inlist_remove(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
151
152 fd = ecore_main_fd_handler_fd_get(_fdh);
153 if (ECORE_FILE_MONITOR_INOTIFY(em)->wd)
154 inotify_rm_watch(fd, ECORE_FILE_MONITOR_INOTIFY(em)->wd);
155 free(em->path);
156 free(em);
157}
158
159static Eina_Bool
160_ecore_file_monitor_inotify_handler(void *data __UNUSED__, Ecore_Fd_Handler *fdh)
161{
162 Ecore_File_Monitor *em;
163 char buffer[16384];
164 struct inotify_event *event;
165 int i = 0;
166 int event_size;
167 ssize_t size;
168
169 size = read(ecore_main_fd_handler_fd_get(fdh), buffer, sizeof(buffer));
170 while (i < size)
171 {
172 event = (struct inotify_event *)&buffer[i];
173 event_size = sizeof(struct inotify_event) + event->len;
174 i += event_size;
175
176 em = _ecore_file_monitor_inotify_monitor_find(event->wd);
177 if (!em) continue;
178
179 _ecore_file_monitor_inotify_events(em, (event->len ? event->name : NULL), event->mask);
180 }
181
182 return ECORE_CALLBACK_RENEW;
183}
184
185static Ecore_File_Monitor *
186_ecore_file_monitor_inotify_monitor_find(int wd)
187{
188 Ecore_File_Monitor *l;
189
190 EINA_INLIST_FOREACH(_monitors, l)
191 {
192 if (ECORE_FILE_MONITOR_INOTIFY(l)->wd == wd)
193 return l;
194 }
195 return NULL;
196}
197
198static void
199_ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask)
200{
201 char buf[PATH_MAX];
202 int isdir;
203
204 if ((file) && (file[0]))
205 snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
206 else
207 strcpy(buf, em->path);
208 isdir = mask & IN_ISDIR;
209
210#if 0
211 _ecore_file_monitor_inotify_print(buf, mask);
212#endif
213
214 if (mask & IN_ATTRIB)
215 {
216 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
217 }
218 if (mask & IN_CLOSE_WRITE)
219 {
220 if (!isdir)
221 em->func(em->data, em, ECORE_FILE_EVENT_CLOSED, buf);
222 }
223 if (mask & IN_MODIFY)
224 {
225 if (!isdir)
226 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
227 }
228 if (mask & IN_MOVED_FROM)
229 {
230 if (isdir)
231 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf);
232 else
233 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_FILE, buf);
234 }
235 if (mask & IN_MOVED_TO)
236 {
237 if (isdir)
238 em->func(em->data, em, ECORE_FILE_EVENT_CREATED_DIRECTORY, buf);
239 else
240 em->func(em->data, em, ECORE_FILE_EVENT_CREATED_FILE, buf);
241 }
242 if (mask & IN_DELETE)
243 {
244 if (isdir)
245 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf);
246 else
247 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_FILE, buf);
248 }
249 if (mask & IN_CREATE)
250 {
251 if (isdir)
252 em->func(em->data, em, ECORE_FILE_EVENT_CREATED_DIRECTORY, buf);
253 else
254 em->func(em->data, em, ECORE_FILE_EVENT_CREATED_FILE, buf);
255 }
256 if (mask & IN_DELETE_SELF)
257 {
258 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
259 }
260 if (mask & IN_MOVE_SELF)
261 {
262 /* We just call delete. The dir is gone... */
263 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
264 }
265 if (mask & IN_UNMOUNT)
266 {
267 /* We just call delete. The dir is gone... */
268 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
269 }
270 if (mask & IN_IGNORED)
271 {
272 /* The watch is removed. If the file name still exists monitor the new one,
273 * else delete it */
274 if (ecore_file_exists(em->path))
275 {
276 if (!_ecore_file_monitor_inotify_monitor(em, em->path))
277 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
278 }
279 else
280 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
281 }
282}
283
284static int
285_ecore_file_monitor_inotify_monitor(Ecore_File_Monitor *em, const char *path)
286{
287 int mask =
288 IN_ATTRIB |
289 IN_CLOSE_WRITE |
290 IN_MOVED_FROM |
291 IN_MOVED_TO |
292 IN_DELETE |
293 IN_CREATE |
294 IN_MODIFY |
295 IN_DELETE_SELF |
296 IN_MOVE_SELF |
297 IN_UNMOUNT;
298
299 ECORE_FILE_MONITOR_INOTIFY(em)->wd =
300 inotify_add_watch(ecore_main_fd_handler_fd_get(_fdh), path, mask);
301 if (ECORE_FILE_MONITOR_INOTIFY(em)->wd < 0)
302 {
303 ERR("inotify_add_watch error");
304 ecore_file_monitor_inotify_del(em);
305 return 0;
306 }
307 return 1;
308}
309
310#ifndef HAVE_SYS_INOTIFY
311static inline int
312inotify_init(void)
313{
314 return syscall(__NR_inotify_init);
315}
316
317static inline int
318inotify_add_watch(int fd, const char *name, __u32 mask)
319{
320 return syscall(__NR_inotify_add_watch, fd, name, mask);
321}
322
323static inline int
324inotify_rm_watch(int fd, __u32 wd)
325{
326 return syscall(__NR_inotify_rm_watch, fd, wd);
327}
328#endif
329
330#if 0
331static void
332_ecore_file_monitor_inotify_print(char *file, int mask)
333{
334 const char *type;
335
336 if (mask & IN_ISDIR)
337 type = "dir";
338 else
339 type = "file";
340
341 if (mask & IN_ACCESS)
342 INF("Inotify accessed %s: %s", type, file);
343 if (mask & IN_MODIFY)
344 INF("Inotify modified %s: %s", type, file);
345 if (mask & IN_ATTRIB)
346 INF("Inotify attributes %s: %s", type, file);
347 if (mask & IN_CLOSE_WRITE)
348 INF("Inotify close write %s: %s", type, file);
349 if (mask & IN_CLOSE_NOWRITE)
350 INF("Inotify close write %s: %s", type, file);
351 if (mask & IN_OPEN)
352 INF("Inotify open %s: %s", type, file);
353 if (mask & IN_MOVED_FROM)
354 INF("Inotify moved from %s: %s", type, file);
355 if (mask & IN_MOVED_TO)
356 INF("Inotify moved to %s: %s", type, file);
357 if (mask & IN_DELETE)
358 INF("Inotify delete %s: %s", type, file);
359 if (mask & IN_CREATE)
360 INF("Inotify create %s: %s", type, file);
361 if (mask & IN_DELETE_SELF)
362 INF("Inotify delete self %s: %s", type, file);
363 if (mask & IN_MOVE_SELF)
364 INF("Inotify move self %s: %s", type, file);
365 if (mask & IN_UNMOUNT)
366 INF("Inotify unmount %s: %s", type, file);
367}
368#endif
369#endif /* HAVE_INOTIFY */
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c b/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c
new file mode 100644
index 0000000..1f71b55
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c
@@ -0,0 +1,339 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <string.h>
7
8#include "ecore_file_private.h"
9
10#ifdef HAVE_POLL
11
12/*
13 * TODO:
14 * - Implement recursive as an option!
15 * - Keep whole path or just name of file? (Memory or CPU...)
16 * - Remove requests without files?
17 * - Change poll time
18 */
19
20typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll;
21
22#define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x))
23
24struct _Ecore_File_Monitor_Poll
25{
26 Ecore_File_Monitor monitor;
27 int mtime;
28 unsigned char deleted;
29};
30
31#define ECORE_FILE_INTERVAL_MIN 1.0
32#define ECORE_FILE_INTERVAL_STEP 0.5
33#define ECORE_FILE_INTERVAL_MAX 5.0
34
35static double _interval = ECORE_FILE_INTERVAL_MIN;
36static Ecore_Timer *_timer = NULL;
37static Ecore_File_Monitor *_monitors = NULL;
38static int _lock = 0;
39
40static Eina_Bool _ecore_file_monitor_poll_handler(void *data);
41static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em);
42static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name);
43
44int
45ecore_file_monitor_poll_init(void)
46{
47 return 1;
48}
49
50int
51ecore_file_monitor_poll_shutdown(void)
52{
53 while(_monitors)
54 ecore_file_monitor_poll_del(_monitors);
55
56 if (_timer)
57 {
58 ecore_timer_del(_timer);
59 _timer = NULL;
60 }
61 return 1;
62}
63
64Ecore_File_Monitor *
65ecore_file_monitor_poll_add(const char *path,
66 void (*func) (void *data, Ecore_File_Monitor *em,
67 Ecore_File_Event event,
68 const char *path),
69 void *data)
70{
71 Ecore_File_Monitor *em;
72 size_t len;
73
74 if (!path) return NULL;
75 if (!func) return NULL;
76
77 em = calloc(1, sizeof(Ecore_File_Monitor_Poll));
78 if (!em) return NULL;
79
80 if (!_timer)
81 _timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL);
82 else
83 ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
84
85 em->path = strdup(path);
86 len = strlen(em->path);
87 if (em->path[len - 1] == '/' && strcmp(em->path, "/"))
88 em->path[len - 1] = 0;
89
90 em->func = func;
91 em->data = data;
92
93 ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path);
94 _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
95
96 if (ecore_file_exists(em->path))
97 {
98 if (ecore_file_is_dir(em->path))
99 {
100 /* Check for subdirs */
101 Eina_List *files;
102 char *file;
103
104 files = ecore_file_ls(em->path);
105 EINA_LIST_FREE(files, file)
106 {
107 Ecore_File *f;
108 char buf[PATH_MAX];
109
110 f = calloc(1, sizeof(Ecore_File));
111 if (!f)
112 {
113 free(file);
114 continue;
115 }
116
117 snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
118 f->name = file;
119 f->mtime = ecore_file_mod_time(buf);
120 f->is_dir = ecore_file_is_dir(buf);
121 em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
122 }
123 }
124 }
125 else
126 {
127 ecore_file_monitor_poll_del(em);
128 return NULL;
129 }
130
131 return em;
132}
133
134void
135ecore_file_monitor_poll_del(Ecore_File_Monitor *em)
136{
137 Ecore_File *l;
138
139 if (_lock)
140 {
141 ECORE_FILE_MONITOR_POLL(em)->deleted = 1;
142 return;
143 }
144
145 /* Remove files */
146 /*It's possible there weren't any files to monitor, so check if the list is init*/
147 if (em->files)
148 {
149 for (l = em->files; l;)
150 {
151 Ecore_File *file = l;
152
153 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
154 free(file->name);
155 free(file);
156 }
157 }
158
159 if (_monitors)
160 _monitors = ECORE_FILE_MONITOR(eina_inlist_remove(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
161
162 free(em->path);
163 free(em);
164
165 if (_timer)
166 {
167 if (!_monitors)
168 {
169 ecore_timer_del(_timer);
170 _timer = NULL;
171 }
172 else
173 ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
174 }
175}
176
177static Eina_Bool
178_ecore_file_monitor_poll_handler(void *data __UNUSED__)
179{
180 Ecore_File_Monitor *l;
181
182 _interval += ECORE_FILE_INTERVAL_STEP;
183
184 _lock = 1;
185 EINA_INLIST_FOREACH(_monitors, l)
186 _ecore_file_monitor_poll_check(l);
187 _lock = 0;
188
189 if (_interval > ECORE_FILE_INTERVAL_MAX)
190 _interval = ECORE_FILE_INTERVAL_MAX;
191 ecore_timer_interval_set(_timer, _interval);
192
193 for (l = _monitors; l;)
194 {
195 Ecore_File_Monitor *em = l;
196
197 l = ECORE_FILE_MONITOR(EINA_INLIST_GET(l)->next);
198 if (ECORE_FILE_MONITOR_POLL(em)->deleted)
199 ecore_file_monitor_del(em);
200 }
201 return ECORE_CALLBACK_RENEW;
202}
203
204static void
205_ecore_file_monitor_poll_check(Ecore_File_Monitor *em)
206{
207 int mtime;
208
209 mtime = ecore_file_mod_time(em->path);
210 if (mtime < ECORE_FILE_MONITOR_POLL(em)->mtime)
211 {
212 Ecore_File *l;
213 Ecore_File_Event event;
214
215 /* Notify all files deleted */
216 for (l = em->files; l;)
217 {
218 Ecore_File *f = l;
219 char buf[PATH_MAX];
220
221 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
222
223 snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
224 if (f->is_dir)
225 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
226 else
227 event = ECORE_FILE_EVENT_DELETED_FILE;
228 em->func(em->data, em, event, buf);
229 free(f->name);
230 free(f);
231 }
232 em->files = NULL;
233 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
234 _interval = ECORE_FILE_INTERVAL_MIN;
235 }
236 else
237 {
238 Ecore_File *l;
239
240 /* Check for changed files */
241 for (l = em->files; l;)
242 {
243 Ecore_File *f = l;
244 char buf[PATH_MAX];
245 int mt;
246 Ecore_File_Event event;
247
248 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
249
250 snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
251 mt = ecore_file_mod_time(buf);
252 if (mt < f->mtime)
253 {
254 if (f->is_dir)
255 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
256 else
257 event = ECORE_FILE_EVENT_DELETED_FILE;
258
259 em->func(em->data, em, event, buf);
260 em->files = (Ecore_File *) eina_inlist_remove(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
261 free(f->name);
262 free(f);
263 _interval = ECORE_FILE_INTERVAL_MIN;
264 }
265 else if ((mt > f->mtime) && !(f->is_dir))
266 {
267 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
268 _interval = ECORE_FILE_INTERVAL_MIN;
269 f->mtime = mt;
270 }
271 else
272 f->mtime = mt;
273 }
274
275 /* Check for new files */
276 if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime)
277 {
278 Eina_List *files;
279 Eina_List *fl;
280 char *file;
281
282 /* Files have been added or removed */
283 files = ecore_file_ls(em->path);
284 if (files)
285 {
286 /* Are we a directory? We should check first, rather than rely on null here*/
287 EINA_LIST_FOREACH(files, fl, file)
288 {
289 Ecore_File *f;
290 char buf[PATH_MAX];
291 Ecore_File_Event event;
292
293 if (_ecore_file_monitor_poll_checking(em, file))
294 continue;
295
296 snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
297 f = calloc(1, sizeof(Ecore_File));
298 if (!f)
299 continue;
300
301 f->name = strdup(file);
302 f->mtime = ecore_file_mod_time(buf);
303 f->is_dir = ecore_file_is_dir(buf);
304 if (f->is_dir)
305 event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
306 else
307 event = ECORE_FILE_EVENT_CREATED_FILE;
308 em->func(em->data, em, event, buf);
309 em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
310 }
311 while (files)
312 {
313 file = eina_list_data_get(files);
314 free(file);
315 files = eina_list_remove_list(files, files);
316 }
317 }
318
319 if (!ecore_file_is_dir(em->path))
320 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, em->path);
321 _interval = ECORE_FILE_INTERVAL_MIN;
322 }
323 }
324 ECORE_FILE_MONITOR_POLL(em)->mtime = mtime;
325}
326
327static int
328_ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name)
329{
330 Ecore_File *l;
331
332 EINA_INLIST_FOREACH(em->files, l)
333 {
334 if (!strcmp(l->name, name))
335 return 1;
336 }
337 return 0;
338}
339#endif
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_win32.c b/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_win32.c
new file mode 100644
index 0000000..7f3af09
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_win32.c
@@ -0,0 +1,310 @@
1/*
2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3 */
4
5#ifdef HAVE_CONFIG_H
6# include <config.h>
7#endif
8
9#ifdef HAVE_NOTIFY_WIN32
10
11# define WIN32_LEAN_AND_MEAN
12# include <windows.h>
13# undef WIN32_LEAN_AND_MEAN
14# include <process.h>
15
16# include "ecore_file_private.h"
17
18
19typedef struct _Ecore_File_Monitor_Win32 Ecore_File_Monitor_Win32;
20typedef struct _Ecore_File_Monitor_Win32_Data Ecore_File_Monitor_Win32_Data;
21
22/* 4096 = 256 * sizeof(FILE_NOTIFY_INFORMATION) */
23# define ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE 4096
24# define ECORE_FILE_MONITOR_WIN32(x) ((Ecore_File_Monitor_Win32 *)(x))
25
26struct _Ecore_File_Monitor_Win32_Data
27{
28 char buffer[ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE];
29 OVERLAPPED overlapped;
30 HANDLE handle;
31 HANDLE event;
32 Ecore_File_Monitor *monitor;
33 Ecore_Win32_Handler *h;
34 DWORD buf_length;
35 int is_dir;
36};
37
38struct _Ecore_File_Monitor_Win32
39{
40 Ecore_File_Monitor monitor;
41 Ecore_File_Monitor_Win32_Data *file;
42 Ecore_File_Monitor_Win32_Data *dir;
43};
44
45static Ecore_File_Monitor *_monitors = NULL;
46
47static Eina_Bool _ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh);
48
49
50static Ecore_File_Monitor_Win32_Data *
51_ecore_file_monitor_win32_data_new(Ecore_File_Monitor *monitor, int type)
52{
53 Ecore_File_Monitor_Win32_Data *md;
54 DWORD filter;
55
56 md = (Ecore_File_Monitor_Win32_Data *)calloc(1, sizeof(Ecore_File_Monitor_Win32_Data));
57 if (!md) return NULL;
58
59 md->handle = CreateFile(monitor->path,
60 FILE_LIST_DIRECTORY,
61 FILE_SHARE_READ |
62 FILE_SHARE_WRITE,
63 NULL,
64 OPEN_EXISTING,
65 FILE_FLAG_BACKUP_SEMANTICS |
66 FILE_FLAG_OVERLAPPED,
67 NULL);
68 if (md->handle == INVALID_HANDLE_VALUE)
69 goto free_md;
70
71 md->event = CreateEvent(NULL, FALSE, FALSE, NULL);
72 if (!md->event)
73 goto close_handle;
74
75 ZeroMemory (&md->overlapped, sizeof(md->overlapped));
76 md->overlapped.hEvent = md->event;
77
78 filter = (type == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME;
79 filter |=
80 FILE_NOTIFY_CHANGE_ATTRIBUTES |
81 FILE_NOTIFY_CHANGE_SIZE |
82 FILE_NOTIFY_CHANGE_LAST_WRITE |
83 FILE_NOTIFY_CHANGE_LAST_ACCESS |
84 FILE_NOTIFY_CHANGE_CREATION |
85 FILE_NOTIFY_CHANGE_SECURITY;
86
87 if (!ReadDirectoryChangesW(md->handle,
88 md->buffer,
89 ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE,
90 FALSE,
91 filter,
92 &md->buf_length,
93 &md->overlapped,
94 NULL))
95 goto close_event;
96
97 md->h = ecore_main_win32_handler_add(md->event,
98 _ecore_file_monitor_win32_cb,
99 md);
100 if (!md->h)
101 goto close_event;
102
103 md->monitor = monitor;
104 md->is_dir = type;
105
106 return md;
107
108 close_event:
109 CloseHandle(md->event);
110 close_handle:
111 CloseHandle(md->handle);
112 free_md:
113 free(md);
114
115 return NULL;
116}
117
118static void
119_ecore_file_monitor_win32_data_free(Ecore_File_Monitor_Win32_Data *md)
120{
121 if (!md) return;
122
123 CloseHandle(md->event);
124 CloseHandle (md->handle);
125 free (md);
126}
127
128static Eina_Bool
129_ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh)
130{
131 char filename[PATH_MAX];
132 PFILE_NOTIFY_INFORMATION fni;
133 Ecore_File_Monitor_Win32_Data *md;
134 wchar_t *wname;
135 char *name;
136 DWORD filter;
137 DWORD offset;
138 DWORD buf_length;
139 Ecore_File_Event event = ECORE_FILE_EVENT_NONE;
140
141 md = (Ecore_File_Monitor_Win32_Data *)data;
142
143 if (!GetOverlappedResult (md->handle, &md->overlapped, &buf_length, TRUE))
144 return 1;
145
146 fni = (PFILE_NOTIFY_INFORMATION)md->buffer;
147 do {
148 if (!fni)
149 break;
150 offset = fni->NextEntryOffset;
151
152 wname = (wchar_t *)malloc(sizeof(wchar_t) * (fni->FileNameLength + 1));
153 if (!wname)
154 return 0;
155
156 memcpy(wname, fni->FileName, fni->FileNameLength);
157 wname[fni->FileNameLength]='\0';
158 name = evil_wchar_to_char(wname);
159 free(wname);
160 if (!name)
161 return 0;
162
163 _snprintf(filename, PATH_MAX, "%s\\%s", md->monitor->path, name);
164 free(name);
165
166 switch (fni->Action)
167 {
168 case FILE_ACTION_ADDED:
169 if (md->is_dir)
170 event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
171 else
172 event = ECORE_FILE_EVENT_CREATED_FILE;
173 break;
174 case FILE_ACTION_REMOVED:
175 if (md->is_dir)
176 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
177 else
178 event = ECORE_FILE_EVENT_DELETED_FILE;
179 break;
180 case FILE_ACTION_MODIFIED:
181 if (!md->is_dir)
182 event = ECORE_FILE_EVENT_MODIFIED;
183 break;
184 case FILE_ACTION_RENAMED_OLD_NAME:
185 if (md->is_dir)
186 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
187 else
188 event = ECORE_FILE_EVENT_DELETED_FILE;
189 break;
190 case FILE_ACTION_RENAMED_NEW_NAME:
191 if (md->is_dir)
192 event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
193 else
194 event = ECORE_FILE_EVENT_CREATED_FILE;
195 break;
196 default:
197 fprintf(stderr, "unknown event\n");
198 event = ECORE_FILE_EVENT_NONE;
199 break;
200 }
201 if (event != ECORE_FILE_EVENT_NONE)
202 md->monitor->func(md->monitor->data, md->monitor, event, filename);
203
204 fni = (PFILE_NOTIFY_INFORMATION)((LPBYTE)fni + offset);
205 } while (offset);
206
207 filter = (md->is_dir == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME;
208 filter |=
209 FILE_NOTIFY_CHANGE_ATTRIBUTES |
210 FILE_NOTIFY_CHANGE_SIZE |
211 FILE_NOTIFY_CHANGE_LAST_WRITE |
212 FILE_NOTIFY_CHANGE_LAST_ACCESS |
213 FILE_NOTIFY_CHANGE_CREATION |
214 FILE_NOTIFY_CHANGE_SECURITY;
215
216 ReadDirectoryChangesW(md->handle,
217 md->buffer,
218 ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE,
219 FALSE,
220 filter,
221 &md->buf_length,
222 &md->overlapped,
223 NULL);
224 return 1;
225}
226
227int
228ecore_file_monitor_win32_init(void)
229{
230 return 1;
231}
232
233int
234ecore_file_monitor_win32_shutdown(void)
235{
236 return 1;
237}
238
239Ecore_File_Monitor *
240ecore_file_monitor_win32_add(const char *path,
241 void (*func) (void *data, Ecore_File_Monitor *em,
242 Ecore_File_Event event,
243 const char *path),
244 void *data)
245{
246 Ecore_File_Monitor_Win32 *m;
247 Ecore_File_Monitor *em;
248 size_t len;
249
250 if (!path || (*path == '\0')) return NULL;
251 if (!ecore_file_exists(path) || !ecore_file_is_dir(path))
252 return NULL;
253 if (!func) return NULL;
254
255 em = (Ecore_File_Monitor *)calloc(1, sizeof(Ecore_File_Monitor_Win32));
256 if (!em) return NULL;
257
258 em->func = func;
259 em->data = data;
260
261 em->path = strdup(path);
262 if (!em->path)
263 {
264 free(em);
265 return NULL;
266 }
267 len = strlen(em->path);
268 if (em->path[len - 1] == '/' || em->path[len - 1] == '\\')
269 em->path[len - 1] = '\0';
270
271 m = ECORE_FILE_MONITOR_WIN32(em);
272
273 m->file = _ecore_file_monitor_win32_data_new(em, 0);
274 if (!m->file)
275 {
276 free(em->path);
277 free(em);
278 return NULL;
279 }
280
281 m->dir = _ecore_file_monitor_win32_data_new(em, 1);
282 if (!m->dir)
283 {
284 _ecore_file_monitor_win32_data_free(m->file);
285 free(em->path);
286 free(em);
287 return NULL;
288 }
289
290 _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
291
292 return em;
293}
294
295void
296ecore_file_monitor_win32_del(Ecore_File_Monitor *em)
297{
298 Ecore_File_Monitor_Win32 *m;
299
300 if (!em)
301 return;
302
303 m = ECORE_FILE_MONITOR_WIN32(em);
304 _ecore_file_monitor_win32_data_free(m->dir);
305 _ecore_file_monitor_win32_data_free(m->file);
306 free(em->path);
307 free(em);
308}
309
310#endif
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file_path.c b/libraries/ecore/src/lib/ecore_file/ecore_file_path.c
new file mode 100644
index 0000000..ade3bc6
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/ecore_file_path.c
@@ -0,0 +1,184 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#undef alloca
6#ifdef HAVE_ALLOCA_H
7# include <alloca.h>
8#elif defined __GNUC__
9# define alloca __builtin_alloca
10#elif defined _AIX
11# define alloca __alloca
12#elif defined _MSC_VER
13# include <malloc.h>
14# define alloca _alloca
15#else
16# include <stddef.h>
17# ifdef __cplusplus
18extern "C"
19# endif
20void *alloca (size_t);
21#endif
22
23#include <stdio.h>
24#include <string.h>
25
26#include "ecore_file_private.h"
27
28static Eina_List *__ecore_file_path_bin = NULL;
29
30static Eina_List *_ecore_file_path_from_env(const char *env);
31
32void
33ecore_file_path_init(void)
34{
35 __ecore_file_path_bin = _ecore_file_path_from_env("PATH");
36}
37
38void
39ecore_file_path_shutdown(void)
40{
41 char *dir;
42
43 EINA_LIST_FREE(__ecore_file_path_bin, dir)
44 eina_stringshare_del(dir);
45}
46
47Eina_List *
48_ecore_file_path_from_env(const char *env)
49{
50 Eina_List *path = NULL;
51 char *env_tmp, *env_path, *p, *last;
52
53 env_tmp = getenv(env);
54 if (!env_tmp)
55 return path;
56
57 env_path = alloca(sizeof(char) * strlen(env_tmp) + 1);
58 memset(env_path, 0, strlen(env_tmp));
59 strcpy(env_path, env_tmp);
60 last = env_path;
61 for (p = env_path; *p; p++)
62 {
63 if (*p == ':')
64 *p = '\0';
65
66 if (!*p)
67 {
68 if (!ecore_file_path_dir_exists(last))
69 path = eina_list_append(path, eina_stringshare_add(last));
70 last = p + 1;
71 }
72 }
73 if (p > last)
74 path = eina_list_append(path, eina_stringshare_add(last));
75
76 return path;
77}
78
79/**
80 * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions
81 *
82 * @{
83 */
84
85/**
86 * @brief Check if the given directory is in PATH.
87 *
88 * @param The name of the directory to search in PATH.
89 * @return EINA_TRUE if the directory exist in PATH, EINA_FALSE otherwise.
90 *
91 * This function checks if @p in_dir is in the environment variable
92 * PATH. If @p in_dir is @c NULL, or if PATH is empty, or @p in_dir is
93 * not in PATH, the function returns EINA_FALSE, otherwise it returns
94 * EINA_TRUE.
95 */
96EAPI Eina_Bool
97ecore_file_path_dir_exists(const char *in_dir)
98{
99 Eina_List *l;
100 char *dir;
101
102 if (!in_dir)
103 return EINA_FALSE;
104
105 if (!__ecore_file_path_bin) return EINA_FALSE;
106 EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir)
107 {
108 if (strcmp(dir, in_dir))
109 return EINA_TRUE;
110 }
111
112 return EINA_FALSE;
113}
114
115/**
116 * @brief Check if the given application is installed.
117 *
118 * @param exe The name of the application
119 * @return EINA_TRUE if the exe is in PATH and is executable,
120 * EINA_FALSE otherwise.
121 *
122 *
123 * This function checks if @p exe exists in PATH and is executable. If
124 * @p exe is @c NULL or is not executable, the function returns
125 * EINA_FALSE, otherwise it returns EINA_TRUE.
126 */
127EAPI Eina_Bool
128ecore_file_app_installed(const char *exe)
129{
130 Eina_List *l;
131 char *dir;
132 char buf[PATH_MAX];
133
134 if (!exe) return EINA_FALSE;
135 if (ecore_file_can_exec(exe)) return EINA_TRUE;
136
137 EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir)
138 {
139 snprintf(buf, sizeof(buf), "%s/%s", dir, exe);
140 if (ecore_file_can_exec(buf))
141 return EINA_TRUE;
142 }
143
144 return EINA_FALSE;
145}
146
147/**
148 * @brief Get a list of all the applications installed on the system.
149 *
150 * @return An Eina_List containing all the executable files in the
151 * system.
152 *
153 * This function returns a list of allocated strings of all the
154 * executable files. If no files are found, the function returns
155 * @c NULL. When not needed anymore, the element of the list must be
156 * freed.
157 */
158EAPI Eina_List *
159ecore_file_app_list(void)
160{
161 Eina_List *list = NULL;
162 Eina_List *files;
163 Eina_List *l;
164 char buf[PATH_MAX], *dir, *exe;
165
166 EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir)
167 {
168 files = ecore_file_ls(dir);
169 EINA_LIST_FREE(files, exe)
170 {
171 snprintf(buf, sizeof(buf), "%s/%s", dir, exe);
172 if ((ecore_file_can_exec(buf)) &&
173 (!ecore_file_is_dir(buf)))
174 list = eina_list_append(list, strdup(buf));
175 free(exe);
176 }
177 }
178
179 return list;
180}
181
182/**
183 * @}
184 */
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file_private.h b/libraries/ecore/src/lib/ecore_file/ecore_file_private.h
new file mode 100644
index 0000000..45d2cbd
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_file/ecore_file_private.h
@@ -0,0 +1,129 @@
1#ifndef ECORE_FILE_PRIVATE_H_
2#define ECORE_FILE_PRIVATE_H_
3
4#ifdef __linux__
5# include <features.h>
6#endif
7
8#ifdef HAVE_EVIL
9# include <Evil.h>
10#endif
11
12#ifdef HAVE_ESCAPE
13# include <Escape.h>
14#endif
15
16#include <sys/types.h>
17#include <sys/stat.h>
18
19#include "Ecore.h"
20#include "ecore_private.h"
21
22#include "Ecore_File.h"
23
24extern int _ecore_file_log_dom;
25
26#ifdef ECORE_FILE_DEFAULT_LOG_COLOR
27#undef ECORE_FILE_DEFAULT_LOG_COLOR
28#endif
29#define ECORE_FILE_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
30
31#ifdef ERR
32# undef ERR
33#endif
34#define ERR(...) EINA_LOG_DOM_ERR(_ecore_file_log_dom, __VA_ARGS__)
35
36#ifdef DBG
37# undef DBG
38#endif
39#define DBG(...) EINA_LOG_DOM_DBG(_ecore_file_log_dom, __VA_ARGS__)
40
41#ifdef INF
42# undef INF
43#endif
44#define INF(...) EINA_LOG_DOM_INFO(_ecore_file_log_dom, __VA_ARGS__)
45
46#ifdef WRN
47# undef WRN
48#endif
49#define WRN(...) EINA_LOG_DOM_WARN(_ecore_file_log_dom, __VA_ARGS__)
50
51#ifdef CRIT
52# undef CRIT
53#endif
54#define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_file_log_dom, __VA_ARGS__)
55
56/* ecore_file_monitor */
57int ecore_file_monitor_init(void);
58void ecore_file_monitor_shutdown(void);
59
60#define ECORE_FILE_MONITOR(x) ((Ecore_File_Monitor *)(x))
61
62typedef struct _Ecore_File Ecore_File;
63struct _Ecore_File
64{
65 EINA_INLIST;
66 char *name;
67 int mtime;
68 unsigned char is_dir;
69};
70
71struct _Ecore_File_Monitor
72{
73 EINA_INLIST;
74 void (*func) (void *data,
75 Ecore_File_Monitor *ecore_file_monitor,
76 Ecore_File_Event event,
77 const char *path);
78
79 char *path;
80 void *data;
81 Ecore_File *files;
82};
83
84#ifdef HAVE_INOTIFY
85int ecore_file_monitor_inotify_init(void);
86int ecore_file_monitor_inotify_shutdown(void);
87Ecore_File_Monitor *ecore_file_monitor_inotify_add(const char *path,
88 void (*func) (void *data,
89 Ecore_File_Monitor *ecore_file_monitor,
90 Ecore_File_Event event,
91 const char *path),
92 void *data);
93void ecore_file_monitor_inotify_del(Ecore_File_Monitor *ecore_file_monitor);
94#endif
95
96#ifdef HAVE_NOTIFY_WIN32
97int ecore_file_monitor_win32_init(void);
98int ecore_file_monitor_win32_shutdown(void);
99Ecore_File_Monitor *ecore_file_monitor_win32_add(const char *path,
100 void (*func) (void *data,
101 Ecore_File_Monitor *ecore_file_monitor,
102 Ecore_File_Event event,
103 const char *path),
104 void *data);
105void ecore_file_monitor_win32_del(Ecore_File_Monitor *ecore_file_monitor);
106#endif
107
108#ifdef HAVE_POLL
109int ecore_file_monitor_poll_init(void);
110int ecore_file_monitor_poll_shutdown(void);
111Ecore_File_Monitor *ecore_file_monitor_poll_add(const char *path,
112 void (*func) (void *data,
113 Ecore_File_Monitor *ecore_file_monitor,
114 Ecore_File_Event event,
115 const char *path),
116 void *data);
117void ecore_file_monitor_poll_del(Ecore_File_Monitor *ecore_file_monitor);
118
119#endif
120
121/* ecore_file_path */
122void ecore_file_path_init(void);
123void ecore_file_path_shutdown(void);
124
125/* ecore_file_download */
126int ecore_file_download_init(void);
127void ecore_file_download_shutdown(void);
128
129#endif