diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/ecore/src/lib/ecore_file | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-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.h | 190 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/Makefile.am | 41 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/Makefile.in | 837 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/ecore_file.c | 1110 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/ecore_file_download.c | 440 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/ecore_file_monitor.c | 180 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c | 369 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c | 339 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/ecore_file_monitor_win32.c | 310 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/ecore_file_path.c | 184 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_file/ecore_file_private.h | 129 |
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 | ||
43 | extern "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 | */ | ||
56 | typedef struct _Ecore_File_Monitor Ecore_File_Monitor; | ||
57 | |||
58 | /** | ||
59 | * @typedef Ecore_File_Download_Job | ||
60 | * Abstract type used when aborting a download. | ||
61 | */ | ||
62 | typedef 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 | */ | ||
68 | typedef 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 | */ | ||
84 | typedef 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 | */ | ||
90 | typedef 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 | */ | ||
97 | typedef 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 | */ | ||
107 | typedef 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 | |||
116 | EAPI int ecore_file_init (void); | ||
117 | EAPI int ecore_file_shutdown (void); | ||
118 | EAPI long long ecore_file_mod_time (const char *file); | ||
119 | EAPI long long ecore_file_size (const char *file); | ||
120 | EAPI Eina_Bool ecore_file_exists (const char *file); | ||
121 | EAPI Eina_Bool ecore_file_is_dir (const char *file); | ||
122 | EAPI Eina_Bool ecore_file_mkdir (const char *dir); | ||
123 | EAPI int ecore_file_mkdirs (const char **dirs); | ||
124 | EAPI int ecore_file_mksubdirs (const char *base, const char **subdirs); | ||
125 | EAPI Eina_Bool ecore_file_rmdir (const char *dir); | ||
126 | EAPI Eina_Bool ecore_file_recursive_rm (const char *dir); | ||
127 | EAPI Eina_Bool ecore_file_mkpath (const char *path); | ||
128 | EAPI int ecore_file_mkpaths (const char **paths); | ||
129 | EAPI Eina_Bool ecore_file_cp (const char *src, const char *dst); | ||
130 | EAPI Eina_Bool ecore_file_mv (const char *src, const char *dst); | ||
131 | EAPI Eina_Bool ecore_file_symlink (const char *src, const char *dest); | ||
132 | EAPI char *ecore_file_realpath (const char *file); | ||
133 | EAPI Eina_Bool ecore_file_unlink (const char *file); | ||
134 | EAPI Eina_Bool ecore_file_remove (const char *file); | ||
135 | EAPI const char *ecore_file_file_get (const char *path); | ||
136 | EAPI char *ecore_file_dir_get (const char *path); | ||
137 | EAPI Eina_Bool ecore_file_can_read (const char *file); | ||
138 | EAPI Eina_Bool ecore_file_can_write (const char *file); | ||
139 | EAPI Eina_Bool ecore_file_can_exec (const char *file); | ||
140 | EAPI char *ecore_file_readlink (const char *link); | ||
141 | EAPI Eina_List *ecore_file_ls (const char *dir); | ||
142 | EAPI Eina_Iterator *ecore_file_ls_iterator (const char *dir); | ||
143 | EAPI char *ecore_file_app_exe_get (const char *app); | ||
144 | EAPI char *ecore_file_escape_name (const char *filename); | ||
145 | EAPI char *ecore_file_strip_ext (const char *file); | ||
146 | EAPI int ecore_file_dir_is_empty (const char *dir); | ||
147 | |||
148 | /* Monitoring */ | ||
149 | |||
150 | EAPI Ecore_File_Monitor *ecore_file_monitor_add(const char *path, | ||
151 | Ecore_File_Monitor_Cb func, | ||
152 | void *data); | ||
153 | EAPI void ecore_file_monitor_del(Ecore_File_Monitor *ecore_file_monitor); | ||
154 | EAPI const char *ecore_file_monitor_path_get(Ecore_File_Monitor *ecore_file_monitor); | ||
155 | |||
156 | /* Path */ | ||
157 | |||
158 | EAPI Eina_Bool ecore_file_path_dir_exists(const char *in_dir); | ||
159 | EAPI Eina_Bool ecore_file_app_installed(const char *exe); | ||
160 | EAPI Eina_List *ecore_file_app_list(void); | ||
161 | |||
162 | /* Download */ | ||
163 | |||
164 | EAPI 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); | ||
170 | EAPI 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 | |||
178 | EAPI void ecore_file_download_abort_all(void); | ||
179 | EAPI void ecore_file_download_abort(Ecore_File_Download_Job *job); | ||
180 | EAPI 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 @@ | |||
1 | MAINTAINERCLEANFILES = Makefile.in | ||
2 | |||
3 | AM_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 | |||
13 | AM_CFLAGS = @WIN32_CFLAGS@ | ||
14 | |||
15 | if BUILD_ECORE_CON | ||
16 | lib_ecore_con_la = $(top_builddir)/src/lib/ecore_con/libecore_con.la | ||
17 | endif | ||
18 | |||
19 | lib_LTLIBRARIES = libecore_file.la | ||
20 | includes_HEADERS = Ecore_File.h | ||
21 | includesdir = $(includedir)/ecore-@VMAJ@ | ||
22 | |||
23 | libecore_file_la_SOURCES = \ | ||
24 | ecore_file.c \ | ||
25 | ecore_file_monitor.c \ | ||
26 | ecore_file_monitor_inotify.c \ | ||
27 | ecore_file_monitor_win32.c \ | ||
28 | ecore_file_monitor_poll.c \ | ||
29 | ecore_file_path.c \ | ||
30 | ecore_file_download.c | ||
31 | |||
32 | libecore_file_la_LIBADD = \ | ||
33 | $(top_builddir)/src/lib/ecore/libecore.la \ | ||
34 | $(lib_ecore_con_la) \ | ||
35 | @EVIL_LIBS@ \ | ||
36 | @EINA_LIBS@ | ||
37 | |||
38 | libecore_file_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ | ||
39 | |||
40 | EXTRA_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 | |||
19 | VPATH = @srcdir@ | ||
20 | pkgdatadir = $(datadir)/@PACKAGE@ | ||
21 | pkgincludedir = $(includedir)/@PACKAGE@ | ||
22 | pkglibdir = $(libdir)/@PACKAGE@ | ||
23 | pkglibexecdir = $(libexecdir)/@PACKAGE@ | ||
24 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd | ||
25 | install_sh_DATA = $(install_sh) -c -m 644 | ||
26 | install_sh_PROGRAM = $(install_sh) -c | ||
27 | install_sh_SCRIPT = $(install_sh) -c | ||
28 | INSTALL_HEADER = $(INSTALL_DATA) | ||
29 | transform = $(program_transform_name) | ||
30 | NORMAL_INSTALL = : | ||
31 | PRE_INSTALL = : | ||
32 | POST_INSTALL = : | ||
33 | NORMAL_UNINSTALL = : | ||
34 | PRE_UNINSTALL = : | ||
35 | POST_UNINSTALL = : | ||
36 | build_triplet = @build@ | ||
37 | host_triplet = @host@ | ||
38 | subdir = src/lib/ecore_file | ||
39 | DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \ | ||
40 | $(srcdir)/Makefile.in | ||
41 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ||
42 | am__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 | ||
60 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ | ||
61 | $(ACLOCAL_M4) | ||
62 | mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs | ||
63 | CONFIG_HEADER = $(top_builddir)/config.h | ||
64 | CONFIG_CLEAN_FILES = | ||
65 | CONFIG_CLEAN_VPATH_FILES = | ||
66 | am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; | ||
67 | am__vpath_adj = case $$p in \ | ||
68 | $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ | ||
69 | *) f=$$p;; \ | ||
70 | esac; | ||
71 | am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; | ||
72 | am__install_max = 40 | ||
73 | am__nobase_strip_setup = \ | ||
74 | srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` | ||
75 | am__nobase_strip = \ | ||
76 | for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" | ||
77 | am__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] }' | ||
84 | am__base_list = \ | ||
85 | sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ | ||
86 | sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | ||
87 | am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)" | ||
88 | LTLIBRARIES = $(lib_LTLIBRARIES) | ||
89 | libecore_file_la_DEPENDENCIES = \ | ||
90 | $(top_builddir)/src/lib/ecore/libecore.la $(lib_ecore_con_la) | ||
91 | am_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 | ||
95 | libecore_file_la_OBJECTS = $(am_libecore_file_la_OBJECTS) | ||
96 | AM_V_lt = $(am__v_lt_$(V)) | ||
97 | am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) | ||
98 | am__v_lt_0 = --silent | ||
99 | libecore_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 $@ | ||
103 | DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) | ||
104 | depcomp = $(SHELL) $(top_srcdir)/depcomp | ||
105 | am__depfiles_maybe = depfiles | ||
106 | am__mv = mv -f | ||
107 | COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ | ||
108 | $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||
109 | LTCOMPILE = $(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) | ||
113 | AM_V_CC = $(am__v_CC_$(V)) | ||
114 | am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) | ||
115 | am__v_CC_0 = @echo " CC " $@; | ||
116 | AM_V_at = $(am__v_at_$(V)) | ||
117 | am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) | ||
118 | am__v_at_0 = @ | ||
119 | CCLD = $(CC) | ||
120 | LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
121 | $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ | ||
122 | $(AM_LDFLAGS) $(LDFLAGS) -o $@ | ||
123 | AM_V_CCLD = $(am__v_CCLD_$(V)) | ||
124 | am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) | ||
125 | am__v_CCLD_0 = @echo " CCLD " $@; | ||
126 | AM_V_GEN = $(am__v_GEN_$(V)) | ||
127 | am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) | ||
128 | am__v_GEN_0 = @echo " GEN " $@; | ||
129 | SOURCES = $(libecore_file_la_SOURCES) | ||
130 | DIST_SOURCES = $(libecore_file_la_SOURCES) | ||
131 | HEADERS = $(includes_HEADERS) | ||
132 | ETAGS = etags | ||
133 | CTAGS = ctags | ||
134 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) | ||
135 | ACLOCAL = @ACLOCAL@ | ||
136 | ALLOCA = @ALLOCA@ | ||
137 | AMTAR = @AMTAR@ | ||
138 | AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ | ||
139 | AR = @AR@ | ||
140 | AS = @AS@ | ||
141 | AUTOCONF = @AUTOCONF@ | ||
142 | AUTOHEADER = @AUTOHEADER@ | ||
143 | AUTOMAKE = @AUTOMAKE@ | ||
144 | AWK = @AWK@ | ||
145 | CARES_CFLAGS = @CARES_CFLAGS@ | ||
146 | CARES_LIBS = @CARES_LIBS@ | ||
147 | CC = @CC@ | ||
148 | CCDEPMODE = @CCDEPMODE@ | ||
149 | CFLAGS = @CFLAGS@ | ||
150 | CHECK_CFLAGS = @CHECK_CFLAGS@ | ||
151 | CHECK_LIBS = @CHECK_LIBS@ | ||
152 | CPP = @CPP@ | ||
153 | CPPFLAGS = @CPPFLAGS@ | ||
154 | CURL_CFLAGS = @CURL_CFLAGS@ | ||
155 | CURL_LIBS = @CURL_LIBS@ | ||
156 | CXX = @CXX@ | ||
157 | CXXCPP = @CXXCPP@ | ||
158 | CXXDEPMODE = @CXXDEPMODE@ | ||
159 | CXXFLAGS = @CXXFLAGS@ | ||
160 | CYGPATH_W = @CYGPATH_W@ | ||
161 | DEFS = @DEFS@ | ||
162 | DEPDIR = @DEPDIR@ | ||
163 | DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@ | ||
164 | DIRECTFB_LIBS = @DIRECTFB_LIBS@ | ||
165 | DLLTOOL = @DLLTOOL@ | ||
166 | DSYMUTIL = @DSYMUTIL@ | ||
167 | DUMPBIN = @DUMPBIN@ | ||
168 | ECHO_C = @ECHO_C@ | ||
169 | ECHO_N = @ECHO_N@ | ||
170 | ECHO_T = @ECHO_T@ | ||
171 | ECORE_XCB_CFLAGS = @ECORE_XCB_CFLAGS@ | ||
172 | ECORE_XCB_LIBS = @ECORE_XCB_LIBS@ | ||
173 | EFL_ECORE_BUILD = @EFL_ECORE_BUILD@ | ||
174 | EFL_ECORE_CON_BUILD = @EFL_ECORE_CON_BUILD@ | ||
175 | EFL_ECORE_EVAS_BUILD = @EFL_ECORE_EVAS_BUILD@ | ||
176 | EFL_ECORE_FILE_BUILD = @EFL_ECORE_FILE_BUILD@ | ||
177 | EFL_ECORE_IMF_BUILD = @EFL_ECORE_IMF_BUILD@ | ||
178 | EFL_ECORE_IMF_EVAS_BUILD = @EFL_ECORE_IMF_EVAS_BUILD@ | ||
179 | EFL_ECORE_INPUT_BUILD = @EFL_ECORE_INPUT_BUILD@ | ||
180 | EFL_ECORE_INPUT_EVAS_BUILD = @EFL_ECORE_INPUT_EVAS_BUILD@ | ||
181 | EFL_ECORE_IPC_BUILD = @EFL_ECORE_IPC_BUILD@ | ||
182 | EFL_ECORE_PSL1GHT_BUILD = @EFL_ECORE_PSL1GHT_BUILD@ | ||
183 | EFL_ECORE_SDL_BUILD = @EFL_ECORE_SDL_BUILD@ | ||
184 | EFL_ECORE_WIN32_BUILD = @EFL_ECORE_WIN32_BUILD@ | ||
185 | EFL_ECORE_WINCE_BUILD = @EFL_ECORE_WINCE_BUILD@ | ||
186 | EFL_PTHREAD_CFLAGS = @EFL_PTHREAD_CFLAGS@ | ||
187 | EFL_PTHREAD_LIBS = @EFL_PTHREAD_LIBS@ | ||
188 | EGREP = @EGREP@ | ||
189 | EINA_CFLAGS = @EINA_CFLAGS@ | ||
190 | EINA_LIBS = @EINA_LIBS@ | ||
191 | ESCAPE_CFLAGS = @ESCAPE_CFLAGS@ | ||
192 | ESCAPE_LIBS = @ESCAPE_LIBS@ | ||
193 | EVAS_CFLAGS = @EVAS_CFLAGS@ | ||
194 | EVAS_LIBS = @EVAS_LIBS@ | ||
195 | EVIL_CFLAGS = @EVIL_CFLAGS@ | ||
196 | EVIL_LIBS = @EVIL_LIBS@ | ||
197 | EXEEXT = @EXEEXT@ | ||
198 | FGREP = @FGREP@ | ||
199 | GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ | ||
200 | GLIB_CFLAGS = @GLIB_CFLAGS@ | ||
201 | GLIB_LIBS = @GLIB_LIBS@ | ||
202 | GMSGFMT = @GMSGFMT@ | ||
203 | GMSGFMT_015 = @GMSGFMT_015@ | ||
204 | GREP = @GREP@ | ||
205 | INSTALL = @INSTALL@ | ||
206 | INSTALL_DATA = @INSTALL_DATA@ | ||
207 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ | ||
208 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ | ||
209 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ | ||
210 | INTLLIBS = @INTLLIBS@ | ||
211 | INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ | ||
212 | KEYSYMDEFS = @KEYSYMDEFS@ | ||
213 | LD = @LD@ | ||
214 | LDFLAGS = @LDFLAGS@ | ||
215 | LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ | ||
216 | LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ | ||
217 | LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ | ||
218 | LIBICONV = @LIBICONV@ | ||
219 | LIBINTL = @LIBINTL@ | ||
220 | LIBOBJS = @LIBOBJS@ | ||
221 | LIBS = @LIBS@ | ||
222 | LIBTOOL = @LIBTOOL@ | ||
223 | LIPO = @LIPO@ | ||
224 | LN_S = @LN_S@ | ||
225 | LTLIBICONV = @LTLIBICONV@ | ||
226 | LTLIBINTL = @LTLIBINTL@ | ||
227 | LTLIBOBJS = @LTLIBOBJS@ | ||
228 | MAKEINFO = @MAKEINFO@ | ||
229 | MKDIR_P = @MKDIR_P@ | ||
230 | MSGFMT = @MSGFMT@ | ||
231 | MSGFMT_015 = @MSGFMT_015@ | ||
232 | MSGMERGE = @MSGMERGE@ | ||
233 | NM = @NM@ | ||
234 | NMEDIT = @NMEDIT@ | ||
235 | OBJC = @OBJC@ | ||
236 | OBJCDEPMODE = @OBJCDEPMODE@ | ||
237 | OBJCFLAGS = @OBJCFLAGS@ | ||
238 | OBJDUMP = @OBJDUMP@ | ||
239 | OBJEXT = @OBJEXT@ | ||
240 | OTOOL = @OTOOL@ | ||
241 | OTOOL64 = @OTOOL64@ | ||
242 | PACKAGE = @PACKAGE@ | ||
243 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ | ||
244 | PACKAGE_NAME = @PACKAGE_NAME@ | ||
245 | PACKAGE_STRING = @PACKAGE_STRING@ | ||
246 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ | ||
247 | PACKAGE_URL = @PACKAGE_URL@ | ||
248 | PACKAGE_VERSION = @PACKAGE_VERSION@ | ||
249 | PATH_SEPARATOR = @PATH_SEPARATOR@ | ||
250 | PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ | ||
251 | PIXMAN_LIBS = @PIXMAN_LIBS@ | ||
252 | PKG_CONFIG = @PKG_CONFIG@ | ||
253 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ | ||
254 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ | ||
255 | POSUB = @POSUB@ | ||
256 | RANLIB = @RANLIB@ | ||
257 | SDL_CFLAGS = @SDL_CFLAGS@ | ||
258 | SDL_CONFIG = @SDL_CONFIG@ | ||
259 | SDL_LIBS = @SDL_LIBS@ | ||
260 | SED = @SED@ | ||
261 | SET_MAKE = @SET_MAKE@ | ||
262 | SHELL = @SHELL@ | ||
263 | SSL_CFLAGS = @SSL_CFLAGS@ | ||
264 | SSL_LIBS = @SSL_LIBS@ | ||
265 | STRIP = @STRIP@ | ||
266 | TLS2_CFLAGS = @TLS2_CFLAGS@ | ||
267 | TLS2_LIBS = @TLS2_LIBS@ | ||
268 | TLS_CFLAGS = @TLS_CFLAGS@ | ||
269 | TLS_LIBS = @TLS_LIBS@ | ||
270 | TSLIB_CFLAGS = @TSLIB_CFLAGS@ | ||
271 | TSLIB_LIBS = @TSLIB_LIBS@ | ||
272 | USE_NLS = @USE_NLS@ | ||
273 | VERSION = @VERSION@ | ||
274 | VMAJ = @VMAJ@ | ||
275 | WIN32_CFLAGS = @WIN32_CFLAGS@ | ||
276 | WIN32_CPPFLAGS = @WIN32_CPPFLAGS@ | ||
277 | WIN32_LIBS = @WIN32_LIBS@ | ||
278 | XCB_COMPOSITE_CFLAGS = @XCB_COMPOSITE_CFLAGS@ | ||
279 | XCB_COMPOSITE_LIBS = @XCB_COMPOSITE_LIBS@ | ||
280 | XCB_CURSOR_CFLAGS = @XCB_CURSOR_CFLAGS@ | ||
281 | XCB_CURSOR_LIBS = @XCB_CURSOR_LIBS@ | ||
282 | XCB_DAMAGE_CFLAGS = @XCB_DAMAGE_CFLAGS@ | ||
283 | XCB_DAMAGE_LIBS = @XCB_DAMAGE_LIBS@ | ||
284 | XCB_DPMS_CFLAGS = @XCB_DPMS_CFLAGS@ | ||
285 | XCB_DPMS_LIBS = @XCB_DPMS_LIBS@ | ||
286 | XCB_RANDR_CFLAGS = @XCB_RANDR_CFLAGS@ | ||
287 | XCB_RANDR_LIBS = @XCB_RANDR_LIBS@ | ||
288 | XCB_RENDER_CFLAGS = @XCB_RENDER_CFLAGS@ | ||
289 | XCB_RENDER_LIBS = @XCB_RENDER_LIBS@ | ||
290 | XCB_SCREENSAVER_CFLAGS = @XCB_SCREENSAVER_CFLAGS@ | ||
291 | XCB_SCREENSAVER_LIBS = @XCB_SCREENSAVER_LIBS@ | ||
292 | XCB_SHAPE_CFLAGS = @XCB_SHAPE_CFLAGS@ | ||
293 | XCB_SHAPE_LIBS = @XCB_SHAPE_LIBS@ | ||
294 | XCB_SYNC_CFLAGS = @XCB_SYNC_CFLAGS@ | ||
295 | XCB_SYNC_LIBS = @XCB_SYNC_LIBS@ | ||
296 | XCB_X11_CFLAGS = @XCB_X11_CFLAGS@ | ||
297 | XCB_X11_LIBS = @XCB_X11_LIBS@ | ||
298 | XCB_XFIXES_CFLAGS = @XCB_XFIXES_CFLAGS@ | ||
299 | XCB_XFIXES_LIBS = @XCB_XFIXES_LIBS@ | ||
300 | XCB_XGESTURE_CFLAGS = @XCB_XGESTURE_CFLAGS@ | ||
301 | XCB_XGESTURE_LIBS = @XCB_XGESTURE_LIBS@ | ||
302 | XCB_XINERAMA_CFLAGS = @XCB_XINERAMA_CFLAGS@ | ||
303 | XCB_XINERAMA_LIBS = @XCB_XINERAMA_LIBS@ | ||
304 | XCB_XINPUT_CFLAGS = @XCB_XINPUT_CFLAGS@ | ||
305 | XCB_XINPUT_LIBS = @XCB_XINPUT_LIBS@ | ||
306 | XCB_XPRINT_CFLAGS = @XCB_XPRINT_CFLAGS@ | ||
307 | XCB_XPRINT_LIBS = @XCB_XPRINT_LIBS@ | ||
308 | XCB_XTEST_CFLAGS = @XCB_XTEST_CFLAGS@ | ||
309 | XCB_XTEST_LIBS = @XCB_XTEST_LIBS@ | ||
310 | XCOMPOSITE_CFLAGS = @XCOMPOSITE_CFLAGS@ | ||
311 | XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ | ||
312 | XDAMAGE_CFLAGS = @XDAMAGE_CFLAGS@ | ||
313 | XDAMAGE_LIBS = @XDAMAGE_LIBS@ | ||
314 | XDPMS_CFLAGS = @XDPMS_CFLAGS@ | ||
315 | XDPMS_LIBS = @XDPMS_LIBS@ | ||
316 | XFIXES_CFLAGS = @XFIXES_CFLAGS@ | ||
317 | XFIXES_LIBS = @XFIXES_LIBS@ | ||
318 | XGESTURE_CFLAGS = @XGESTURE_CFLAGS@ | ||
319 | XGESTURE_LIBS = @XGESTURE_LIBS@ | ||
320 | XGETTEXT = @XGETTEXT@ | ||
321 | XGETTEXT_015 = @XGETTEXT_015@ | ||
322 | XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ | ||
323 | XI2_CFLAGS = @XI2_CFLAGS@ | ||
324 | XI2_LIBS = @XI2_LIBS@ | ||
325 | XINERAMA_CFLAGS = @XINERAMA_CFLAGS@ | ||
326 | XINERAMA_LIBS = @XINERAMA_LIBS@ | ||
327 | XKB_CFLAGS = @XKB_CFLAGS@ | ||
328 | XKB_LIBS = @XKB_LIBS@ | ||
329 | XMKMF = @XMKMF@ | ||
330 | XPRINT_CFLAGS = @XPRINT_CFLAGS@ | ||
331 | XPRINT_LIBS = @XPRINT_LIBS@ | ||
332 | XRANDR_CFLAGS = @XRANDR_CFLAGS@ | ||
333 | XRANDR_LIBS = @XRANDR_LIBS@ | ||
334 | XRENDER_CFLAGS = @XRENDER_CFLAGS@ | ||
335 | XRENDER_LIBS = @XRENDER_LIBS@ | ||
336 | XSS_CFLAGS = @XSS_CFLAGS@ | ||
337 | XSS_LIBS = @XSS_LIBS@ | ||
338 | XTEST_CFLAGS = @XTEST_CFLAGS@ | ||
339 | XTEST_LIBS = @XTEST_LIBS@ | ||
340 | X_CFLAGS = @X_CFLAGS@ | ||
341 | X_EXTRA_LIBS = @X_EXTRA_LIBS@ | ||
342 | X_LIBS = @X_LIBS@ | ||
343 | X_PRE_LIBS = @X_PRE_LIBS@ | ||
344 | Xcursor_cflags = @Xcursor_cflags@ | ||
345 | Xcursor_libs = @Xcursor_libs@ | ||
346 | abs_builddir = @abs_builddir@ | ||
347 | abs_srcdir = @abs_srcdir@ | ||
348 | abs_top_builddir = @abs_top_builddir@ | ||
349 | abs_top_srcdir = @abs_top_srcdir@ | ||
350 | ac_ct_CC = @ac_ct_CC@ | ||
351 | ac_ct_CXX = @ac_ct_CXX@ | ||
352 | ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ | ||
353 | ac_ct_OBJC = @ac_ct_OBJC@ | ||
354 | am__include = @am__include@ | ||
355 | am__leading_dot = @am__leading_dot@ | ||
356 | am__quote = @am__quote@ | ||
357 | am__tar = @am__tar@ | ||
358 | am__untar = @am__untar@ | ||
359 | bindir = @bindir@ | ||
360 | build = @build@ | ||
361 | build_alias = @build_alias@ | ||
362 | build_cpu = @build_cpu@ | ||
363 | build_os = @build_os@ | ||
364 | build_vendor = @build_vendor@ | ||
365 | builddir = @builddir@ | ||
366 | cocoa_ldflags = @cocoa_ldflags@ | ||
367 | datadir = @datadir@ | ||
368 | datarootdir = @datarootdir@ | ||
369 | dlopen_libs = @dlopen_libs@ | ||
370 | docdir = @docdir@ | ||
371 | dvidir = @dvidir@ | ||
372 | ecore_cocoa_cflags = @ecore_cocoa_cflags@ | ||
373 | ecore_cocoa_libs = @ecore_cocoa_libs@ | ||
374 | ecore_con_cflags = @ecore_con_cflags@ | ||
375 | ecore_con_libs = @ecore_con_libs@ | ||
376 | ecore_directfb_cflags = @ecore_directfb_cflags@ | ||
377 | ecore_directfb_libs = @ecore_directfb_libs@ | ||
378 | ecore_evas_cflags = @ecore_evas_cflags@ | ||
379 | ecore_evas_libs = @ecore_evas_libs@ | ||
380 | ecore_fb_cflags = @ecore_fb_cflags@ | ||
381 | ecore_fb_libs = @ecore_fb_libs@ | ||
382 | ecore_file_cflags = @ecore_file_cflags@ | ||
383 | ecore_file_libs = @ecore_file_libs@ | ||
384 | ecore_imf_cflags = @ecore_imf_cflags@ | ||
385 | ecore_imf_evas_cflags = @ecore_imf_evas_cflags@ | ||
386 | ecore_imf_evas_libs = @ecore_imf_evas_libs@ | ||
387 | ecore_imf_libs = @ecore_imf_libs@ | ||
388 | ecore_imf_xim_cflags = @ecore_imf_xim_cflags@ | ||
389 | ecore_imf_xim_libs = @ecore_imf_xim_libs@ | ||
390 | ecore_input_cflags = @ecore_input_cflags@ | ||
391 | ecore_input_evas_cflags = @ecore_input_evas_cflags@ | ||
392 | ecore_input_evas_libs = @ecore_input_evas_libs@ | ||
393 | ecore_input_libs = @ecore_input_libs@ | ||
394 | ecore_ipc_cflags = @ecore_ipc_cflags@ | ||
395 | ecore_ipc_libs = @ecore_ipc_libs@ | ||
396 | ecore_psl1ght_cflags = @ecore_psl1ght_cflags@ | ||
397 | ecore_psl1ght_libs = @ecore_psl1ght_libs@ | ||
398 | ecore_sdl_cflags = @ecore_sdl_cflags@ | ||
399 | ecore_sdl_libs = @ecore_sdl_libs@ | ||
400 | ecore_win32_cflags = @ecore_win32_cflags@ | ||
401 | ecore_win32_libs = @ecore_win32_libs@ | ||
402 | ecore_wince_cflags = @ecore_wince_cflags@ | ||
403 | ecore_wince_libs = @ecore_wince_libs@ | ||
404 | ecore_x_cflags = @ecore_x_cflags@ | ||
405 | ecore_x_libs = @ecore_x_libs@ | ||
406 | ecore_x_libs_private = @ecore_x_libs_private@ | ||
407 | efl_doxygen = @efl_doxygen@ | ||
408 | efl_have_doxygen = @efl_have_doxygen@ | ||
409 | exec_prefix = @exec_prefix@ | ||
410 | have_ecore_x_xcb_define = @have_ecore_x_xcb_define@ | ||
411 | host = @host@ | ||
412 | host_alias = @host_alias@ | ||
413 | host_cpu = @host_cpu@ | ||
414 | host_os = @host_os@ | ||
415 | host_vendor = @host_vendor@ | ||
416 | htmldir = @htmldir@ | ||
417 | includedir = @includedir@ | ||
418 | infodir = @infodir@ | ||
419 | install_sh = @install_sh@ | ||
420 | libdir = @libdir@ | ||
421 | libexecdir = @libexecdir@ | ||
422 | localedir = @localedir@ | ||
423 | localstatedir = @localstatedir@ | ||
424 | lt_ECHO = @lt_ECHO@ | ||
425 | lt_enable_auto_import = @lt_enable_auto_import@ | ||
426 | mandir = @mandir@ | ||
427 | mkdir_p = @mkdir_p@ | ||
428 | oldincludedir = @oldincludedir@ | ||
429 | pdfdir = @pdfdir@ | ||
430 | pkgconfig_requires_private = @pkgconfig_requires_private@ | ||
431 | prefix = @prefix@ | ||
432 | program_transform_name = @program_transform_name@ | ||
433 | psdir = @psdir@ | ||
434 | release_info = @release_info@ | ||
435 | requirements_ecore = @requirements_ecore@ | ||
436 | requirements_ecore_cocoa = @requirements_ecore_cocoa@ | ||
437 | requirements_ecore_con = @requirements_ecore_con@ | ||
438 | requirements_ecore_directfb = @requirements_ecore_directfb@ | ||
439 | requirements_ecore_evas = @requirements_ecore_evas@ | ||
440 | requirements_ecore_fb = @requirements_ecore_fb@ | ||
441 | requirements_ecore_file = @requirements_ecore_file@ | ||
442 | requirements_ecore_imf = @requirements_ecore_imf@ | ||
443 | requirements_ecore_imf_evas = @requirements_ecore_imf_evas@ | ||
444 | requirements_ecore_imf_xim = @requirements_ecore_imf_xim@ | ||
445 | requirements_ecore_input = @requirements_ecore_input@ | ||
446 | requirements_ecore_input_evas = @requirements_ecore_input_evas@ | ||
447 | requirements_ecore_ipc = @requirements_ecore_ipc@ | ||
448 | requirements_ecore_psl1ght = @requirements_ecore_psl1ght@ | ||
449 | requirements_ecore_sdl = @requirements_ecore_sdl@ | ||
450 | requirements_ecore_win32 = @requirements_ecore_win32@ | ||
451 | requirements_ecore_wince = @requirements_ecore_wince@ | ||
452 | requirements_ecore_x = @requirements_ecore_x@ | ||
453 | rt_libs = @rt_libs@ | ||
454 | sbindir = @sbindir@ | ||
455 | sharedstatedir = @sharedstatedir@ | ||
456 | srcdir = @srcdir@ | ||
457 | sysconfdir = @sysconfdir@ | ||
458 | target_alias = @target_alias@ | ||
459 | top_build_prefix = @top_build_prefix@ | ||
460 | top_builddir = @top_builddir@ | ||
461 | top_srcdir = @top_srcdir@ | ||
462 | version_info = @version_info@ | ||
463 | x_cflags = @x_cflags@ | ||
464 | x_includes = @x_includes@ | ||
465 | x_libs = @x_libs@ | ||
466 | MAINTAINERCLEANFILES = Makefile.in | ||
467 | AM_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 | |||
477 | AM_CFLAGS = @WIN32_CFLAGS@ | ||
478 | @BUILD_ECORE_CON_TRUE@lib_ecore_con_la = $(top_builddir)/src/lib/ecore_con/libecore_con.la | ||
479 | lib_LTLIBRARIES = libecore_file.la | ||
480 | includes_HEADERS = Ecore_File.h | ||
481 | includesdir = $(includedir)/ecore-@VMAJ@ | ||
482 | libecore_file_la_SOURCES = \ | ||
483 | ecore_file.c \ | ||
484 | ecore_file_monitor.c \ | ||
485 | ecore_file_monitor_inotify.c \ | ||
486 | ecore_file_monitor_win32.c \ | ||
487 | ecore_file_monitor_poll.c \ | ||
488 | ecore_file_path.c \ | ||
489 | ecore_file_download.c | ||
490 | |||
491 | libecore_file_la_LIBADD = \ | ||
492 | $(top_builddir)/src/lib/ecore/libecore.la \ | ||
493 | $(lib_ecore_con_la) \ | ||
494 | @EVIL_LIBS@ \ | ||
495 | @EINA_LIBS@ | ||
496 | |||
497 | libecore_file_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ | ||
498 | EXTRA_DIST = ecore_file_private.h | ||
499 | all: 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 | ||
516 | Makefile: $(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): | ||
533 | install-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 | |||
547 | uninstall-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 | |||
556 | clean-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 | ||
564 | libecore_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 | |||
567 | mostlyclean-compile: | ||
568 | -rm -f *.$(OBJEXT) | ||
569 | |||
570 | distclean-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 | |||
605 | mostlyclean-libtool: | ||
606 | -rm -f *.lo | ||
607 | |||
608 | clean-libtool: | ||
609 | -rm -rf .libs _libs | ||
610 | install-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 | |||
623 | uninstall-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 | |||
631 | ID: $(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 | ||
639 | tags: TAGS | ||
640 | |||
641 | TAGS: $(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 | ||
662 | ctags: CTAGS | ||
663 | CTAGS: $(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 | |||
675 | GTAGS: | ||
676 | here=`$(am__cd) $(top_builddir) && pwd` \ | ||
677 | && $(am__cd) $(top_srcdir) \ | ||
678 | && gtags -i $(GTAGS_ARGS) "$$here" | ||
679 | |||
680 | distclean-tags: | ||
681 | -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags | ||
682 | |||
683 | distdir: $(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 | ||
713 | check-am: all-am | ||
714 | check: check-am | ||
715 | all-am: Makefile $(LTLIBRARIES) $(HEADERS) | ||
716 | installdirs: | ||
717 | for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"; do \ | ||
718 | test -z "$$dir" || $(MKDIR_P) "$$dir"; \ | ||
719 | done | ||
720 | install: install-am | ||
721 | install-exec: install-exec-am | ||
722 | install-data: install-data-am | ||
723 | uninstall: uninstall-am | ||
724 | |||
725 | install-am: all-am | ||
726 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | ||
727 | |||
728 | installcheck: installcheck-am | ||
729 | install-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 | ||
734 | mostlyclean-generic: | ||
735 | |||
736 | clean-generic: | ||
737 | |||
738 | distclean-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 | |||
742 | maintainer-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) | ||
746 | clean: clean-am | ||
747 | |||
748 | clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ | ||
749 | mostlyclean-am | ||
750 | |||
751 | distclean: distclean-am | ||
752 | -rm -rf ./$(DEPDIR) | ||
753 | -rm -f Makefile | ||
754 | distclean-am: clean-am distclean-compile distclean-generic \ | ||
755 | distclean-tags | ||
756 | |||
757 | dvi: dvi-am | ||
758 | |||
759 | dvi-am: | ||
760 | |||
761 | html: html-am | ||
762 | |||
763 | html-am: | ||
764 | |||
765 | info: info-am | ||
766 | |||
767 | info-am: | ||
768 | |||
769 | install-data-am: install-includesHEADERS | ||
770 | |||
771 | install-dvi: install-dvi-am | ||
772 | |||
773 | install-dvi-am: | ||
774 | |||
775 | install-exec-am: install-libLTLIBRARIES | ||
776 | |||
777 | install-html: install-html-am | ||
778 | |||
779 | install-html-am: | ||
780 | |||
781 | install-info: install-info-am | ||
782 | |||
783 | install-info-am: | ||
784 | |||
785 | install-man: | ||
786 | |||
787 | install-pdf: install-pdf-am | ||
788 | |||
789 | install-pdf-am: | ||
790 | |||
791 | install-ps: install-ps-am | ||
792 | |||
793 | install-ps-am: | ||
794 | |||
795 | installcheck-am: | ||
796 | |||
797 | maintainer-clean: maintainer-clean-am | ||
798 | -rm -rf ./$(DEPDIR) | ||
799 | -rm -f Makefile | ||
800 | maintainer-clean-am: distclean-am maintainer-clean-generic | ||
801 | |||
802 | mostlyclean: mostlyclean-am | ||
803 | |||
804 | mostlyclean-am: mostlyclean-compile mostlyclean-generic \ | ||
805 | mostlyclean-libtool | ||
806 | |||
807 | pdf: pdf-am | ||
808 | |||
809 | pdf-am: | ||
810 | |||
811 | ps: ps-am | ||
812 | |||
813 | ps-am: | ||
814 | |||
815 | uninstall-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 | |||
29 | int _ecore_file_log_dom = -1; | ||
30 | static 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 | */ | ||
53 | EAPI int | ||
54 | ecore_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 | */ | ||
105 | EAPI int | ||
106 | ecore_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 | */ | ||
133 | EAPI long long | ||
134 | ecore_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 | */ | ||
151 | EAPI long long | ||
152 | ecore_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 | */ | ||
169 | EAPI Eina_Bool | ||
170 | ecore_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 | */ | ||
190 | EAPI Eina_Bool | ||
191 | ecore_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 | |||
200 | static 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 | */ | ||
212 | EAPI Eina_Bool | ||
213 | ecore_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 | */ | ||
232 | EAPI int | ||
233 | ecore_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 | */ | ||
263 | EAPI int | ||
264 | ecore_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 | */ | ||
349 | EAPI Eina_Bool | ||
350 | ecore_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 | */ | ||
365 | EAPI Eina_Bool | ||
366 | ecore_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 | */ | ||
381 | EAPI Eina_Bool | ||
382 | ecore_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 | */ | ||
398 | EAPI Eina_Bool | ||
399 | ecore_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 | |||
438 | static 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 | */ | ||
471 | EAPI Eina_Bool | ||
472 | ecore_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 | */ | ||
507 | EAPI int | ||
508 | ecore_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 | */ | ||
532 | EAPI Eina_Bool | ||
533 | ecore_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 | */ | ||
571 | EAPI Eina_Bool | ||
572 | ecore_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 | |||
632 | PASS: | ||
633 | return EINA_TRUE; | ||
634 | |||
635 | FAIL: | ||
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 | */ | ||
650 | EAPI Eina_Bool | ||
651 | ecore_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 | */ | ||
670 | EAPI char * | ||
671 | ecore_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 | */ | ||
694 | EAPI const char * | ||
695 | ecore_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 | */ | ||
716 | EAPI char * | ||
717 | ecore_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 | */ | ||
738 | EAPI Eina_Bool | ||
739 | ecore_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 | */ | ||
755 | EAPI Eina_Bool | ||
756 | ecore_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 | */ | ||
772 | EAPI Eina_Bool | ||
773 | ecore_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 | */ | ||
791 | EAPI char * | ||
792 | ecore_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 | */ | ||
819 | EAPI Eina_List * | ||
820 | ecore_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 | */ | ||
851 | EAPI char * | ||
852 | ecore_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; | ||
861 | restart: | ||
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 | */ | ||
1008 | EAPI char * | ||
1009 | ecore_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 | */ | ||
1054 | EAPI char * | ||
1055 | ecore_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 | */ | ||
1089 | EAPI int | ||
1090 | ecore_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 | |||
18 | struct _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 | ||
32 | Ecore_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 | |||
38 | static Eina_Bool _ecore_file_download_url_complete_cb(void *data, int type, void *event); | ||
39 | static Eina_Bool _ecore_file_download_url_progress_cb(void *data, int type, void *event); | ||
40 | #endif | ||
41 | |||
42 | static Ecore_Event_Handler *_url_complete_handler = NULL; | ||
43 | static Ecore_Event_Handler *_url_progress_download = NULL; | ||
44 | static Eina_List *_job_list; | ||
45 | |||
46 | #endif /* BUILD_ECORE_CON */ | ||
47 | |||
48 | int | ||
49 | ecore_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 | |||
65 | void | ||
66 | ecore_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 | ||
83 | static 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 | |||
94 | static 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 | */ | ||
211 | EAPI Eina_Bool | ||
212 | ecore_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 | */ | ||
234 | EAPI Eina_Bool | ||
235 | ecore_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 | */ | ||
257 | EAPI Eina_Bool | ||
258 | ecore_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 | ||
276 | static 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 | |||
286 | static 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 | |||
307 | static 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 | |||
334 | Ecore_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 | */ | ||
400 | EAPI void | ||
401 | ecore_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 | */ | ||
427 | EAPI void | ||
428 | ecore_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 | |||
7 | typedef 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 | |||
20 | static Ecore_File_Monitor_Type monitor_type = ECORE_FILE_MONITOR_TYPE_NONE; | ||
21 | |||
22 | int | ||
23 | ecore_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 | |||
44 | void | ||
45 | ecore_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 | */ | ||
92 | EAPI Ecore_File_Monitor * | ||
93 | ecore_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 | */ | ||
131 | EAPI void | ||
132 | ecore_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 | */ | ||
170 | EAPI const char * | ||
171 | ecore_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 | ||
32 | static inline int inotify_init(void); | ||
33 | static inline int inotify_add_watch(int fd, const char *name, __u32 mask); | ||
34 | static inline int inotify_rm_watch(int fd, __u32 wd); | ||
35 | #endif | ||
36 | |||
37 | |||
38 | typedef struct _Ecore_File_Monitor_Inotify Ecore_File_Monitor_Inotify; | ||
39 | |||
40 | #define ECORE_FILE_MONITOR_INOTIFY(x) ((Ecore_File_Monitor_Inotify *)(x)) | ||
41 | |||
42 | struct _Ecore_File_Monitor_Inotify | ||
43 | { | ||
44 | Ecore_File_Monitor monitor; | ||
45 | int wd; | ||
46 | }; | ||
47 | |||
48 | static Ecore_Fd_Handler *_fdh = NULL; | ||
49 | static Ecore_File_Monitor *_monitors = NULL; | ||
50 | static pid_t _inotify_fd_pid = -1; | ||
51 | |||
52 | static Eina_Bool _ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh); | ||
53 | static Ecore_File_Monitor *_ecore_file_monitor_inotify_monitor_find(int wd); | ||
54 | static void _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask); | ||
55 | static int _ecore_file_monitor_inotify_monitor(Ecore_File_Monitor *em, const char *path); | ||
56 | #if 0 | ||
57 | static void _ecore_file_monitor_inotify_print(char *file, int mask); | ||
58 | #endif | ||
59 | |||
60 | int | ||
61 | ecore_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 | |||
81 | int | ||
82 | ecore_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 | |||
99 | Ecore_File_Monitor * | ||
100 | ecore_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 | |||
144 | void | ||
145 | ecore_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 | |||
159 | static 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 | |||
185 | static 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 | |||
198 | static 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 | |||
284 | static 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 | ||
311 | static inline int | ||
312 | inotify_init(void) | ||
313 | { | ||
314 | return syscall(__NR_inotify_init); | ||
315 | } | ||
316 | |||
317 | static inline int | ||
318 | inotify_add_watch(int fd, const char *name, __u32 mask) | ||
319 | { | ||
320 | return syscall(__NR_inotify_add_watch, fd, name, mask); | ||
321 | } | ||
322 | |||
323 | static inline int | ||
324 | inotify_rm_watch(int fd, __u32 wd) | ||
325 | { | ||
326 | return syscall(__NR_inotify_rm_watch, fd, wd); | ||
327 | } | ||
328 | #endif | ||
329 | |||
330 | #if 0 | ||
331 | static 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 | |||
20 | typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll; | ||
21 | |||
22 | #define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x)) | ||
23 | |||
24 | struct _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 | |||
35 | static double _interval = ECORE_FILE_INTERVAL_MIN; | ||
36 | static Ecore_Timer *_timer = NULL; | ||
37 | static Ecore_File_Monitor *_monitors = NULL; | ||
38 | static int _lock = 0; | ||
39 | |||
40 | static Eina_Bool _ecore_file_monitor_poll_handler(void *data); | ||
41 | static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em); | ||
42 | static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name); | ||
43 | |||
44 | int | ||
45 | ecore_file_monitor_poll_init(void) | ||
46 | { | ||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | int | ||
51 | ecore_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 | |||
64 | Ecore_File_Monitor * | ||
65 | ecore_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 | |||
134 | void | ||
135 | ecore_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 | |||
177 | static 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 | |||
204 | static 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 | |||
327 | static 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 | |||
19 | typedef struct _Ecore_File_Monitor_Win32 Ecore_File_Monitor_Win32; | ||
20 | typedef 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 | |||
26 | struct _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 | |||
38 | struct _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 | |||
45 | static Ecore_File_Monitor *_monitors = NULL; | ||
46 | |||
47 | static Eina_Bool _ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh); | ||
48 | |||
49 | |||
50 | static 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 | |||
118 | static 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 | |||
128 | static 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 | |||
227 | int | ||
228 | ecore_file_monitor_win32_init(void) | ||
229 | { | ||
230 | return 1; | ||
231 | } | ||
232 | |||
233 | int | ||
234 | ecore_file_monitor_win32_shutdown(void) | ||
235 | { | ||
236 | return 1; | ||
237 | } | ||
238 | |||
239 | Ecore_File_Monitor * | ||
240 | ecore_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 | |||
295 | void | ||
296 | ecore_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 | ||
18 | extern "C" | ||
19 | # endif | ||
20 | void *alloca (size_t); | ||
21 | #endif | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <string.h> | ||
25 | |||
26 | #include "ecore_file_private.h" | ||
27 | |||
28 | static Eina_List *__ecore_file_path_bin = NULL; | ||
29 | |||
30 | static Eina_List *_ecore_file_path_from_env(const char *env); | ||
31 | |||
32 | void | ||
33 | ecore_file_path_init(void) | ||
34 | { | ||
35 | __ecore_file_path_bin = _ecore_file_path_from_env("PATH"); | ||
36 | } | ||
37 | |||
38 | void | ||
39 | ecore_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 | |||
47 | Eina_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 | */ | ||
96 | EAPI Eina_Bool | ||
97 | ecore_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 | */ | ||
127 | EAPI Eina_Bool | ||
128 | ecore_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 | */ | ||
158 | EAPI Eina_List * | ||
159 | ecore_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 | |||
24 | extern 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 */ | ||
57 | int ecore_file_monitor_init(void); | ||
58 | void ecore_file_monitor_shutdown(void); | ||
59 | |||
60 | #define ECORE_FILE_MONITOR(x) ((Ecore_File_Monitor *)(x)) | ||
61 | |||
62 | typedef struct _Ecore_File Ecore_File; | ||
63 | struct _Ecore_File | ||
64 | { | ||
65 | EINA_INLIST; | ||
66 | char *name; | ||
67 | int mtime; | ||
68 | unsigned char is_dir; | ||
69 | }; | ||
70 | |||
71 | struct _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 | ||
85 | int ecore_file_monitor_inotify_init(void); | ||
86 | int ecore_file_monitor_inotify_shutdown(void); | ||
87 | Ecore_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); | ||
93 | void ecore_file_monitor_inotify_del(Ecore_File_Monitor *ecore_file_monitor); | ||
94 | #endif | ||
95 | |||
96 | #ifdef HAVE_NOTIFY_WIN32 | ||
97 | int ecore_file_monitor_win32_init(void); | ||
98 | int ecore_file_monitor_win32_shutdown(void); | ||
99 | Ecore_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); | ||
105 | void ecore_file_monitor_win32_del(Ecore_File_Monitor *ecore_file_monitor); | ||
106 | #endif | ||
107 | |||
108 | #ifdef HAVE_POLL | ||
109 | int ecore_file_monitor_poll_init(void); | ||
110 | int ecore_file_monitor_poll_shutdown(void); | ||
111 | Ecore_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); | ||
117 | void ecore_file_monitor_poll_del(Ecore_File_Monitor *ecore_file_monitor); | ||
118 | |||
119 | #endif | ||
120 | |||
121 | /* ecore_file_path */ | ||
122 | void ecore_file_path_init(void); | ||
123 | void ecore_file_path_shutdown(void); | ||
124 | |||
125 | /* ecore_file_download */ | ||
126 | int ecore_file_download_init(void); | ||
127 | void ecore_file_download_shutdown(void); | ||
128 | |||
129 | #endif | ||