11
#include "efreetd_ipc.h"
14
#define EFREET_MODULE_LOG_DOM efreetd_log_dom
15
#include "efreet_private.h"
16
#include "efreetd_cache.h"
22
extern FILE *efreetd_log_file;
24
static Eina_Hash *icon_change_monitors = NULL;
25
static Eina_Hash *icon_change_monitors_mon = NULL;
26
static Eina_Hash *desktop_change_monitors = NULL;
27
static Eina_Hash *desktop_change_monitors_mon = NULL;
29
static Ecore_Event_Handler *cache_exe_del_handler = NULL;
30
static Ecore_Event_Handler *cache_exe_data_handler = NULL;
31
static Ecore_Exe *icon_cache_exe = NULL;
32
static Ecore_Exe *desktop_cache_exe = NULL;
33
static Ecore_Timer *icon_cache_timer = NULL;
34
static Ecore_Timer *desktop_cache_timer = NULL;
35
static Eina_Prefix *pfx = NULL;
37
static Eina_Bool desktop_exists = EINA_FALSE;
39
static Eina_List *desktop_system_dirs = NULL;
40
static Eina_List *desktop_extra_dirs = NULL;
41
static Eina_List *icon_extra_dirs = NULL;
42
static Eina_List *icon_exts = NULL;
43
static Eina_Bool icon_flush = EINA_FALSE;
45
static Eina_Bool desktop_queue = EINA_FALSE;
46
static Eina_Bool icon_queue = EINA_FALSE;
48
static Eina_List *_handlers = NULL;
50
static void icon_changes_listen(void);
51
static void desktop_changes_listen(void);
54
typedef struct _Subdir_Cache Subdir_Cache;
55
typedef struct _Subdir_Cache_Dir Subdir_Cache_Dir;
62
struct _Subdir_Cache_Dir
64
unsigned long long dev;
65
unsigned long long ino;
66
unsigned long long mode;
67
unsigned long long uid;
68
unsigned long long gid;
69
unsigned long long size;
70
unsigned long long mtim;
71
unsigned long long ctim;
73
unsigned int dirs_count;
76
static Eet_Data_Descriptor *subdir_edd = NULL;
77
static Eet_Data_Descriptor *subdir_dir_edd = NULL;
78
static Subdir_Cache *subdir_cache = NULL;
79
static Eina_Bool subdir_need_save = EINA_FALSE;
81
static Eina_Hash *mime_monitors = NULL;
82
static Eina_Hash *mime_monitors_mon = NULL;
83
static Ecore_Timer *mime_update_timer = NULL;
84
static Ecore_Exe *mime_cache_exe = NULL;
86
static void mime_cache_init(void);
87
static void mime_cache_shutdown(void);
88
static Eina_Bool mime_update_cache_cb(void *data EINA_UNUSED);
91
subdir_cache_dir_free(Subdir_Cache_Dir *cd)
97
for (i = 0; i < cd->dirs_count; i++)
98
eina_stringshare_del(cd->dirs[i]);
105
subdir_cache_hash_add(void *hash, const char *key, void *data)
107
if (!hash) hash = eina_hash_string_superfast_new(EINA_FREE_CB(subdir_cache_dir_free));
108
if (!hash) return NULL;
109
eina_hash_add(hash, key, data);
114
subdir_cache_init(void)
116
Eet_Data_Descriptor_Class eddc;
118
Eina_Strbuf *buf = eina_strbuf_new();
122
eet_eina_stream_data_descriptor_class_set(&eddc, sizeof(Subdir_Cache_Dir), "D", sizeof(Subdir_Cache_Dir));
123
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Subdir_Cache_Dir);
124
subdir_dir_edd = eet_data_descriptor_stream_new(&eddc);
125
EET_DATA_DESCRIPTOR_ADD_BASIC(subdir_dir_edd, Subdir_Cache_Dir, "0", dev, EET_T_ULONG_LONG);
126
EET_DATA_DESCRIPTOR_ADD_BASIC(subdir_dir_edd, Subdir_Cache_Dir, "1", ino, EET_T_ULONG_LONG);
127
EET_DATA_DESCRIPTOR_ADD_BASIC(subdir_dir_edd, Subdir_Cache_Dir, "2", mode, EET_T_ULONG_LONG);
128
EET_DATA_DESCRIPTOR_ADD_BASIC(subdir_dir_edd, Subdir_Cache_Dir, "3", uid, EET_T_ULONG_LONG);
129
EET_DATA_DESCRIPTOR_ADD_BASIC(subdir_dir_edd, Subdir_Cache_Dir, "4", gid, EET_T_ULONG_LONG);
130
EET_DATA_DESCRIPTOR_ADD_BASIC(subdir_dir_edd, Subdir_Cache_Dir, "5", size, EET_T_ULONG_LONG);
131
EET_DATA_DESCRIPTOR_ADD_BASIC(subdir_dir_edd, Subdir_Cache_Dir, "6", mtim, EET_T_ULONG_LONG);
132
EET_DATA_DESCRIPTOR_ADD_BASIC(subdir_dir_edd, Subdir_Cache_Dir, "7", ctim, EET_T_ULONG_LONG);
133
EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING(subdir_dir_edd, Subdir_Cache_Dir, "d", dirs);
135
eet_eina_stream_data_descriptor_class_set(&eddc, sizeof(Subdir_Cache), "C", sizeof(Subdir_Cache));
136
eddc.func.hash_add = subdir_cache_hash_add;
137
subdir_edd = eet_data_descriptor_stream_new(&eddc);
138
EET_DATA_DESCRIPTOR_ADD_HASH(subdir_edd, Subdir_Cache, "dirs", dirs, subdir_dir_edd);
141
eina_strbuf_append_printf(buf, "%s/efreet/subdirs_%s.eet",
142
efreet_cache_home_get(), efreet_hostname_get());
143
ef = eet_open(eina_strbuf_string_get(buf), EET_FILE_MODE_READ);
146
subdir_cache = eet_data_read(ef, subdir_edd, "subdirs");
149
eina_strbuf_free(buf);
152
if (!subdir_cache) subdir_cache = calloc(1, sizeof(Subdir_Cache));
155
ERR("Cannot allocate subdir cache in memory");
160
if (!subdir_cache->dirs)
161
subdir_cache->dirs = eina_hash_string_superfast_new(EINA_FREE_CB(subdir_cache_dir_free));
165
subdir_cache_shutdown(void)
170
if (subdir_cache->dirs) eina_hash_free(subdir_cache->dirs);
173
eet_data_descriptor_free(subdir_dir_edd);
174
eet_data_descriptor_free(subdir_edd);
176
subdir_dir_edd = NULL;
181
subdir_cache_save(void)
185
Eina_Tmpstr *tmpstr = NULL;
189
if (!subdir_need_save) return;
190
if (!subdir_cache) return;
191
if (!subdir_cache->dirs) return;
193
buf = eina_strbuf_new();
197
eina_strbuf_append_printf(buf, "%s/efreet/subdirs_%s.eet.XXXXXX.cache",
198
efreet_cache_home_get(), efreet_hostname_get());
200
tmpfd = eina_file_mkstemp(eina_strbuf_string_get(buf), &tmpstr);
203
eina_strbuf_free(buf);
207
eina_strbuf_reset(buf);
210
ef = eet_open(tmpstr, EET_FILE_MODE_WRITE);
211
eet_data_write(ef, subdir_edd, "subdirs", subdir_cache, EET_COMPRESSION_SUPERFAST);
224
eina_strbuf_append_printf(buf, "%s/efreet/subdirs_%s.eet",
225
efreet_cache_home_get(), efreet_hostname_get());
227
if (rename(tmpstr, eina_strbuf_string_get(buf)) < 0)
230
ERR("Can't save subdir cache %s", eina_strbuf_string_get(buf));
233
subdir_need_save = EINA_FALSE;
234
eina_tmpstr_del(tmpstr);
235
eina_strbuf_free(buf);
238
static const Subdir_Cache_Dir *
239
subdir_cache_get(const struct stat *st, const char *path)
242
Eina_File_Direct_Info *info;
243
Subdir_Cache_Dir *cd;
244
Eina_List *files = NULL;
249
if (!subdir_cache) return NULL;
250
if (!subdir_cache->dirs) return NULL;
253
cd = eina_hash_find(subdir_cache->dirs, path);
255
((cd->dev != (unsigned long long)st->st_dev) ||
256
(cd->ino != (unsigned long long)st->st_ino) ||
257
(cd->mode != (unsigned long long)st->st_mode) ||
258
(cd->uid != (unsigned long long)st->st_uid) ||
259
(cd->gid != (unsigned long long)st->st_gid) ||
260
(cd->size != (unsigned long long)st->st_size) ||
261
(cd->mtim != (unsigned long long)st->st_mtime) ||
262
(cd->ctim != (unsigned long long)st->st_ctime)))
265
eina_hash_del(subdir_cache->dirs, path, cd);
272
cd = calloc(1, sizeof(Subdir_Cache_Dir));
273
if (!cd) return NULL;
276
cd->dev = (unsigned long long)st->st_dev;
277
cd->ino = (unsigned long long)st->st_ino;
278
cd->mode = (unsigned long long)st->st_mode;
279
cd->uid = (unsigned long long)st->st_uid;
280
cd->gid = (unsigned long long)st->st_gid;
281
cd->size = (unsigned long long)st->st_size;
282
cd->mtim = (unsigned long long)st->st_mtime;
283
cd->ctim = (unsigned long long)st->st_ctime;
286
it = eina_file_stat_ls(path);
289
EINA_ITERATOR_FOREACH(it, info)
292
if (info->path[info->name_start] == '.') continue;
294
if (((info->type == EINA_FILE_LNK) && (ecore_file_is_dir(info->path))) ||
295
(info->type == EINA_FILE_DIR))
298
files = eina_list_append
299
(files, eina_stringshare_add(info->path + info->name_start));
302
eina_iterator_free(it);
305
cd->dirs_count = eina_list_count(files);
306
if (cd->dirs_count > 0)
308
cd->dirs = malloc(cd->dirs_count * sizeof(char *));
309
EINA_LIST_FREE(files, file)
316
eina_hash_add(subdir_cache->dirs, path, cd);
318
subdir_need_save = EINA_TRUE;
323
icon_cache_update_cache_cb(void *data EINA_UNUSED)
325
Eina_Strbuf *file = eina_strbuf_new();
326
if (!file) return EINA_FALSE;
328
icon_cache_timer = NULL;
332
icon_queue = EINA_TRUE;
333
eina_strbuf_free(file);
334
return ECORE_CALLBACK_CANCEL;
336
icon_queue = EINA_FALSE;
337
if ((!icon_flush) && (!icon_exts))
339
eina_strbuf_free(file);
340
return ECORE_CALLBACK_CANCEL;
343
if (icon_change_monitors) eina_hash_free(icon_change_monitors);
344
if (icon_change_monitors_mon) eina_hash_free(icon_change_monitors_mon);
345
icon_change_monitors = eina_hash_string_superfast_new
346
(EINA_FREE_CB(eio_monitor_del));
347
icon_change_monitors_mon = eina_hash_pointer_new(NULL);
348
icon_changes_listen();
352
eina_strbuf_append_printf(file, "%s/efreet/" MODULE_ARCH "/efreet_icon_cache_create",
353
eina_prefix_lib_get(pfx));
359
eina_strbuf_append(file, " -d");
360
EINA_LIST_FOREACH(icon_extra_dirs, ll, p)
362
eina_strbuf_append(file, " ");
363
eina_strbuf_append(file, p);
371
eina_strbuf_append(file, " -e");
372
EINA_LIST_FOREACH(icon_exts, ll, p)
374
eina_strbuf_append(file, " ");
375
eina_strbuf_append(file, p);
379
eina_strbuf_append(file, " -f");
380
icon_flush = EINA_FALSE;
381
fprintf(efreetd_log_file, "[%09.3f] Run:\n %s\n", ecore_time_get(),
382
eina_strbuf_string_get(file));
383
fflush(efreetd_log_file);
384
icon_cache_exe = ecore_exe_pipe_run
385
(eina_strbuf_string_get(file),
386
ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_READ_LINE_BUFFERED,
389
eina_strbuf_free(file);
391
return ECORE_CALLBACK_CANCEL;
395
desktop_cache_update_cache_cb(void *data EINA_UNUSED)
399
desktop_cache_timer = NULL;
401
if (desktop_cache_exe)
403
desktop_queue = EINA_TRUE;
404
return ECORE_CALLBACK_CANCEL;
406
desktop_queue = EINA_FALSE;
407
file = eina_strbuf_new();
409
if (desktop_change_monitors) eina_hash_free(desktop_change_monitors);
410
if (desktop_change_monitors_mon) eina_hash_free(desktop_change_monitors_mon);
411
desktop_change_monitors = eina_hash_string_superfast_new
412
(EINA_FREE_CB(eio_monitor_del));
413
desktop_change_monitors_mon = eina_hash_pointer_new(NULL);
414
desktop_changes_listen();
417
eina_strbuf_append_printf(file, "%s/efreet/" MODULE_ARCH "/efreet_desktop_cache_create",
418
eina_prefix_lib_get(pfx));
419
if (desktop_extra_dirs)
424
eina_strbuf_append(file, " -d");
425
EINA_LIST_FOREACH(desktop_extra_dirs, ll, str)
427
eina_strbuf_append(file, " ");
428
eina_strbuf_append(file, str);
431
INF("Run desktop cache creation: %s", eina_strbuf_string_get(file));
432
fprintf(efreetd_log_file, "[%09.3f] Run:\n %s\n", ecore_time_get(),
433
eina_strbuf_string_get(file));
434
fflush(efreetd_log_file);
435
desktop_cache_exe = ecore_exe_pipe_run
436
(eina_strbuf_string_get(file),
437
ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_READ_LINE_BUFFERED,
440
eina_strbuf_free(file);
442
return ECORE_CALLBACK_CANCEL;
446
cache_icon_update(Eina_Bool flush)
448
if (icon_cache_timer) ecore_timer_del(icon_cache_timer);
449
if (flush) icon_flush = flush;
450
icon_cache_timer = ecore_timer_add(0.2, icon_cache_update_cache_cb, NULL);
454
cache_desktop_update(void)
456
if (desktop_cache_timer) ecore_timer_del(desktop_cache_timer);
457
desktop_cache_timer = ecore_timer_add(0.2, desktop_cache_update_cache_cb, NULL);
461
_cb_monitor_event(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
463
Eio_Monitor_Event *ev = event;
466
if (eina_hash_find(icon_change_monitors_mon, &(ev->monitor)))
468
cache_icon_update(EINA_FALSE);
471
else if (eina_hash_find(desktop_change_monitors_mon, &(ev->monitor)))
473
cache_desktop_update();
476
else if (eina_hash_find(mime_monitors_mon, &(ev->monitor)))
478
if ((!strcmp("/etc/mime.types", ev->filename)) ||
479
(!strcmp("globs", ecore_file_file_get(ev->filename))))
481
mime_cache_shutdown();
483
if (mime_update_timer) ecore_timer_del(mime_update_timer);
484
mime_update_timer = ecore_timer_add(0.2, mime_update_cache_cb, NULL);
487
return ECORE_CALLBACK_PASS_ON;
491
icon_changes_monitor_add(const struct stat *st, const char *path)
495
const char *monpath = path;
497
if (eina_hash_find(icon_change_monitors, path)) return;
499
if (S_ISLNK(st->st_mode))
501
realp = ecore_file_realpath(path);
506
if (ecore_file_is_dir(monpath))
508
mon = eio_monitor_add(monpath);
511
eina_hash_add(icon_change_monitors, path, mon);
512
eina_hash_add(icon_change_monitors_mon, &mon, mon);
519
desktop_changes_monitor_add(const struct stat *st, const char *path)
523
const char *monpath = path;
525
if (eina_hash_find(desktop_change_monitors, path)) return;
527
if (S_ISLNK(st->st_mode))
529
realp = ecore_file_realpath(path);
534
if (ecore_file_is_dir(monpath))
536
mon = eio_monitor_add(monpath);
539
eina_hash_add(desktop_change_monitors, path, mon);
540
eina_hash_add(desktop_change_monitors_mon, &mon, mon);
547
stat_cmp(const void *a, const void *b)
549
const struct stat *st1 = a;
550
const struct stat *st2 = b;
552
if ((st2->st_dev == st1->st_dev) && (st2->st_ino == st1->st_ino))
558
_check_recurse_monitor_sanity(Eina_Inarray *stack, const char *path, unsigned int stack_limit)
560
const char *home = eina_environment_home_get();
563
if (eina_inarray_count(stack) >= stack_limit)
565
ERR("Recursing too far. Level %i. Stopping at %s\n", stack_limit, path);
569
if ((home) && (!strcmp(home, path)))
571
ERR("Recursively monitor homedir! Ignore.");
578
icon_changes_listen_recursive(Eina_Inarray *stack, const char *path, Eina_Bool base)
580
struct stat *st = eina_mempool_malloc(efreetd_mp_stat, sizeof(struct stat));
583
if (stat(path, st) == -1) return;
584
if (eina_inarray_search(stack, st, stat_cmp) >= 0) return;
585
if (!_check_recurse_monitor_sanity(stack, path, 10)) return;
586
eina_inarray_push(stack, st);
588
if ((!S_ISDIR(st->st_mode)) && (base))
598
if (S_ISDIR(st->st_mode))
601
const Subdir_Cache_Dir *cd = subdir_cache_get(st, path);
602
icon_changes_monitor_add(st, path);
605
Eina_Strbuf *buf = eina_strbuf_new();
607
for (i = 0; i < cd->dirs_count; i++)
610
eina_strbuf_append_printf(buf, "%s/%s", path, cd->dirs[i]);
611
icon_changes_listen_recursive(stack, eina_strbuf_string_get(buf), EINA_FALSE);
612
eina_strbuf_reset(buf);
614
eina_strbuf_free(buf);
617
eina_inarray_pop(stack);
618
eina_mempool_free(efreetd_mp_stat, st);
622
desktop_changes_listen_recursive(Eina_Inarray *stack, const char *path, Eina_Bool base)
624
struct stat *st = eina_mempool_malloc(efreetd_mp_stat, sizeof(struct stat));
627
if (stat(path, st) == -1) return;
628
if (eina_inarray_search(stack, st, stat_cmp) >= 0) return;
629
if (!_check_recurse_monitor_sanity(stack, path, 10)) return;
630
eina_inarray_push(stack, st);
632
if ((!S_ISDIR(st->st_mode)) && (base))
642
if (S_ISDIR(st->st_mode))
645
const Subdir_Cache_Dir *cd = subdir_cache_get(st, path);
646
desktop_changes_monitor_add(st, path);
649
Eina_Strbuf *buf = eina_strbuf_new();
651
for (i = 0; i < cd->dirs_count; i++)
653
eina_strbuf_append_printf(buf, "%s/%s", path, cd->dirs[i]);
654
desktop_changes_listen_recursive(stack, eina_strbuf_string_get(buf), EINA_FALSE);
655
eina_strbuf_reset(buf);
657
eina_strbuf_free(buf);
660
eina_inarray_pop(stack);
661
eina_mempool_free(efreetd_mp_stat, st);
665
icon_changes_listen(void)
671
Eina_Strbuf *buf = eina_strbuf_new();
674
stack = eina_inarray_new(sizeof(struct stat), 16);
677
eina_strbuf_free(buf);
680
icon_changes_listen_recursive(stack, efreet_icon_deprecated_user_dir_get(), EINA_TRUE);
681
eina_inarray_flush(stack);
682
icon_changes_listen_recursive(stack, efreet_icon_user_dir_get(), EINA_TRUE);
683
EINA_LIST_FOREACH(icon_extra_dirs, l, dir)
685
if (!strcmp(dir, "/")) continue;
686
eina_inarray_flush(stack);
687
icon_changes_listen_recursive(stack, dir, EINA_TRUE);
690
xdg_dirs = efreet_data_dirs_get();
691
EINA_LIST_FOREACH(xdg_dirs, l, dir)
693
eina_strbuf_append_printf(buf, "%s/icons", dir);
694
eina_inarray_flush(stack);
695
icon_changes_listen_recursive(stack, eina_strbuf_string_get(buf), EINA_TRUE);
696
eina_strbuf_reset(buf);
700
EINA_LIST_FOREACH(xdg_dirs, l, dir)
702
eina_strbuf_append_printf(buf, "%s/pixmaps", dir);
703
eina_inarray_flush(stack);
704
icon_changes_listen_recursive(stack, eina_strbuf_string_get(buf), EINA_TRUE);
705
eina_strbuf_reset(buf);
708
eina_inarray_flush(stack);
709
icon_changes_listen_recursive(stack, "/usr/local/share/pixmaps", EINA_TRUE);
710
icon_changes_listen_recursive(stack, "/usr/share/pixmaps", EINA_TRUE);
711
eina_inarray_free(stack);
712
eina_strbuf_free(buf);
716
desktop_changes_listen(void)
722
stack = eina_inarray_new(sizeof(struct stat), 16);
724
EINA_LIST_FOREACH(desktop_system_dirs, l, path)
726
eina_inarray_flush(stack);
727
desktop_changes_listen_recursive(stack, path, EINA_TRUE);
729
EINA_LIST_FOREACH(desktop_extra_dirs, l, path)
731
eina_inarray_flush(stack);
732
desktop_changes_listen_recursive(stack, path, EINA_TRUE);
734
eina_inarray_free(stack);
738
fill_list(const char *file, Eina_List **l)
741
Eina_Iterator *it = NULL;
742
Eina_File_Line *line = NULL;
743
Eina_Strbuf *buf = eina_strbuf_new();
746
eina_strbuf_append_printf(buf, "%s/efreet/%s", efreet_cache_home_get(), file);
747
f = eina_file_open(eina_strbuf_string_get(buf), EINA_FALSE);
748
if (!f) goto error_buf;
749
it = eina_file_map_lines(f);
751
EINA_ITERATOR_FOREACH(it, line)
753
if (line->end > line->start)
755
const char *s = eina_stringshare_add_length(line->start, line->end - line->start);
756
if (s) *l = eina_list_append(*l, s);
759
eina_iterator_free(it);
763
eina_strbuf_free(buf);
772
fill_list("extra_icons.dirs", &icon_extra_dirs);
773
fill_list("icons.exts", &icon_exts);
777
save_list(const char *file, Eina_List *l)
782
Eina_Strbuf *buf = eina_strbuf_new();
785
eina_strbuf_append_printf(buf, "%s/efreet/%s", efreet_cache_home_get(), file);
786
f = fopen(eina_strbuf_string_get(buf), "wb");
789
eina_strbuf_free(buf);
792
EINA_LIST_FOREACH(l, ll, path)
793
fprintf(f, "%s\n", path);
795
eina_strbuf_free(buf);
799
strcmplen(const void *data1, const void *data2)
801
return strncmp(data1, data2, eina_stringshare_strlen(data1));
805
cache_exe_data_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
807
Ecore_Exe_Event_Data *ev = event;
809
if (ev->exe == desktop_cache_exe)
811
Eina_Bool update = EINA_FALSE;
813
fprintf(efreetd_log_file, "[%09.3f] Data desktop_cache_create\n", ecore_time_get());
814
fflush(efreetd_log_file);
815
if ((ev->lines) && (*ev->lines->line == 'c')) update = EINA_TRUE;
817
send_signal_desktop_cache_build();
818
desktop_exists = EINA_TRUE;
819
send_signal_desktop_cache_update(update);
821
else if (ev->exe == icon_cache_exe)
823
Eina_Bool update = EINA_FALSE;
825
fprintf(efreetd_log_file, "[%09.3f] Data icon_cache_create\n", ecore_time_get());
826
fflush(efreetd_log_file);
827
if ((ev->lines) && (*ev->lines->line == 'c')) update = EINA_TRUE;
828
send_signal_icon_cache_update(update);
830
else if (ev->exe == mime_cache_exe)
832
fprintf(efreetd_log_file, "[%09.3f] Data mime_cache_create\n", ecore_time_get());
833
fflush(efreetd_log_file);
836
return ECORE_CALLBACK_RENEW;
840
cache_exe_del_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
842
Ecore_Exe_Event_Del *ev = event;
844
if (ev->exe == desktop_cache_exe)
846
fprintf(efreetd_log_file, "[%09.3f] Exit desktop_cache_create\n", ecore_time_get());
847
fflush(efreetd_log_file);
848
desktop_cache_exe = NULL;
849
if (desktop_queue) cache_desktop_update();
851
else if (ev->exe == icon_cache_exe)
853
fprintf(efreetd_log_file, "[%09.3f] Exit icon_cache_create\n", ecore_time_get());
854
fflush(efreetd_log_file);
855
icon_cache_exe = NULL;
856
if (icon_queue) cache_icon_update(EINA_FALSE);
858
else if (ev->exe == mime_cache_exe)
860
fprintf(efreetd_log_file, "[%09.3f] Exit mime_cache_create\n", ecore_time_get());
861
fflush(efreetd_log_file);
862
mime_cache_exe = NULL;
863
send_signal_mime_cache_build();
865
return ECORE_CALLBACK_RENEW;
870
cache_desktop_dir_add(const char *dir)
875
san = eina_file_path_sanitize(dir);
877
if ((l = eina_list_search_unsorted_list(desktop_system_dirs, strcmplen, san)))
880
const char *path = eina_list_data_get(l);
881
if (!eina_hash_find(desktop_change_monitors, path))
882
cache_desktop_update();
884
else if (!eina_list_search_unsorted_list(desktop_extra_dirs, EINA_COMPARE_CB(strcmp), san))
887
desktop_extra_dirs = eina_list_append(desktop_extra_dirs, eina_stringshare_add(san));
888
save_list("extra_desktops.dirs", desktop_extra_dirs);
889
cache_desktop_update();
895
cache_icon_dir_add(const char *dir)
899
san = eina_file_path_sanitize(dir);
901
if (!eina_list_search_unsorted_list(icon_extra_dirs, EINA_COMPARE_CB(strcmp), san))
903
if (!strcmp(san, "/")) goto out;
904
icon_extra_dirs = eina_list_append(icon_extra_dirs, eina_stringshare_add(san));
905
save_list("extra_icons.dirs", icon_extra_dirs);
906
cache_icon_update(EINA_TRUE);
913
cache_icon_ext_add(const char *ext)
915
if (!eina_list_search_unsorted_list(icon_exts, EINA_COMPARE_CB(strcmp), ext))
917
icon_exts = eina_list_append(icon_exts, eina_stringshare_add(ext));
918
save_list("icons.exts", icon_exts);
919
cache_icon_update(EINA_TRUE);
924
cache_desktop_exists(void)
926
return desktop_exists;
930
mime_update_launch(void)
932
Eina_Strbuf *file = eina_strbuf_new();
935
eina_strbuf_append_printf(file,
936
"%s/efreet/" MODULE_ARCH "/efreet_mime_cache_create",
937
eina_prefix_lib_get(pfx));
938
mime_cache_exe = ecore_exe_pipe_run(eina_strbuf_string_get(file),
939
ECORE_EXE_PIPE_READ |
940
ECORE_EXE_PIPE_READ_LINE_BUFFERED,
942
eina_strbuf_free(file);
946
mime_update_cache_cb(void *data EINA_UNUSED)
948
mime_update_timer = NULL;
951
ecore_exe_kill(mime_cache_exe);
952
ecore_exe_free(mime_cache_exe);
954
mime_update_launch();
962
Eina_List *datadirs, *l;
964
Eina_Strbuf *buf = eina_strbuf_new();
967
mime_monitors = eina_hash_string_superfast_new
968
(EINA_FREE_CB(eio_monitor_del));
969
mime_monitors_mon = eina_hash_pointer_new(NULL);
971
if (ecore_file_is_dir("/etc"))
973
mon = eio_monitor_add("/etc");
976
eina_hash_add(mime_monitors, "/etc", mon);
977
eina_hash_add(mime_monitors_mon, &mon, mon);
980
if (ecore_file_is_dir("/usr/share/mime"))
982
mon = eio_monitor_add("/usr/share/mime");
985
eina_hash_add(mime_monitors, "/usr/share/mime", mon);
986
eina_hash_add(mime_monitors_mon, &mon, mon);
990
datadirs = efreet_data_dirs_get();
991
EINA_LIST_FOREACH(datadirs, l, s)
993
eina_strbuf_append_printf(buf, "%s/mime", s);
994
if (ecore_file_is_dir(eina_strbuf_string_get(buf)))
996
if (!eina_hash_find(mime_monitors, eina_strbuf_string_get(buf)))
998
mon = eio_monitor_add(eina_strbuf_string_get(buf));
1001
eina_hash_add(mime_monitors, eina_strbuf_string_get(buf), mon);
1002
eina_hash_add(mime_monitors_mon, &mon, mon);
1007
eina_strbuf_free(buf);
1011
mime_cache_shutdown(void)
1013
if (mime_update_timer)
1015
ecore_timer_del(mime_update_timer);
1016
mime_update_timer = NULL;
1020
eina_hash_free(mime_monitors);
1021
mime_monitors = NULL;
1023
if (mime_monitors_mon)
1025
eina_hash_free(mime_monitors_mon);
1026
mime_monitors_mon = NULL;
1035
ecore_app_args_get(NULL, &argv);
1037
pfx = eina_prefix_new(argv[0], cache_init,
1038
"EFREET", "efreet", "checkme",
1044
cache_exe_del_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
1045
cache_exe_del_cb, NULL);
1046
if (!cache_exe_del_handler)
1048
ERR("Failed to add exe del handler");
1051
cache_exe_data_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DATA,
1052
cache_exe_data_cb, NULL);
1053
if (!cache_exe_data_handler)
1055
ERR("Failed to add exe data handler");
1059
icon_change_monitors = eina_hash_string_superfast_new
1060
(EINA_FREE_CB(eio_monitor_del));
1061
icon_change_monitors_mon = eina_hash_pointer_new(NULL);
1062
desktop_change_monitors = eina_hash_string_superfast_new
1063
(EINA_FREE_CB(eio_monitor_del));
1064
desktop_change_monitors_mon = eina_hash_pointer_new(NULL);
1066
efreet_cache_update = 0;
1067
if (!efreet_init()) goto error;
1070
#define MONITOR_EVENT(ev, fn) \
1071
_handlers = eina_list_append(_handlers, ecore_event_handler_add(ev, fn, NULL))
1072
MONITOR_EVENT(EIO_MONITOR_FILE_CREATED, _cb_monitor_event);
1073
MONITOR_EVENT(EIO_MONITOR_FILE_DELETED, _cb_monitor_event);
1074
MONITOR_EVENT(EIO_MONITOR_FILE_MODIFIED, _cb_monitor_event);
1075
MONITOR_EVENT(EIO_MONITOR_DIRECTORY_CREATED, _cb_monitor_event);
1076
MONITOR_EVENT(EIO_MONITOR_DIRECTORY_DELETED, _cb_monitor_event);
1077
MONITOR_EVENT(EIO_MONITOR_DIRECTORY_MODIFIED, _cb_monitor_event);
1078
MONITOR_EVENT(EIO_MONITOR_SELF_RENAME, _cb_monitor_event);
1079
MONITOR_EVENT(EIO_MONITOR_SELF_DELETED, _cb_monitor_event);
1081
subdir_cache_init();
1083
mime_update_launch();
1086
desktop_system_dirs = efreet_default_dirs_get(efreet_data_home_get(),
1087
efreet_data_dirs_get(), "applications");
1088
desktop_system_dirs =
1090
desktop_system_dirs, efreet_default_dirs_get(efreet_data_home_get(),
1091
efreet_data_dirs_get(), "desktop-directories"));
1092
icon_changes_listen();
1093
desktop_changes_listen();
1094
cache_icon_update(EINA_FALSE);
1095
cache_desktop_update();
1096
subdir_cache_save();
1100
if (cache_exe_del_handler) ecore_event_handler_del(cache_exe_del_handler);
1101
cache_exe_del_handler = NULL;
1102
if (cache_exe_data_handler) ecore_event_handler_del(cache_exe_data_handler);
1103
cache_exe_data_handler = NULL;
1111
Ecore_Event_Handler *handler;
1113
eina_prefix_free(pfx);
1116
mime_cache_shutdown();
1117
subdir_cache_shutdown();
1120
if (cache_exe_del_handler) ecore_event_handler_del(cache_exe_del_handler);
1121
cache_exe_del_handler = NULL;
1122
if (cache_exe_data_handler) ecore_event_handler_del(cache_exe_data_handler);
1123
cache_exe_data_handler = NULL;
1125
if (icon_change_monitors) eina_hash_free(icon_change_monitors);
1126
icon_change_monitors = NULL;
1127
if (icon_change_monitors_mon) eina_hash_free(icon_change_monitors_mon);
1128
icon_change_monitors_mon = NULL;
1129
if (desktop_change_monitors) eina_hash_free(desktop_change_monitors);
1130
desktop_change_monitors = NULL;
1131
if (desktop_change_monitors_mon) eina_hash_free(desktop_change_monitors_mon);
1132
desktop_change_monitors_mon = NULL;
1133
EINA_LIST_FREE(desktop_system_dirs, data)
1134
eina_stringshare_del(data);
1135
EINA_LIST_FREE(desktop_extra_dirs, data)
1136
eina_stringshare_del(data);
1137
EINA_LIST_FREE(icon_extra_dirs, data)
1138
eina_stringshare_del(data);
1139
EINA_LIST_FREE(icon_exts, data)
1140
eina_stringshare_del(data);
1141
EINA_LIST_FREE(_handlers, handler)
1142
ecore_event_handler_del(handler);