10 #include <Ecore_File.h>
12 /* define macros and variable for using the eina logging system */
13 #define EFREET_MODULE_LOG_DOM _efreet_trash_log_dom
14 static int _efreet_trash_log_dom = -1;
17 #include "Efreet_Trash.h"
18 #include "efreet_private.h"
20 static unsigned int _efreet_trash_init_count = 0;
21 static const char *efreet_trash_dir = NULL;
24 # define getuid() GetCurrentProcessId()
28 efreet_trash_init(void)
30 if (++_efreet_trash_init_count != 1)
31 return _efreet_trash_init_count;
34 return --_efreet_trash_init_count;
36 _efreet_trash_log_dom = eina_log_domain_register
37 ("efreet_trash", EFREET_DEFAULT_LOG_COLOR);
38 if (_efreet_trash_log_dom < 0)
40 EINA_LOG_ERR("Efreet: Could not create a log domain for efreet_trash");
42 return --_efreet_trash_init_count;
44 return _efreet_trash_init_count;
48 efreet_trash_shutdown(void)
50 if (--_efreet_trash_init_count != 0)
51 return _efreet_trash_init_count;
53 IF_RELEASE(efreet_trash_dir);
54 eina_log_domain_unregister(_efreet_trash_log_dom);
55 _efreet_trash_log_dom = -1;
58 return _efreet_trash_init_count;
62 efreet_trash_dir_get(const char *file)
67 const char *trash_dir = NULL;
71 if (stat(efreet_data_home_get(), &s_dest) != 0)
74 if (stat(file, &s_src) != 0)
78 if (!file || s_src.st_dev == s_dest.st_dev)
80 if (efreet_trash_dir && ecore_file_exists(efreet_trash_dir))
82 eina_stringshare_ref(efreet_trash_dir);
83 return efreet_trash_dir;
86 snprintf(buf, sizeof(buf), "%s/Trash", efreet_data_home_get());
87 if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
90 IF_RELEASE(efreet_trash_dir);
91 efreet_trash_dir = eina_stringshare_add(buf);
92 trash_dir = eina_stringshare_ref(efreet_trash_dir);
99 strncpy(buf, file, PATH_MAX);
100 buf[PATH_MAX - 1] = 0;
103 while (strlen(buf) > 1)
105 strncpy(path, buf, PATH_MAX);
108 if (stat(dir, &s_dest) == 0)
110 if (s_src.st_dev == s_dest.st_dev){
112 strncpy(buf, dir, PATH_MAX);
127 snprintf(buf, sizeof(buf), "%s/.Trash-%d", path, getuid());
128 if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
131 trash_dir = eina_stringshare_add(buf);
136 snprintf(buf, sizeof(buf), "%s/files", trash_dir);
137 if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
139 eina_stringshare_del(trash_dir);
143 snprintf(buf, sizeof(buf), "%s/info", trash_dir);
144 if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
146 eina_stringshare_del(trash_dir);
155 efreet_trash_delete_uri(Efreet_Uri *uri, int force_delete)
161 const char *trash_dir;
166 EINA_SAFETY_ON_NULL_RETURN_VAL(uri, 0);
167 EINA_SAFETY_ON_NULL_RETURN_VAL(uri->path, 0);
168 EINA_SAFETY_ON_FALSE_RETURN_VAL(ecore_file_can_write(uri->path), 0);
170 fname = ecore_file_file_get(uri->path);
172 trash_dir = efreet_trash_dir_get(uri->path);
175 ERR("EFREET TRASH ERROR: No trash directory.");
178 snprintf(dest, sizeof(dest), "%s/files/%s", trash_dir, fname);
180 /* search for a free filename */
181 while (ecore_file_exists(dest) && (i < 100))
182 snprintf(dest, sizeof(dest), "%s/files/%s$%d",
183 trash_dir, fname, i++);
185 fname = ecore_file_file_get(dest);
187 /* move file to trash dir */
188 if (rename(uri->path, dest))
194 eina_stringshare_del(trash_dir);
198 if (!ecore_file_recursive_rm(uri->path))
200 ERR("EFREET TRASH ERROR: Can't delete file.");
201 eina_stringshare_del(trash_dir);
207 ERR("EFREET TRASH ERROR: Can't move file to trash.");
208 eina_stringshare_del(trash_dir);
213 /* create info file */
214 snprintf(dest, sizeof(dest), "%s/info/%s.trashinfo", trash_dir, fname);
216 if ((f = fopen(dest, "w")))
218 fputs("[Trash Info]\n", f);
221 escaped = efreet_uri_encode(uri);
222 fputs(escaped + 7, f); // +7 == don't write 'file://'
226 strftime(times, sizeof(times), "%Y-%m-%dT%H:%M:%S", localtime(&now));
227 fputs("\nDeletionDate=", f);
234 ERR("EFREET TRASH ERROR: Can't create trash info file.");
242 efreet_trash_is_empty(void)
246 snprintf(buf, sizeof(buf), "%s/files", efreet_trash_dir_get(NULL));
248 /* TODO Check also trash in other filesystems */
249 return ecore_file_dir_is_empty(buf);
253 efreet_trash_empty_trash(void)
257 snprintf(buf, sizeof(buf), "%s/info", efreet_trash_dir_get(NULL));
258 if (!ecore_file_recursive_rm(buf)) return 0;
259 ecore_file_mkdir(buf);
261 snprintf(buf, sizeof(buf), "%s/files", efreet_trash_dir_get(NULL));
262 if (!ecore_file_recursive_rm(buf)) return 0;
263 ecore_file_mkdir(buf);
265 /* TODO Empty also trash in other filesystems */
270 efreet_trash_ls(void)
274 Eina_List *files, *l;
276 // NOTE THIS FUNCTION NOW IS NOT COMPLETE AS I DON'T NEED IT
277 // TODO read the name from the infofile instead of the filename
279 snprintf(buf, sizeof(buf), "%s/files", efreet_trash_dir_get(NULL));
280 files = ecore_file_ls(buf);
282 if (eina_log_domain_level_check(_efreet_trash_log_dom, EINA_LOG_LEVEL_INFO))
283 EINA_LIST_FOREACH(files, l, infofile)
284 INF("FILE: %s\n", infofile);