efreetd - cache - add more statinfo work around 0 mtime distros
some distros 9notably in this case nixos) want to do reproducible
builds. to them this means going around setting mtime for all files to
0. this means efreetd not only thinks mtime is invalid/stupid (0 is
generally just that as midnight on jan 1 1970 is not exactly a
sensible dare for a modified timestamp of a file as no filesystem with
any sanity will have not been modified since that time), but it keeps
mtime at 0 even when things update. this totally breaks efreetd that
expects to find mtime increases over time as things change. it's
necessary because it has to perform a "are mu caches up to date" scan
of all file data it caches and it needs to know if it should rebuild
something based on this.
so this does a few things:
1. it makes mtime have to be an exact match to the cache, not cache
mtime >= file mtime. so any change forward or back is an inavlidation.
2. it now also uses ctime, mode, size, uid, gid, block count and if a
symlink, the sha1 of the symlink path in addition and any change to
these == invalid.
this adds a lot of code and changes how dirs get scanned a bit but it
means it can pick up changes on these 0 mtime distros.
interestingly the policy of mtime being 0 is to have a reprodcible fs
... but ctime still changes and is > 0, as does inode info, so it's
not actually possible to have it totally work... but they try still,
so this is a fix for that problem.
whilst i was doing thisi also noticed efreetd re-red dirs many times
due to icon theme inhritance. i also fixed that to do a LOT less
syscalls by only scanning a dir once as i was rejigging the scanning
code at the time anyway. this should optimize thr scan costs at
efreetd startup too.
@fix
@opt
2020-06-18 03:03:02 -07:00
|
|
|
|
2010-11-15 13:07:22 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2011-02-01 13:03:40 -08:00
|
|
|
/* TODO: Consider flushing local icons cache after idling.
|
|
|
|
* Icon requests will probably come in batches, f.ex. during menu
|
|
|
|
* browsing.
|
|
|
|
*/
|
2011-01-31 03:44:56 -08:00
|
|
|
|
2011-02-10 06:25:23 -08:00
|
|
|
#include <libgen.h>
|
2010-11-22 06:16:09 -08:00
|
|
|
#include <unistd.h>
|
2010-11-23 18:40:54 -08:00
|
|
|
#include <sys/stat.h>
|
2011-08-18 00:35:48 -07:00
|
|
|
#include <fcntl.h>
|
2010-11-22 06:16:09 -08:00
|
|
|
|
2010-11-26 09:05:16 -08:00
|
|
|
#include <Eet.h>
|
|
|
|
#include <Ecore.h>
|
2010-11-25 15:52:57 -08:00
|
|
|
#include <Ecore_File.h>
|
2015-06-24 03:24:21 -07:00
|
|
|
#include <Ecore_Ipc.h>
|
2018-07-03 09:49:08 -07:00
|
|
|
#include <Ecore_Con.h>
|
2010-11-25 15:52:57 -08:00
|
|
|
|
2011-02-05 11:05:55 -08:00
|
|
|
/* define macros and variable for using the eina logging system */
|
|
|
|
#define EFREET_MODULE_LOG_DOM _efreet_cache_log_dom
|
|
|
|
static int _efreet_cache_log_dom = -1;
|
|
|
|
|
2010-11-15 13:07:22 -08:00
|
|
|
#include "Efreet.h"
|
|
|
|
#include "efreet_private.h"
|
2010-11-27 12:15:00 -08:00
|
|
|
#include "efreet_cache_private.h"
|
2018-07-10 08:41:25 -07:00
|
|
|
#include "../../static_libs/buildsystem/buildsystem.h"
|
2011-02-10 06:34:03 -08:00
|
|
|
#define NON_EXISTING (void *)-1
|
|
|
|
|
2010-11-23 12:14:13 -08:00
|
|
|
typedef struct _Efreet_Old_Cache Efreet_Old_Cache;
|
|
|
|
|
|
|
|
struct _Efreet_Old_Cache
|
|
|
|
{
|
|
|
|
Eina_Hash *hash;
|
|
|
|
Eet_File *ef;
|
|
|
|
};
|
|
|
|
|
2015-06-24 03:24:21 -07:00
|
|
|
static Ecore_Ipc_Server *ipc = NULL;
|
|
|
|
static Ecore_Event_Handler *hnd_add = NULL;
|
|
|
|
static Ecore_Event_Handler *hnd_del = NULL;
|
|
|
|
static Ecore_Event_Handler *hnd_data = NULL;
|
2013-06-20 02:52:43 -07:00
|
|
|
|
|
|
|
static Eina_Lock _lock;
|
|
|
|
|
2010-11-15 13:07:22 -08:00
|
|
|
/**
|
|
|
|
* Data for cache files
|
|
|
|
*/
|
2010-11-29 05:17:33 -08:00
|
|
|
static Eet_Data_Descriptor *directory_edd = NULL;
|
2010-12-08 13:39:43 -08:00
|
|
|
static Eet_Data_Descriptor *icon_theme_edd = NULL;
|
|
|
|
static Eet_Data_Descriptor *icon_theme_directory_edd = NULL;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-12-08 13:39:43 -08:00
|
|
|
static Eet_Data_Descriptor *icon_fallback_edd = NULL;
|
|
|
|
static Eet_Data_Descriptor *icon_element_pointer_edd = NULL;
|
|
|
|
static Eet_Data_Descriptor *icon_element_edd = NULL;
|
|
|
|
static Eet_Data_Descriptor *icon_edd = NULL;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-12-03 01:55:36 -08:00
|
|
|
static Eet_File *icon_cache = NULL;
|
2011-01-31 03:44:56 -08:00
|
|
|
static Eet_File *fallback_cache = NULL;
|
2010-12-09 00:56:56 -08:00
|
|
|
static Eet_File *icon_theme_cache = NULL;
|
2010-11-15 13:07:22 -08:00
|
|
|
|
2011-02-09 09:09:16 -08:00
|
|
|
static Eina_Hash *themes = NULL;
|
2011-02-01 13:03:40 -08:00
|
|
|
static Eina_Hash *icons = NULL;
|
|
|
|
static Eina_Hash *fallbacks = NULL;
|
|
|
|
|
2010-12-08 13:39:43 -08:00
|
|
|
static const char *icon_theme_cache_file = NULL;
|
|
|
|
|
2010-11-26 06:56:23 -08:00
|
|
|
static const char *theme_name = NULL;
|
2010-11-22 06:16:09 -08:00
|
|
|
|
2010-12-03 01:55:36 -08:00
|
|
|
static Eet_Data_Descriptor *version_edd = NULL;
|
2010-11-23 12:14:13 -08:00
|
|
|
static Eet_Data_Descriptor *desktop_edd = NULL;
|
2014-09-24 23:47:18 -07:00
|
|
|
static Eet_Data_Descriptor *desktop_action_edd = NULL;
|
2011-01-31 03:32:34 -08:00
|
|
|
static Eet_Data_Descriptor *hash_array_string_edd = NULL;
|
|
|
|
static Eet_Data_Descriptor *array_string_edd = NULL;
|
|
|
|
static Eet_Data_Descriptor *hash_string_edd = NULL;
|
2010-11-23 12:14:13 -08:00
|
|
|
|
2011-02-10 06:25:44 -08:00
|
|
|
static Eina_Hash *desktops = NULL;
|
2010-11-23 12:14:13 -08:00
|
|
|
static Eet_File *desktop_cache = NULL;
|
|
|
|
static const char *desktop_cache_file = NULL;
|
2010-11-22 06:16:09 -08:00
|
|
|
|
2010-11-23 12:14:13 -08:00
|
|
|
static Eina_List *old_desktop_caches = NULL;
|
2010-11-16 13:50:53 -08:00
|
|
|
|
2011-02-10 06:24:40 -08:00
|
|
|
static const char *util_cache_file = NULL;
|
|
|
|
static Eet_File *util_cache = NULL;
|
|
|
|
static Efreet_Cache_Hash *util_cache_hash = NULL;
|
|
|
|
static const char *util_cache_hash_key = NULL;
|
|
|
|
static Efreet_Cache_Array_String *util_cache_names = NULL;
|
|
|
|
static const char *util_cache_names_key = NULL;
|
|
|
|
|
2010-12-02 00:32:59 -08:00
|
|
|
static void efreet_cache_edd_shutdown(void);
|
2011-02-01 13:03:40 -08:00
|
|
|
static void efreet_cache_icon_free(Efreet_Cache_Icon *icon);
|
|
|
|
static void efreet_cache_icon_fallback_free(Efreet_Cache_Fallback_Icon *icon);
|
2011-02-10 06:24:09 -08:00
|
|
|
static void efreet_cache_icon_theme_free(Efreet_Icon_Theme *theme);
|
2010-11-22 06:16:48 -08:00
|
|
|
|
2011-02-10 06:24:40 -08:00
|
|
|
static Eina_Bool efreet_cache_check(Eet_File **ef, const char *path, int major);
|
|
|
|
static void *efreet_cache_close(Eet_File *ef);
|
|
|
|
|
2010-12-11 12:37:17 -08:00
|
|
|
static void icon_cache_update_free(void *data, void *ev);
|
2010-11-23 12:14:13 -08:00
|
|
|
|
2011-02-09 09:09:38 -08:00
|
|
|
static void *hash_array_string_add(void *hash, const char *key, void *data);
|
|
|
|
|
2018-04-27 05:35:13 -07:00
|
|
|
static Eina_Bool disable_cache;
|
2018-07-05 14:26:42 -07:00
|
|
|
static Eina_Bool run_in_tree;
|
2020-04-09 16:15:30 -07:00
|
|
|
static int relaunch_try = 0;
|
2018-04-27 05:35:13 -07:00
|
|
|
|
2010-11-22 06:16:09 -08:00
|
|
|
EAPI int EFREET_EVENT_ICON_CACHE_UPDATE = 0;
|
2010-11-23 12:14:13 -08:00
|
|
|
EAPI int EFREET_EVENT_DESKTOP_CACHE_UPDATE = 0;
|
2011-08-18 00:34:19 -07:00
|
|
|
EAPI int EFREET_EVENT_DESKTOP_CACHE_BUILD = 0;
|
2010-11-15 13:07:22 -08:00
|
|
|
|
2015-06-24 03:24:21 -07:00
|
|
|
#define IPC_HEAD(_type) \
|
|
|
|
Ecore_Ipc_Event_Server_##_type *e = event; \
|
|
|
|
if (e->server != ipc) \
|
|
|
|
return ECORE_CALLBACK_PASS_ON
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ipc_launch(void)
|
|
|
|
{
|
|
|
|
char buf[PATH_MAX];
|
2019-08-25 03:24:54 -07:00
|
|
|
int num;
|
|
|
|
int try_gap = 10000; // 10ms
|
2020-01-15 11:23:44 -08:00
|
|
|
int tries = 1000; // 1000 * 10ms == 10sec
|
2019-08-25 03:24:54 -07:00
|
|
|
const char *s;
|
2015-06-24 03:24:21 -07:00
|
|
|
|
2020-04-09 16:15:30 -07:00
|
|
|
if (relaunch_try == 0)
|
|
|
|
{
|
|
|
|
ipc = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, "efreetd", 0, NULL);
|
|
|
|
if (ipc)
|
|
|
|
{
|
|
|
|
relaunch_try++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
relaunch_try--;
|
2019-08-25 03:24:54 -07:00
|
|
|
s = getenv("EFREETD_CONNECT_TRIES");
|
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
num = atoi(s);
|
|
|
|
if (num >= 0) tries = num;
|
|
|
|
}
|
|
|
|
s = getenv("EFREETD_CONNECT_TRY_GAP");
|
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
num = atoi(s);
|
|
|
|
if (num >= 0) try_gap = num;
|
|
|
|
}
|
2018-07-05 14:26:42 -07:00
|
|
|
if (run_in_tree)
|
|
|
|
bs_binary_get(buf, sizeof(buf), "efreet", "efreetd");
|
|
|
|
else
|
|
|
|
snprintf(buf, sizeof(buf), PACKAGE_BIN_DIR "/efreetd");
|
2015-06-24 03:24:21 -07:00
|
|
|
ecore_exe_run(buf, NULL);
|
2019-08-25 03:24:54 -07:00
|
|
|
num = 0;
|
|
|
|
while ((!ipc) && (num < tries))
|
2015-06-24 03:24:21 -07:00
|
|
|
{
|
|
|
|
num++;
|
2019-08-25 03:24:54 -07:00
|
|
|
usleep(try_gap);
|
2015-06-24 03:24:21 -07:00
|
|
|
ipc = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, "efreetd", 0, NULL);
|
|
|
|
}
|
efreet: fix typo
Summary: efreet: fix typo
Test Plan: None
Reviewers: cedric, raster, lauromoura, devilhorns, marcelhollerbach, segfaultxavi, zmike, vtorri
Reviewed By: segfaultxavi, vtorri
Subscribers: cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D10676
2019-11-15 03:54:55 -08:00
|
|
|
if (!ipc) ERR("Timeout in trying to start and then connect to efreetd");
|
2015-06-24 03:24:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_cb_server_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
IPC_HEAD(Add);
|
2020-04-09 16:15:30 -07:00
|
|
|
relaunch_try--;
|
2015-06-24 03:24:21 -07:00
|
|
|
return ECORE_CALLBACK_DONE;
|
|
|
|
}
|
|
|
|
|
2016-12-25 20:06:35 -08:00
|
|
|
static Ecore_Timer *reconnect_timer = NULL;
|
2017-03-17 10:16:53 -07:00
|
|
|
static unsigned int reconnect_count = 0;
|
2016-12-25 20:06:35 -08:00
|
|
|
|
2015-06-24 03:24:21 -07:00
|
|
|
static Eina_Bool
|
2016-12-25 20:06:35 -08:00
|
|
|
_cb_server_reconnect(void *data EINA_UNUSED)
|
2015-06-24 03:24:21 -07:00
|
|
|
{
|
2016-12-25 20:06:35 -08:00
|
|
|
if (reconnect_timer) ecore_timer_del(reconnect_timer);
|
|
|
|
reconnect_timer = NULL;
|
2017-03-17 10:16:53 -07:00
|
|
|
reconnect_count++;
|
2015-06-24 03:24:21 -07:00
|
|
|
_ipc_launch();
|
2015-06-24 19:41:15 -07:00
|
|
|
if (ipc)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
int len = 0;
|
|
|
|
|
|
|
|
s = efreet_language_get();
|
|
|
|
if (s) len = strlen(s);
|
|
|
|
ecore_ipc_server_send(ipc, 1, 0, 0, 0, 0, s, len);
|
2015-08-10 20:56:02 -07:00
|
|
|
efreet_icon_extensions_refresh();
|
2015-06-24 19:41:15 -07:00
|
|
|
}
|
2016-12-25 20:06:35 -08:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_cb_server_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
double t;
|
|
|
|
IPC_HEAD(Del);
|
|
|
|
ipc = NULL;
|
2018-04-27 05:35:13 -07:00
|
|
|
|
|
|
|
if (disable_cache) return ECORE_CALLBACK_RENEW;
|
2017-03-17 10:16:53 -07:00
|
|
|
if (reconnect_count > 10)
|
|
|
|
{
|
2018-07-03 09:49:08 -07:00
|
|
|
char *address = ecore_con_local_path_new(EINA_FALSE, "efreetd", 0);
|
2017-03-17 10:16:53 -07:00
|
|
|
reconnect_timer = NULL;
|
2018-07-03 09:49:08 -07:00
|
|
|
ERR("efreetd connection failed 10 times! check for stale socket file at %s", address);
|
|
|
|
free(address);
|
2017-03-17 10:16:53 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2020-04-09 12:45:57 -07:00
|
|
|
// random 0.5 -> 1.0 sec from now
|
|
|
|
t = (((double)((rand() + (int)getpid()) & 0xff) / 255.0) * 0.5) + 0.5;
|
|
|
|
if (reconnect_timer) ecore_timer_del(reconnect_timer);
|
|
|
|
reconnect_timer = ecore_timer_add(t, _cb_server_reconnect, NULL);
|
2015-06-24 03:24:21 -07:00
|
|
|
return ECORE_CALLBACK_DONE;
|
|
|
|
}
|
|
|
|
|
2018-02-02 13:59:56 -08:00
|
|
|
static void
|
|
|
|
_efreet_cache_reset()
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
int len = 0;
|
|
|
|
|
|
|
|
if (ipc) ecore_ipc_server_del(ipc);
|
2018-04-27 05:35:13 -07:00
|
|
|
ipc = NULL;
|
|
|
|
if (!disable_cache)
|
|
|
|
ipc = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, "efreetd", 0, NULL);
|
2018-02-02 13:59:56 -08:00
|
|
|
if (!ipc) return;
|
|
|
|
|
|
|
|
s = efreet_language_get();
|
|
|
|
if (s) len = strlen(s);
|
|
|
|
ecore_ipc_server_send(ipc, 1, 0, 0, 0, 0, s, len);
|
|
|
|
efreet_icon_extensions_refresh();
|
|
|
|
}
|
|
|
|
|
2015-08-10 20:56:02 -07:00
|
|
|
static void
|
|
|
|
_icon_desktop_cache_update_event_add(int event_type)
|
|
|
|
{
|
|
|
|
Efreet_Event_Cache_Update *ev;
|
|
|
|
Efreet_Old_Cache *d = NULL;
|
|
|
|
Eina_List *l = NULL;
|
|
|
|
|
|
|
|
efreet_cache_desktop_close();
|
|
|
|
|
|
|
|
ev = NEW(Efreet_Event_Cache_Update, 1);
|
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
IF_RELEASE(theme_name);
|
|
|
|
|
|
|
|
// Save all old caches
|
|
|
|
d = NEW(Efreet_Old_Cache, 1);
|
|
|
|
if (d)
|
|
|
|
{
|
|
|
|
d->hash = themes;
|
|
|
|
d->ef = icon_theme_cache;
|
|
|
|
l = eina_list_append(l, d);
|
|
|
|
}
|
|
|
|
|
|
|
|
d = NEW(Efreet_Old_Cache, 1);
|
|
|
|
if (d)
|
|
|
|
{
|
|
|
|
d->hash = icons;
|
|
|
|
d->ef = icon_cache;
|
|
|
|
l = eina_list_append(l, d);
|
|
|
|
}
|
|
|
|
|
|
|
|
d = NEW(Efreet_Old_Cache, 1);
|
|
|
|
if (d)
|
|
|
|
{
|
|
|
|
d->hash = fallbacks;
|
|
|
|
d->ef = fallback_cache;
|
|
|
|
l = eina_list_append(l, d);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create new empty caches
|
|
|
|
themes = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_theme_free));
|
|
|
|
icons = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_free));
|
|
|
|
fallbacks = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_fallback_free));
|
|
|
|
|
|
|
|
icon_theme_cache = NULL;
|
|
|
|
icon_cache = NULL;
|
|
|
|
fallback_cache = NULL;
|
|
|
|
|
|
|
|
// Send event
|
|
|
|
ecore_event_add(event_type, ev, icon_cache_update_free, l);
|
|
|
|
}
|
|
|
|
|
2016-08-22 19:59:37 -07:00
|
|
|
EAPI void (*_efreet_mime_update_func) (void) = NULL;
|
|
|
|
|
2015-06-24 03:24:21 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
IPC_HEAD(Data);
|
|
|
|
if (e->major == 1) // registration
|
|
|
|
{
|
|
|
|
if (e->minor == 1)
|
|
|
|
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_BUILD, NULL, NULL, NULL);
|
|
|
|
}
|
|
|
|
else if (e->major == 2) // icon cache update
|
|
|
|
{
|
|
|
|
if (e->minor == 1)
|
2015-08-10 20:56:02 -07:00
|
|
|
_icon_desktop_cache_update_event_add(EFREET_EVENT_ICON_CACHE_UPDATE);
|
2015-06-24 03:24:21 -07:00
|
|
|
else
|
2015-08-10 20:56:02 -07:00
|
|
|
ecore_event_add(EFREET_EVENT_ICON_CACHE_UPDATE, NULL, NULL, NULL);
|
2015-06-24 03:24:21 -07:00
|
|
|
}
|
|
|
|
else if (e->major == 3) // desktop cache update
|
|
|
|
{
|
2015-08-10 20:56:02 -07:00
|
|
|
_icon_desktop_cache_update_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE);
|
2015-06-24 03:24:21 -07:00
|
|
|
}
|
2016-08-22 19:59:37 -07:00
|
|
|
else if (e->major == 4) // mime cache update
|
|
|
|
{
|
|
|
|
if (_efreet_mime_update_func) _efreet_mime_update_func();
|
|
|
|
}
|
2015-06-24 03:24:21 -07:00
|
|
|
return ECORE_CALLBACK_DONE;
|
|
|
|
}
|
|
|
|
|
2010-11-15 13:07:22 -08:00
|
|
|
int
|
|
|
|
efreet_cache_init(void)
|
|
|
|
{
|
2013-06-21 01:00:20 -07:00
|
|
|
char buf[PATH_MAX];
|
|
|
|
|
2010-11-26 06:56:23 -08:00
|
|
|
_efreet_cache_log_dom = eina_log_domain_register("efreet_cache", EFREET_DEFAULT_LOG_COLOR);
|
|
|
|
if (_efreet_cache_log_dom < 0)
|
|
|
|
return 0;
|
2010-11-22 06:16:09 -08:00
|
|
|
|
2013-06-20 02:52:43 -07:00
|
|
|
if (!eina_lock_new(&_lock))
|
|
|
|
{
|
|
|
|
ERR("Could not create lock");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2013-06-21 01:00:20 -07:00
|
|
|
snprintf(buf, sizeof(buf), "%s/efreet", efreet_cache_home_get());
|
|
|
|
if (!ecore_file_mkpath(buf))
|
|
|
|
{
|
|
|
|
ERR("Failed to create directory '%s'", buf);
|
|
|
|
}
|
|
|
|
|
2018-07-05 14:26:42 -07:00
|
|
|
run_in_tree = !!getenv("EFL_RUN_IN_TREE");
|
|
|
|
|
2017-12-18 18:14:37 -08:00
|
|
|
EFREET_EVENT_ICON_CACHE_UPDATE = ecore_event_type_new();
|
|
|
|
EFREET_EVENT_DESKTOP_CACHE_UPDATE = ecore_event_type_new();
|
|
|
|
EFREET_EVENT_DESKTOP_CACHE_BUILD = ecore_event_type_new();
|
2010-11-22 06:16:09 -08:00
|
|
|
|
2011-02-09 09:09:16 -08:00
|
|
|
themes = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_theme_free));
|
2011-02-01 13:03:40 -08:00
|
|
|
icons = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_free));
|
|
|
|
fallbacks = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_fallback_free));
|
2011-02-10 06:25:44 -08:00
|
|
|
desktops = eina_hash_string_superfast_new(NULL);
|
2011-02-01 13:03:40 -08:00
|
|
|
|
2015-06-24 03:24:21 -07:00
|
|
|
ecore_ipc_init();
|
|
|
|
// XXX: connect to efreetd
|
|
|
|
|
2010-11-22 06:16:09 -08:00
|
|
|
if (efreet_cache_update)
|
|
|
|
{
|
2018-04-27 05:35:13 -07:00
|
|
|
if (disable_cache)
|
|
|
|
ipc = NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ipc = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, "efreetd", 0, NULL);
|
|
|
|
if (!ipc) _ipc_launch();
|
|
|
|
}
|
2015-06-24 03:24:21 -07:00
|
|
|
if (ipc)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
int len = 0;
|
|
|
|
|
|
|
|
hnd_add = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD,
|
|
|
|
_cb_server_add, NULL);
|
|
|
|
hnd_del = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL,
|
|
|
|
_cb_server_del, NULL);
|
|
|
|
hnd_data = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA,
|
|
|
|
_cb_server_data, NULL);
|
|
|
|
s = efreet_language_get();
|
|
|
|
if (s) len = strlen(s);
|
|
|
|
ecore_ipc_server_send(ipc, 1, 0, 0, 0, 0, s, len);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Efreet_Event_Cache_Update *ev;
|
|
|
|
|
2018-04-27 05:35:13 -07:00
|
|
|
if (!disable_cache)
|
|
|
|
WRN("Can't contact efreetd daemon for desktop/icon etc. changes");
|
2015-06-24 03:24:21 -07:00
|
|
|
ev = NEW(Efreet_Event_Cache_Update, 1);
|
|
|
|
if (ev)
|
|
|
|
{
|
|
|
|
ev->error = 1;
|
|
|
|
ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_BUILD, ev, NULL, NULL);
|
|
|
|
}
|
|
|
|
}
|
2010-11-22 06:16:09 -08:00
|
|
|
}
|
2018-02-02 13:59:56 -08:00
|
|
|
ecore_fork_reset_callback_add(_efreet_cache_reset, NULL);
|
2010-11-22 06:16:09 -08:00
|
|
|
|
2010-11-15 13:07:22 -08:00
|
|
|
return 1;
|
2010-11-23 12:14:13 -08:00
|
|
|
error:
|
2011-02-10 06:24:50 -08:00
|
|
|
if (themes) eina_hash_free(themes);
|
|
|
|
themes = NULL;
|
|
|
|
if (icons) eina_hash_free(icons);
|
|
|
|
icons = NULL;
|
|
|
|
if (fallbacks) eina_hash_free(fallbacks);
|
|
|
|
fallbacks = NULL;
|
2011-02-10 06:25:44 -08:00
|
|
|
if (desktops) eina_hash_free(desktops);
|
|
|
|
desktops = NULL;
|
2011-02-10 06:24:50 -08:00
|
|
|
|
2010-12-02 00:32:59 -08:00
|
|
|
efreet_cache_edd_shutdown();
|
2010-11-22 06:16:09 -08:00
|
|
|
return 0;
|
2010-11-15 13:07:22 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
efreet_cache_shutdown(void)
|
|
|
|
{
|
2010-11-23 12:14:13 -08:00
|
|
|
Efreet_Old_Cache *d;
|
|
|
|
|
2017-03-09 16:16:28 -08:00
|
|
|
ecore_event_type_flush(EFREET_EVENT_ICON_CACHE_UPDATE,
|
|
|
|
EFREET_EVENT_DESKTOP_CACHE_UPDATE,
|
|
|
|
EFREET_EVENT_DESKTOP_CACHE_BUILD);
|
2018-02-02 13:59:56 -08:00
|
|
|
ecore_fork_reset_callback_del(_efreet_cache_reset, NULL);
|
2010-12-12 14:17:05 -08:00
|
|
|
IF_RELEASE(theme_name);
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-12-03 01:55:36 -08:00
|
|
|
icon_cache = efreet_cache_close(icon_cache);
|
2010-12-09 00:56:56 -08:00
|
|
|
icon_theme_cache = efreet_cache_close(icon_theme_cache);
|
2016-08-04 08:02:46 -07:00
|
|
|
fallback_cache = efreet_cache_close(fallback_cache);
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-09 09:09:16 -08:00
|
|
|
IF_FREE_HASH(themes);
|
2011-02-01 13:03:40 -08:00
|
|
|
IF_FREE_HASH(icons);
|
|
|
|
IF_FREE_HASH(fallbacks);
|
|
|
|
|
2011-02-10 06:25:44 -08:00
|
|
|
IF_FREE_HASH_CB(desktops, EINA_FREE_CB(efreet_cache_desktop_free));
|
2010-12-02 00:34:07 -08:00
|
|
|
desktop_cache = efreet_cache_close(desktop_cache);
|
2010-11-23 12:14:13 -08:00
|
|
|
IF_RELEASE(desktop_cache_file);
|
2010-11-22 06:16:09 -08:00
|
|
|
|
2010-12-02 00:32:59 -08:00
|
|
|
efreet_cache_edd_shutdown();
|
2010-12-08 13:39:43 -08:00
|
|
|
IF_RELEASE(icon_theme_cache_file);
|
2010-11-23 12:14:13 -08:00
|
|
|
|
2011-08-18 00:34:40 -07:00
|
|
|
if (old_desktop_caches)
|
2011-08-19 21:22:24 -07:00
|
|
|
ERR("This application has not properly closed all its desktop references!");
|
2010-11-23 12:14:13 -08:00
|
|
|
EINA_LIST_FREE(old_desktop_caches, d)
|
|
|
|
{
|
|
|
|
eina_hash_free(d->hash);
|
2011-08-18 00:34:40 -07:00
|
|
|
eet_close(d->ef);
|
2010-11-23 12:14:13 -08:00
|
|
|
free(d);
|
|
|
|
}
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-10 06:24:40 -08:00
|
|
|
IF_RELEASE(util_cache_names_key);
|
|
|
|
efreet_cache_array_string_free(util_cache_names);
|
|
|
|
util_cache_names = NULL;
|
|
|
|
|
|
|
|
IF_RELEASE(util_cache_hash_key);
|
|
|
|
if (util_cache_hash)
|
|
|
|
{
|
|
|
|
eina_hash_free(util_cache_hash->hash);
|
|
|
|
free(util_cache_hash);
|
|
|
|
util_cache_hash = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
util_cache = efreet_cache_close(util_cache);
|
|
|
|
IF_RELEASE(util_cache_file);
|
|
|
|
|
2015-06-24 03:24:21 -07:00
|
|
|
if (ipc) ecore_ipc_server_del(ipc);
|
|
|
|
if (hnd_add) ecore_event_handler_del(hnd_add);
|
|
|
|
if (hnd_del) ecore_event_handler_del(hnd_del);
|
|
|
|
if (hnd_data) ecore_event_handler_del(hnd_data);
|
2016-07-04 04:07:30 -07:00
|
|
|
|
|
|
|
ecore_ipc_shutdown();
|
|
|
|
|
2015-06-24 03:24:21 -07:00
|
|
|
ipc = NULL;
|
|
|
|
hnd_add = NULL;
|
|
|
|
hnd_del = NULL;
|
|
|
|
hnd_data = NULL;
|
2013-04-18 23:41:17 -07:00
|
|
|
|
2013-06-20 02:52:43 -07:00
|
|
|
eina_lock_free(&_lock);
|
|
|
|
|
2013-04-18 23:41:17 -07:00
|
|
|
eina_log_domain_unregister(_efreet_cache_log_dom);
|
|
|
|
_efreet_cache_log_dom = -1;
|
2010-11-15 13:07:22 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI const char *
|
2011-01-31 03:44:56 -08:00
|
|
|
efreet_icon_cache_file(const char *theme)
|
2010-11-15 13:07:22 -08:00
|
|
|
{
|
|
|
|
static char cache_file[PATH_MAX] = { '\0' };
|
2010-12-04 08:02:20 -08:00
|
|
|
const char *cache;
|
2010-11-15 13:07:22 -08:00
|
|
|
|
2012-05-23 13:10:27 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(theme, NULL);
|
|
|
|
|
2010-12-04 08:02:20 -08:00
|
|
|
cache = efreet_cache_home_get();
|
2010-11-15 13:07:22 -08:00
|
|
|
|
2011-01-31 03:44:56 -08:00
|
|
|
snprintf(cache_file, sizeof(cache_file), "%s/efreet/icons_%s_%s.eet", cache, theme, efreet_hostname_get());
|
2010-11-15 13:07:22 -08:00
|
|
|
|
|
|
|
return cache_file;
|
|
|
|
}
|
2010-12-08 13:39:43 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI const char *
|
|
|
|
efreet_icon_theme_cache_file(void)
|
|
|
|
{
|
2010-12-09 05:41:22 -08:00
|
|
|
char tmp[PATH_MAX] = { '\0' };
|
2010-12-08 13:39:43 -08:00
|
|
|
|
|
|
|
if (icon_theme_cache_file) return icon_theme_cache_file;
|
|
|
|
|
2010-12-09 05:41:22 -08:00
|
|
|
snprintf(tmp, sizeof(tmp), "%s/efreet/icon_themes_%s.eet",
|
2010-12-08 13:39:43 -08:00
|
|
|
efreet_cache_home_get(), efreet_hostname_get());
|
|
|
|
icon_theme_cache_file = eina_stringshare_add(tmp);
|
|
|
|
|
|
|
|
return icon_theme_cache_file;
|
|
|
|
}
|
2010-11-15 13:07:22 -08:00
|
|
|
|
2011-02-10 06:24:40 -08:00
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI const char *
|
|
|
|
efreet_desktop_util_cache_file(void)
|
|
|
|
{
|
|
|
|
char tmp[PATH_MAX] = { '\0' };
|
|
|
|
const char *cache_dir, *lang, *country, *modifier;
|
|
|
|
|
|
|
|
if (util_cache_file) return util_cache_file;
|
|
|
|
|
|
|
|
cache_dir = efreet_cache_home_get();
|
|
|
|
lang = efreet_lang_get();
|
|
|
|
country = efreet_lang_country_get();
|
|
|
|
modifier = efreet_lang_modifier_get();
|
|
|
|
|
|
|
|
if (lang && country && modifier)
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s/efreet/desktop_util_%s_%s_%s@%s.eet", cache_dir, efreet_hostname_get(), lang, country, modifier);
|
|
|
|
else if (lang && country)
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s/efreet/desktop_util_%s_%s_%s.eet", cache_dir, efreet_hostname_get(), lang, country);
|
|
|
|
else if (lang)
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s/efreet/desktop_util_%s_%s.eet", cache_dir, efreet_hostname_get(), lang);
|
|
|
|
else
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s/efreet/desktop_util_%s.eet", cache_dir, efreet_hostname_get());
|
|
|
|
|
|
|
|
util_cache_file = eina_stringshare_add(tmp);
|
|
|
|
return util_cache_file;
|
|
|
|
}
|
|
|
|
|
2010-12-02 02:47:34 -08:00
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
efreetd - cache - add more statinfo work around 0 mtime distros
some distros 9notably in this case nixos) want to do reproducible
builds. to them this means going around setting mtime for all files to
0. this means efreetd not only thinks mtime is invalid/stupid (0 is
generally just that as midnight on jan 1 1970 is not exactly a
sensible dare for a modified timestamp of a file as no filesystem with
any sanity will have not been modified since that time), but it keeps
mtime at 0 even when things update. this totally breaks efreetd that
expects to find mtime increases over time as things change. it's
necessary because it has to perform a "are mu caches up to date" scan
of all file data it caches and it needs to know if it should rebuild
something based on this.
so this does a few things:
1. it makes mtime have to be an exact match to the cache, not cache
mtime >= file mtime. so any change forward or back is an inavlidation.
2. it now also uses ctime, mode, size, uid, gid, block count and if a
symlink, the sha1 of the symlink path in addition and any change to
these == invalid.
this adds a lot of code and changes how dirs get scanned a bit but it
means it can pick up changes on these 0 mtime distros.
interestingly the policy of mtime being 0 is to have a reprodcible fs
... but ctime still changes and is > 0, as does inode info, so it's
not actually possible to have it totally work... but they try still,
so this is a fix for that problem.
whilst i was doing thisi also noticed efreetd re-red dirs many times
due to icon theme inhritance. i also fixed that to do a LOT less
syscalls by only scanning a dir once as i was rejigging the scanning
code at the time anyway. this should optimize thr scan costs at
efreetd startup too.
@fix
@opt
2020-06-18 03:03:02 -07:00
|
|
|
#define SHSH(n, v) ((((v) << (n)) & 0xffffffff) | ((v) >> (32 - (n))))
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
int_to_bigendian(int in)
|
|
|
|
{
|
|
|
|
static const unsigned char test[4] = { 0x11, 0x22, 0x33, 0x44 };
|
|
|
|
static const unsigned int *test_i = (const unsigned int *)test;
|
|
|
|
if (test_i[0] == 0x44332211) return eina_swap32(in);
|
|
|
|
return in;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sha1(unsigned char *data, int size, unsigned char *dst)
|
|
|
|
{
|
|
|
|
unsigned int digest[5], word[80], wa, wb, wc, wd, we, t;
|
|
|
|
unsigned char buf[64], *d;
|
|
|
|
int idx, left, i;
|
|
|
|
const unsigned int magic[4] =
|
|
|
|
{ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
|
|
|
|
|
|
|
|
idx = 0;
|
|
|
|
digest[0] = 0x67452301; digest[1] = 0xefcdab89; digest[2] = 0x98badcfe;
|
|
|
|
digest[3] = 0x10325476; digest[4] = 0xc3d2e1f0;
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
for (left = size, d = data; left > 0; left--, d++)
|
|
|
|
{
|
|
|
|
if ((idx == 0) && (left < 64))
|
|
|
|
{
|
|
|
|
memset(buf, 0, 60);
|
|
|
|
buf[60] = (size >> 24) & 0xff;
|
|
|
|
buf[61] = (size >> 16) & 0xff;
|
|
|
|
buf[62] = (size >> 8) & 0xff;
|
|
|
|
buf[63] = (size) & 0xff;
|
|
|
|
}
|
|
|
|
buf[idx] = *d;
|
|
|
|
idx++;
|
|
|
|
if ((idx == 64) || (left == 1))
|
|
|
|
{
|
|
|
|
if ((left == 1) && (idx < 64)) buf[idx] = 0x80;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
|
|
{
|
|
|
|
word[i] = (unsigned int)buf[(i * 4) ] << 24;
|
|
|
|
word[i] |= (unsigned int)buf[(i * 4) + 1] << 16;
|
|
|
|
word[i] |= (unsigned int)buf[(i * 4) + 2] << 8;
|
|
|
|
word[i] |= (unsigned int)buf[(i * 4) + 3];
|
|
|
|
}
|
|
|
|
for (i = 16; i < 80; i++)
|
|
|
|
word[i] = SHSH(1,
|
|
|
|
word[i - 3 ] ^ word[i - 8 ] ^
|
|
|
|
word[i - 14] ^ word[i - 16]);
|
|
|
|
wa = digest[0]; wb = digest[1]; wc = digest[2];
|
|
|
|
wd = digest[3]; we = digest[4];
|
|
|
|
for (i = 0; i < 80; i++)
|
|
|
|
{
|
|
|
|
if (i < 20)
|
|
|
|
t = SHSH(5, wa) + ((wb & wc) | ((~wb) & wd)) +
|
|
|
|
we + word[i] + magic[0];
|
|
|
|
else if (i < 40)
|
|
|
|
t = SHSH(5, wa) + (wb ^ wc ^ wd) +
|
|
|
|
we + word[i] + magic[1];
|
|
|
|
else if (i < 60)
|
|
|
|
t = SHSH(5, wa) + ((wb & wc) | (wb & wd) | (wc & wd)) +
|
|
|
|
we + word[i] + magic[2];
|
|
|
|
else if (i < 80)
|
|
|
|
t = SHSH(5, wa) + (wb ^ wc ^ wd) +
|
|
|
|
we + word[i] + magic[3];
|
|
|
|
we = wd;
|
|
|
|
wd = wc;
|
|
|
|
wc = SHSH(30, wb);
|
|
|
|
wb = wa;
|
|
|
|
wa = t;
|
|
|
|
}
|
|
|
|
digest[0] += wa; digest[1] += wb; digest[2] += wc;
|
|
|
|
digest[3] += wd; digest[4] += we;
|
|
|
|
idx = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
t = int_to_bigendian(digest[0]); digest[0] = t;
|
|
|
|
t = int_to_bigendian(digest[1]); digest[1] = t;
|
|
|
|
t = int_to_bigendian(digest[2]); digest[2] = t;
|
|
|
|
t = int_to_bigendian(digest[3]); digest[3] = t;
|
|
|
|
t = int_to_bigendian(digest[4]); digest[4] = t;
|
|
|
|
memcpy(dst, digest, 5 * 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
efreet_file_cache_fill(const char *file, Efreet_Cache_Check *check)
|
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
|
2020-06-18 03:35:44 -07:00
|
|
|
memset(check, 0, sizeof(Efreet_Cache_Check));
|
2020-09-29 02:30:45 -07:00
|
|
|
#ifdef _WIN32
|
|
|
|
if (stat(file, &st) != 0) return EINA_FALSE;
|
|
|
|
#else
|
|
|
|
ssize_t size = 0;
|
|
|
|
|
efreetd - cache - add more statinfo work around 0 mtime distros
some distros 9notably in this case nixos) want to do reproducible
builds. to them this means going around setting mtime for all files to
0. this means efreetd not only thinks mtime is invalid/stupid (0 is
generally just that as midnight on jan 1 1970 is not exactly a
sensible dare for a modified timestamp of a file as no filesystem with
any sanity will have not been modified since that time), but it keeps
mtime at 0 even when things update. this totally breaks efreetd that
expects to find mtime increases over time as things change. it's
necessary because it has to perform a "are mu caches up to date" scan
of all file data it caches and it needs to know if it should rebuild
something based on this.
so this does a few things:
1. it makes mtime have to be an exact match to the cache, not cache
mtime >= file mtime. so any change forward or back is an inavlidation.
2. it now also uses ctime, mode, size, uid, gid, block count and if a
symlink, the sha1 of the symlink path in addition and any change to
these == invalid.
this adds a lot of code and changes how dirs get scanned a bit but it
means it can pick up changes on these 0 mtime distros.
interestingly the policy of mtime being 0 is to have a reprodcible fs
... but ctime still changes and is > 0, as does inode info, so it's
not actually possible to have it totally work... but they try still,
so this is a fix for that problem.
whilst i was doing thisi also noticed efreetd re-red dirs many times
due to icon theme inhritance. i also fixed that to do a LOT less
syscalls by only scanning a dir once as i was rejigging the scanning
code at the time anyway. this should optimize thr scan costs at
efreetd startup too.
@fix
@opt
2020-06-18 03:03:02 -07:00
|
|
|
if (lstat(file, &st) != 0) return EINA_FALSE;
|
|
|
|
if (S_ISLNK(st.st_mode))
|
|
|
|
{
|
2020-09-29 02:30:45 -07:00
|
|
|
char link[PATH_MAX];
|
|
|
|
|
efreetd - cache - add more statinfo work around 0 mtime distros
some distros 9notably in this case nixos) want to do reproducible
builds. to them this means going around setting mtime for all files to
0. this means efreetd not only thinks mtime is invalid/stupid (0 is
generally just that as midnight on jan 1 1970 is not exactly a
sensible dare for a modified timestamp of a file as no filesystem with
any sanity will have not been modified since that time), but it keeps
mtime at 0 even when things update. this totally breaks efreetd that
expects to find mtime increases over time as things change. it's
necessary because it has to perform a "are mu caches up to date" scan
of all file data it caches and it needs to know if it should rebuild
something based on this.
so this does a few things:
1. it makes mtime have to be an exact match to the cache, not cache
mtime >= file mtime. so any change forward or back is an inavlidation.
2. it now also uses ctime, mode, size, uid, gid, block count and if a
symlink, the sha1 of the symlink path in addition and any change to
these == invalid.
this adds a lot of code and changes how dirs get scanned a bit but it
means it can pick up changes on these 0 mtime distros.
interestingly the policy of mtime being 0 is to have a reprodcible fs
... but ctime still changes and is > 0, as does inode info, so it's
not actually possible to have it totally work... but they try still,
so this is a fix for that problem.
whilst i was doing thisi also noticed efreetd re-red dirs many times
due to icon theme inhritance. i also fixed that to do a LOT less
syscalls by only scanning a dir once as i was rejigging the scanning
code at the time anyway. this should optimize thr scan costs at
efreetd startup too.
@fix
@opt
2020-06-18 03:03:02 -07:00
|
|
|
size = readlink(file, link, sizeof(link));
|
|
|
|
if ((size > 0) && ((size_t)size >= sizeof(link))) return EINA_FALSE;
|
|
|
|
if (stat(file, &st) != 0) return EINA_FALSE;
|
|
|
|
}
|
|
|
|
if (size > 0) sha1((unsigned char *)link, size, check->link_sha1);
|
2020-06-18 03:35:44 -07:00
|
|
|
#endif
|
efreetd - cache - add more statinfo work around 0 mtime distros
some distros 9notably in this case nixos) want to do reproducible
builds. to them this means going around setting mtime for all files to
0. this means efreetd not only thinks mtime is invalid/stupid (0 is
generally just that as midnight on jan 1 1970 is not exactly a
sensible dare for a modified timestamp of a file as no filesystem with
any sanity will have not been modified since that time), but it keeps
mtime at 0 even when things update. this totally breaks efreetd that
expects to find mtime increases over time as things change. it's
necessary because it has to perform a "are mu caches up to date" scan
of all file data it caches and it needs to know if it should rebuild
something based on this.
so this does a few things:
1. it makes mtime have to be an exact match to the cache, not cache
mtime >= file mtime. so any change forward or back is an inavlidation.
2. it now also uses ctime, mode, size, uid, gid, block count and if a
symlink, the sha1 of the symlink path in addition and any change to
these == invalid.
this adds a lot of code and changes how dirs get scanned a bit but it
means it can pick up changes on these 0 mtime distros.
interestingly the policy of mtime being 0 is to have a reprodcible fs
... but ctime still changes and is > 0, as does inode info, so it's
not actually possible to have it totally work... but they try still,
so this is a fix for that problem.
whilst i was doing thisi also noticed efreetd re-red dirs many times
due to icon theme inhritance. i also fixed that to do a LOT less
syscalls by only scanning a dir once as i was rejigging the scanning
code at the time anyway. this should optimize thr scan costs at
efreetd startup too.
@fix
@opt
2020-06-18 03:03:02 -07:00
|
|
|
check->uid = st.st_uid;
|
|
|
|
check->gid = st.st_gid;
|
|
|
|
check->size = st.st_size;
|
2020-06-18 03:35:44 -07:00
|
|
|
#ifndef _WIN32
|
efreetd - cache - add more statinfo work around 0 mtime distros
some distros 9notably in this case nixos) want to do reproducible
builds. to them this means going around setting mtime for all files to
0. this means efreetd not only thinks mtime is invalid/stupid (0 is
generally just that as midnight on jan 1 1970 is not exactly a
sensible dare for a modified timestamp of a file as no filesystem with
any sanity will have not been modified since that time), but it keeps
mtime at 0 even when things update. this totally breaks efreetd that
expects to find mtime increases over time as things change. it's
necessary because it has to perform a "are mu caches up to date" scan
of all file data it caches and it needs to know if it should rebuild
something based on this.
so this does a few things:
1. it makes mtime have to be an exact match to the cache, not cache
mtime >= file mtime. so any change forward or back is an inavlidation.
2. it now also uses ctime, mode, size, uid, gid, block count and if a
symlink, the sha1 of the symlink path in addition and any change to
these == invalid.
this adds a lot of code and changes how dirs get scanned a bit but it
means it can pick up changes on these 0 mtime distros.
interestingly the policy of mtime being 0 is to have a reprodcible fs
... but ctime still changes and is > 0, as does inode info, so it's
not actually possible to have it totally work... but they try still,
so this is a fix for that problem.
whilst i was doing thisi also noticed efreetd re-red dirs many times
due to icon theme inhritance. i also fixed that to do a LOT less
syscalls by only scanning a dir once as i was rejigging the scanning
code at the time anyway. this should optimize thr scan costs at
efreetd startup too.
@fix
@opt
2020-06-18 03:03:02 -07:00
|
|
|
check->blocks = st.st_blocks;
|
2020-06-18 03:35:44 -07:00
|
|
|
#else
|
|
|
|
check->blocks = 0;
|
|
|
|
#endif
|
efreetd - cache - add more statinfo work around 0 mtime distros
some distros 9notably in this case nixos) want to do reproducible
builds. to them this means going around setting mtime for all files to
0. this means efreetd not only thinks mtime is invalid/stupid (0 is
generally just that as midnight on jan 1 1970 is not exactly a
sensible dare for a modified timestamp of a file as no filesystem with
any sanity will have not been modified since that time), but it keeps
mtime at 0 even when things update. this totally breaks efreetd that
expects to find mtime increases over time as things change. it's
necessary because it has to perform a "are mu caches up to date" scan
of all file data it caches and it needs to know if it should rebuild
something based on this.
so this does a few things:
1. it makes mtime have to be an exact match to the cache, not cache
mtime >= file mtime. so any change forward or back is an inavlidation.
2. it now also uses ctime, mode, size, uid, gid, block count and if a
symlink, the sha1 of the symlink path in addition and any change to
these == invalid.
this adds a lot of code and changes how dirs get scanned a bit but it
means it can pick up changes on these 0 mtime distros.
interestingly the policy of mtime being 0 is to have a reprodcible fs
... but ctime still changes and is > 0, as does inode info, so it's
not actually possible to have it totally work... but they try still,
so this is a fix for that problem.
whilst i was doing thisi also noticed efreetd re-red dirs many times
due to icon theme inhritance. i also fixed that to do a LOT less
syscalls by only scanning a dir once as i was rejigging the scanning
code at the time anyway. this should optimize thr scan costs at
efreetd startup too.
@fix
@opt
2020-06-18 03:03:02 -07:00
|
|
|
check->mtime = st.st_mtime;
|
|
|
|
check->chtime = st.st_ctime;
|
|
|
|
check->mode = st.st_mode;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool // true if matches
|
|
|
|
efreet_file_cache_check(const Efreet_Cache_Check *check1, const Efreet_Cache_Check *check2)
|
|
|
|
{
|
|
|
|
if ((check1->mtime != check2->mtime ) ||
|
|
|
|
(check1->size != check2->size ) ||
|
|
|
|
(check1->chtime != check2->chtime ) ||
|
|
|
|
(check1->blocks != check2->blocks) ||
|
|
|
|
(check1->mode != check2->mode ) ||
|
|
|
|
(check1->uid != check2->uid ) ||
|
|
|
|
(check1->gid != check2->gid ) ||
|
|
|
|
(memcmp(check1->link_sha1, check2->link_sha1, 20) != 0))
|
|
|
|
{
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
return EINA_TRUE; // matches
|
|
|
|
}
|
|
|
|
|
2010-12-02 02:47:34 -08:00
|
|
|
EAPI Eet_Data_Descriptor *
|
|
|
|
efreet_version_edd(void)
|
|
|
|
{
|
|
|
|
Eet_Data_Descriptor_Class eddc;
|
|
|
|
|
2010-12-03 01:55:36 -08:00
|
|
|
if (version_edd) return version_edd;
|
2010-12-02 02:47:34 -08:00
|
|
|
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Version);
|
2010-12-03 01:55:36 -08:00
|
|
|
version_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!version_edd) return NULL;
|
2010-12-02 02:47:34 -08:00
|
|
|
|
2010-12-03 01:55:36 -08:00
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(version_edd, Efreet_Cache_Version,
|
2010-12-02 02:47:34 -08:00
|
|
|
"minor", minor, EET_T_UCHAR);
|
2010-12-03 01:55:36 -08:00
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(version_edd, Efreet_Cache_Version,
|
2010-12-02 02:47:34 -08:00
|
|
|
"major", major, EET_T_UCHAR);
|
|
|
|
|
2010-12-03 01:55:36 -08:00
|
|
|
return version_edd;
|
2010-12-02 02:47:34 -08:00
|
|
|
}
|
|
|
|
|
2011-01-31 03:32:34 -08:00
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI Eet_Data_Descriptor *
|
|
|
|
efreet_hash_array_string_edd(void)
|
|
|
|
{
|
|
|
|
Eet_Data_Descriptor_Class eddc;
|
|
|
|
|
|
|
|
if (hash_array_string_edd) return hash_array_string_edd;
|
|
|
|
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Hash);
|
2011-02-09 09:09:38 -08:00
|
|
|
eddc.func.hash_add = hash_array_string_add;
|
2011-01-31 03:32:34 -08:00
|
|
|
hash_array_string_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!hash_array_string_edd) return NULL;
|
|
|
|
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_HASH(hash_array_string_edd, Efreet_Cache_Hash,
|
|
|
|
"hash", hash, efreet_array_string_edd());
|
|
|
|
|
|
|
|
return hash_array_string_edd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI Eet_Data_Descriptor *
|
|
|
|
efreet_hash_string_edd(void)
|
|
|
|
{
|
|
|
|
Eet_Data_Descriptor_Class eddc;
|
|
|
|
|
|
|
|
if (hash_string_edd) return hash_string_edd;
|
|
|
|
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Hash);
|
|
|
|
hash_string_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!hash_string_edd) return NULL;
|
|
|
|
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_HASH_STRING(hash_string_edd, Efreet_Cache_Hash,
|
|
|
|
"hash", hash);
|
|
|
|
|
|
|
|
return hash_string_edd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI Eet_Data_Descriptor *
|
|
|
|
efreet_array_string_edd(void)
|
|
|
|
{
|
|
|
|
Eet_Data_Descriptor_Class eddc;
|
|
|
|
|
|
|
|
if (array_string_edd) return array_string_edd;
|
|
|
|
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Array_String);
|
|
|
|
array_string_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!array_string_edd) return NULL;
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING(array_string_edd, Efreet_Cache_Array_String,
|
|
|
|
"array", array);
|
|
|
|
|
|
|
|
return array_string_edd;
|
|
|
|
}
|
|
|
|
|
2010-11-23 12:14:13 -08:00
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI const char *
|
|
|
|
efreet_desktop_cache_file(void)
|
|
|
|
{
|
2010-12-09 05:41:22 -08:00
|
|
|
char tmp[PATH_MAX] = { '\0' };
|
2010-12-04 08:02:20 -08:00
|
|
|
const char *cache, *lang, *country, *modifier;
|
2010-11-23 12:14:13 -08:00
|
|
|
|
|
|
|
if (desktop_cache_file) return desktop_cache_file;
|
|
|
|
|
2010-12-04 08:02:20 -08:00
|
|
|
cache = efreet_cache_home_get();
|
2010-11-23 12:14:13 -08:00
|
|
|
lang = efreet_lang_get();
|
|
|
|
country = efreet_lang_country_get();
|
|
|
|
modifier = efreet_lang_modifier_get();
|
|
|
|
|
|
|
|
if (lang && country && modifier)
|
2010-12-09 05:41:22 -08:00
|
|
|
snprintf(tmp, sizeof(tmp), "%s/efreet/desktop_%s_%s_%s@%s.eet", cache, efreet_hostname_get(), lang, country, modifier);
|
2010-11-23 12:14:13 -08:00
|
|
|
else if (lang && country)
|
2010-12-09 05:41:22 -08:00
|
|
|
snprintf(tmp, sizeof(tmp), "%s/efreet/desktop_%s_%s_%s.eet", cache, efreet_hostname_get(), lang, country);
|
2010-11-23 12:14:13 -08:00
|
|
|
else if (lang)
|
2010-12-09 05:41:22 -08:00
|
|
|
snprintf(tmp, sizeof(tmp), "%s/efreet/desktop_%s_%s.eet", cache, efreet_hostname_get(), lang);
|
2010-11-23 12:14:13 -08:00
|
|
|
else
|
2010-12-09 05:41:22 -08:00
|
|
|
snprintf(tmp, sizeof(tmp), "%s/efreet/desktop_%s.eet", cache, efreet_hostname_get());
|
2010-11-23 12:14:13 -08:00
|
|
|
|
|
|
|
desktop_cache_file = eina_stringshare_add(tmp);
|
|
|
|
return desktop_cache_file;
|
|
|
|
}
|
|
|
|
|
2010-12-02 00:32:59 -08:00
|
|
|
#define EDD_SHUTDOWN(Edd) \
|
|
|
|
if (Edd) eet_data_descriptor_free(Edd); \
|
|
|
|
Edd = NULL;
|
|
|
|
|
|
|
|
static void
|
|
|
|
efreet_cache_edd_shutdown(void)
|
|
|
|
{
|
2010-12-03 01:55:36 -08:00
|
|
|
EDD_SHUTDOWN(version_edd);
|
2010-12-02 00:32:59 -08:00
|
|
|
EDD_SHUTDOWN(desktop_edd);
|
2014-09-24 23:47:18 -07:00
|
|
|
EDD_SHUTDOWN(desktop_action_edd);
|
2011-01-31 03:32:34 -08:00
|
|
|
EDD_SHUTDOWN(hash_array_string_edd);
|
|
|
|
EDD_SHUTDOWN(array_string_edd);
|
|
|
|
EDD_SHUTDOWN(hash_string_edd);
|
2010-12-08 13:39:43 -08:00
|
|
|
EDD_SHUTDOWN(icon_theme_edd);
|
|
|
|
EDD_SHUTDOWN(icon_theme_directory_edd);
|
2010-12-02 00:32:59 -08:00
|
|
|
EDD_SHUTDOWN(directory_edd);
|
2010-12-08 13:39:43 -08:00
|
|
|
EDD_SHUTDOWN(icon_fallback_edd);
|
2010-12-02 00:32:59 -08:00
|
|
|
EDD_SHUTDOWN(icon_element_pointer_edd);
|
|
|
|
EDD_SHUTDOWN(icon_element_edd);
|
|
|
|
EDD_SHUTDOWN(icon_edd);
|
|
|
|
}
|
|
|
|
|
2010-11-26 06:56:23 -08:00
|
|
|
#define EFREET_POINTER_TYPE(Edd_Dest, Edd_Source, Type) \
|
2010-11-27 12:36:39 -08:00
|
|
|
{ \
|
|
|
|
typedef struct _Efreet_##Type##_Pointer Efreet_##Type##_Pointer; \
|
|
|
|
struct _Efreet_##Type##_Pointer \
|
|
|
|
{ \
|
2010-11-26 06:56:23 -08:00
|
|
|
Efreet_##Type *pointer; \
|
2010-11-27 12:36:39 -08:00
|
|
|
}; \
|
|
|
|
\
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_##Type##_Pointer); \
|
|
|
|
Edd_Dest = eet_data_descriptor_file_new(&eddc); \
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_SUB(Edd_Dest, Efreet_##Type##_Pointer, \
|
|
|
|
"pointer", pointer, Edd_Source); \
|
|
|
|
}
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-11-29 05:17:33 -08:00
|
|
|
static Eet_Data_Descriptor *
|
|
|
|
efreet_icon_directory_edd(void)
|
|
|
|
{
|
2010-12-08 13:39:43 -08:00
|
|
|
Eet_Data_Descriptor_Class eddc;
|
2010-11-29 05:17:33 -08:00
|
|
|
|
2010-12-08 13:39:43 -08:00
|
|
|
if (directory_edd) return directory_edd;
|
2010-11-29 05:17:33 -08:00
|
|
|
|
2010-12-08 13:39:43 -08:00
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Directory);
|
|
|
|
directory_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!directory_edd) return NULL;
|
2010-11-29 05:17:33 -08:00
|
|
|
|
efreetd - cache - add more statinfo work around 0 mtime distros
some distros 9notably in this case nixos) want to do reproducible
builds. to them this means going around setting mtime for all files to
0. this means efreetd not only thinks mtime is invalid/stupid (0 is
generally just that as midnight on jan 1 1970 is not exactly a
sensible dare for a modified timestamp of a file as no filesystem with
any sanity will have not been modified since that time), but it keeps
mtime at 0 even when things update. this totally breaks efreetd that
expects to find mtime increases over time as things change. it's
necessary because it has to perform a "are mu caches up to date" scan
of all file data it caches and it needs to know if it should rebuild
something based on this.
so this does a few things:
1. it makes mtime have to be an exact match to the cache, not cache
mtime >= file mtime. so any change forward or back is an inavlidation.
2. it now also uses ctime, mode, size, uid, gid, block count and if a
symlink, the sha1 of the symlink path in addition and any change to
these == invalid.
this adds a lot of code and changes how dirs get scanned a bit but it
means it can pick up changes on these 0 mtime distros.
interestingly the policy of mtime being 0 is to have a reprodcible fs
... but ctime still changes and is > 0, as does inode info, so it's
not actually possible to have it totally work... but they try still,
so this is a fix for that problem.
whilst i was doing thisi also noticed efreetd re-red dirs many times
due to icon theme inhritance. i also fixed that to do a LOT less
syscalls by only scanning a dir once as i was rejigging the scanning
code at the time anyway. this should optimize thr scan costs at
efreetd startup too.
@fix
@opt
2020-06-18 03:03:02 -07:00
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
|
|
|
|
"check.uid", check.uid, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
|
|
|
|
"check.gid", check.gid, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
|
|
|
|
"check.size", check.size, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
|
|
|
|
"check.blocks", check.blocks, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
|
|
|
|
"check.mtime", check.mtime, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
|
|
|
|
"check.chtime", check.chtime, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
|
|
|
|
"check.mode", check.mode, EET_T_INT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC_ARRAY(directory_edd, Efreet_Cache_Directory,
|
|
|
|
"check.link_sha1", check.link_sha1, EET_T_CHAR);
|
2010-11-29 05:17:33 -08:00
|
|
|
|
2010-12-08 13:39:43 -08:00
|
|
|
return directory_edd;
|
2010-11-29 05:17:33 -08:00
|
|
|
}
|
|
|
|
|
2010-11-15 13:07:22 -08:00
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI Eet_Data_Descriptor *
|
2011-01-31 03:44:56 -08:00
|
|
|
efreet_icon_edd(void)
|
2010-11-15 13:07:22 -08:00
|
|
|
{
|
2010-11-27 12:36:39 -08:00
|
|
|
Eet_Data_Descriptor_Class eddc;
|
|
|
|
|
2011-01-31 03:44:56 -08:00
|
|
|
if (icon_edd) return icon_edd;
|
2010-11-27 12:36:39 -08:00
|
|
|
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Icon_Element);
|
|
|
|
icon_element_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!icon_element_edd) return NULL;
|
|
|
|
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element,
|
|
|
|
"type", type, EET_T_USHORT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element,
|
|
|
|
"normal", normal, EET_T_USHORT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element,
|
|
|
|
"normal", normal, EET_T_USHORT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element,
|
|
|
|
"min", min, EET_T_USHORT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_element_edd, Efreet_Cache_Icon_Element,
|
|
|
|
"max", max, EET_T_USHORT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING(icon_element_edd, Efreet_Cache_Icon_Element,
|
|
|
|
"paths", paths);
|
|
|
|
|
|
|
|
EFREET_POINTER_TYPE(icon_element_pointer_edd, icon_element_edd, Cache_Icon_Element);
|
|
|
|
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Icon);
|
|
|
|
icon_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!icon_edd) return NULL;
|
|
|
|
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_edd, Efreet_Cache_Icon,
|
|
|
|
"theme", theme, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(icon_edd, Efreet_Cache_Icon,
|
|
|
|
"icons", icons, icon_element_pointer_edd);
|
|
|
|
|
2011-01-31 03:44:56 -08:00
|
|
|
return icon_edd;
|
2010-11-26 06:56:23 -08:00
|
|
|
}
|
2010-11-15 13:07:22 -08:00
|
|
|
|
2010-12-08 13:39:43 -08:00
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI Eet_Data_Descriptor *
|
2011-01-31 03:44:24 -08:00
|
|
|
efreet_icon_theme_edd(Eina_Bool cache)
|
2010-11-26 06:56:23 -08:00
|
|
|
{
|
2010-12-08 13:39:43 -08:00
|
|
|
Eet_Data_Descriptor_Class eddc;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-12-08 13:39:43 -08:00
|
|
|
if (icon_theme_edd) return icon_theme_edd;
|
|
|
|
|
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Icon_Theme_Directory);
|
|
|
|
icon_theme_directory_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!icon_theme_directory_edd) return NULL;
|
|
|
|
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
|
|
|
|
"name", name, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
|
|
|
|
"context", context, EET_T_UCHAR);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
|
|
|
|
"type", type, EET_T_UCHAR);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
|
|
|
|
"size.normal", size.normal, EET_T_UINT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
|
|
|
|
"size.min", size.min, EET_T_UINT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
|
|
|
|
"size.max", size.max, EET_T_UINT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_directory_edd, Efreet_Icon_Theme_Directory,
|
|
|
|
"size.threshold", size.threshold, EET_T_UINT);
|
|
|
|
|
2011-01-31 03:44:24 -08:00
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Icon_Theme);
|
2010-12-08 13:39:43 -08:00
|
|
|
icon_theme_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!icon_theme_edd) return NULL;
|
|
|
|
|
2011-01-31 03:44:24 -08:00
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"name.internal", theme.name.internal, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"name.name", theme.name.name, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"comment", theme.comment, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"example_icon", theme.example_icon, EET_T_STRING);
|
2010-12-08 13:39:43 -08:00
|
|
|
|
|
|
|
eet_data_descriptor_element_add(icon_theme_edd, "paths", EET_T_STRING, EET_G_LIST,
|
2011-01-31 03:44:24 -08:00
|
|
|
offsetof(Efreet_Cache_Icon_Theme, theme.paths), 0, NULL, NULL);
|
2010-12-08 13:39:43 -08:00
|
|
|
eet_data_descriptor_element_add(icon_theme_edd, "inherits", EET_T_STRING, EET_G_LIST,
|
2011-01-31 03:44:24 -08:00
|
|
|
offsetof(Efreet_Cache_Icon_Theme, theme.inherits), 0, NULL, NULL);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_LIST(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"directories", theme.directories, icon_theme_directory_edd);
|
2010-12-08 13:39:43 -08:00
|
|
|
|
2011-01-31 03:44:24 -08:00
|
|
|
if (cache)
|
|
|
|
{
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
efreetd - cache - add more statinfo work around 0 mtime distros
some distros 9notably in this case nixos) want to do reproducible
builds. to them this means going around setting mtime for all files to
0. this means efreetd not only thinks mtime is invalid/stupid (0 is
generally just that as midnight on jan 1 1970 is not exactly a
sensible dare for a modified timestamp of a file as no filesystem with
any sanity will have not been modified since that time), but it keeps
mtime at 0 even when things update. this totally breaks efreetd that
expects to find mtime increases over time as things change. it's
necessary because it has to perform a "are mu caches up to date" scan
of all file data it caches and it needs to know if it should rebuild
something based on this.
so this does a few things:
1. it makes mtime have to be an exact match to the cache, not cache
mtime >= file mtime. so any change forward or back is an inavlidation.
2. it now also uses ctime, mode, size, uid, gid, block count and if a
symlink, the sha1 of the symlink path in addition and any change to
these == invalid.
this adds a lot of code and changes how dirs get scanned a bit but it
means it can pick up changes on these 0 mtime distros.
interestingly the policy of mtime being 0 is to have a reprodcible fs
... but ctime still changes and is > 0, as does inode info, so it's
not actually possible to have it totally work... but they try still,
so this is a fix for that problem.
whilst i was doing thisi also noticed efreetd re-red dirs many times
due to icon theme inhritance. i also fixed that to do a LOT less
syscalls by only scanning a dir once as i was rejigging the scanning
code at the time anyway. this should optimize thr scan costs at
efreetd startup too.
@fix
@opt
2020-06-18 03:03:02 -07:00
|
|
|
"check.uid", check.uid, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"check.gid", check.gid, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"check.size", check.size, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"check.blocks", check.blocks, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"check.mtime", check.mtime, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"check.chtime", check.chtime, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"check.mode", check.mode, EET_T_INT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC_ARRAY(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"check.link_sha1", check.link_sha1, EET_T_CHAR);
|
2011-01-31 03:44:24 -08:00
|
|
|
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"path", path, EET_T_STRING);
|
|
|
|
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_HASH(icon_theme_edd, Efreet_Cache_Icon_Theme,
|
|
|
|
"dirs", dirs, efreet_icon_directory_edd());
|
|
|
|
}
|
2010-12-08 13:39:43 -08:00
|
|
|
|
|
|
|
return icon_theme_edd;
|
2010-11-15 13:07:22 -08:00
|
|
|
}
|
|
|
|
|
2010-11-16 02:32:21 -08:00
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI Eet_Data_Descriptor *
|
2011-01-31 03:44:56 -08:00
|
|
|
efreet_icon_fallback_edd(void)
|
2010-11-16 02:32:21 -08:00
|
|
|
{
|
2010-11-27 12:36:39 -08:00
|
|
|
Eet_Data_Descriptor_Class eddc;
|
2010-11-16 02:32:21 -08:00
|
|
|
|
2011-01-31 03:44:56 -08:00
|
|
|
if (icon_fallback_edd) return icon_fallback_edd;
|
2010-11-16 02:32:21 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Fallback_Icon);
|
|
|
|
icon_fallback_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!icon_fallback_edd) return NULL;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING(icon_fallback_edd,
|
|
|
|
Efreet_Cache_Fallback_Icon, "icons", icons);
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-01-31 03:44:56 -08:00
|
|
|
return icon_fallback_edd;
|
2010-11-16 02:32:21 -08:00
|
|
|
}
|
2010-11-15 13:07:22 -08:00
|
|
|
|
2010-11-23 12:14:13 -08:00
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
|
|
|
EAPI Eet_Data_Descriptor *
|
2010-12-02 00:32:22 -08:00
|
|
|
efreet_desktop_edd(void)
|
2010-11-23 12:14:13 -08:00
|
|
|
{
|
2010-11-27 12:36:39 -08:00
|
|
|
Eet_Data_Descriptor_Class eddc;
|
|
|
|
|
|
|
|
if (desktop_edd) return desktop_edd;
|
|
|
|
|
2014-09-24 23:47:18 -07:00
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Desktop_Action);
|
|
|
|
desktop_action_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!desktop_action_edd) return NULL;
|
|
|
|
|
|
|
|
/* Desktop Spec 1.1 */
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_action_edd, Efreet_Desktop_Action, "key", key, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_action_edd, Efreet_Desktop_Action, "name", name, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_action_edd, Efreet_Desktop_Action, "icon", icon, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_action_edd, Efreet_Desktop_Action, "exec", exec, EET_T_STRING);
|
|
|
|
|
2011-08-18 02:03:44 -07:00
|
|
|
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Desktop);
|
2010-11-27 12:36:39 -08:00
|
|
|
desktop_edd = eet_data_descriptor_file_new(&eddc);
|
|
|
|
if (!desktop_edd) return NULL;
|
|
|
|
|
2014-09-24 23:47:18 -07:00
|
|
|
/* Desktop Spec 1.0 */
|
2011-08-18 02:03:44 -07:00
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "type", desktop.type, EET_T_INT);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "version", desktop.version, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "orig_path", desktop.orig_path, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "load_time", desktop.load_time, EET_T_LONG_LONG);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "name", desktop.name, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "generic_name", desktop.generic_name, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "comment", desktop.comment, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "icon", desktop.icon, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "try_exec", desktop.try_exec, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "exec", desktop.exec, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "path", desktop.path, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "startup_wm_class", desktop.startup_wm_class, EET_T_STRING);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "url", desktop.url, EET_T_STRING);
|
|
|
|
eet_data_descriptor_element_add(desktop_edd, "only_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Desktop, desktop.only_show_in), 0, NULL, NULL);
|
|
|
|
eet_data_descriptor_element_add(desktop_edd, "not_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Desktop, desktop.not_show_in), 0, NULL, NULL);
|
|
|
|
eet_data_descriptor_element_add(desktop_edd, "categories", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Desktop, desktop.categories), 0, NULL, NULL);
|
|
|
|
eet_data_descriptor_element_add(desktop_edd, "mime_types", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Desktop, desktop.mime_types), 0, NULL, NULL);
|
|
|
|
eet_data_descriptor_element_add(desktop_edd, "x", EET_T_STRING, EET_G_HASH, offsetof(Efreet_Cache_Desktop, desktop.x), 0, NULL, NULL);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "no_display", desktop.no_display, EET_T_UCHAR);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "hidden", desktop.hidden, EET_T_UCHAR);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "terminal", desktop.terminal, EET_T_UCHAR);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "startup_notify", desktop.startup_notify, EET_T_UCHAR);
|
2010-11-27 12:36:39 -08:00
|
|
|
|
2014-09-24 23:47:18 -07:00
|
|
|
/* Desktop Spec 1.1 */
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "dbus_activatable", desktop.dbus_activatable, EET_T_UCHAR);
|
|
|
|
EET_DATA_DESCRIPTOR_ADD_LIST(desktop_edd, Efreet_Cache_Desktop,
|
|
|
|
"actions", desktop.actions, desktop_action_edd);
|
|
|
|
eet_data_descriptor_element_add(desktop_edd, "implements", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Desktop, desktop.implements), 0, NULL, NULL);
|
|
|
|
eet_data_descriptor_element_add(desktop_edd, "keywords", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Desktop, desktop.keywords), 0, NULL, NULL);
|
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
return desktop_edd;
|
2010-11-23 12:14:13 -08:00
|
|
|
}
|
|
|
|
|
2010-11-16 13:50:53 -08:00
|
|
|
Efreet_Cache_Icon *
|
|
|
|
efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon)
|
|
|
|
{
|
2011-02-01 13:03:40 -08:00
|
|
|
Efreet_Cache_Icon *cache = NULL;
|
|
|
|
|
2010-11-27 12:36:39 -08:00
|
|
|
if (theme_name && strcmp(theme_name, theme->name.internal))
|
|
|
|
{
|
2010-11-26 06:56:23 -08:00
|
|
|
/* FIXME: this is bad if people have pointer to this cache, things will go wrong */
|
2014-09-29 00:39:17 -07:00
|
|
|
INF("theme_name change from '%s' to '%s'", theme_name, theme->name.internal);
|
2010-12-12 14:17:05 -08:00
|
|
|
IF_RELEASE(theme_name);
|
2011-01-31 03:44:56 -08:00
|
|
|
icon_cache = efreet_cache_close(icon_cache);
|
2011-02-01 13:03:40 -08:00
|
|
|
eina_hash_free(icons);
|
|
|
|
icons = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_free));
|
2010-11-27 12:36:39 -08:00
|
|
|
}
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-01-31 03:44:56 -08:00
|
|
|
if (!efreet_cache_check(&icon_cache, efreet_icon_cache_file(theme->name.internal), EFREET_ICON_CACHE_MAJOR)) return NULL;
|
2010-11-27 12:36:39 -08:00
|
|
|
if (!theme_name)
|
2011-01-31 03:44:56 -08:00
|
|
|
theme_name = eina_stringshare_add(theme->name.internal);
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-01 13:03:40 -08:00
|
|
|
cache = eina_hash_find(icons, icon);
|
|
|
|
if (cache == NON_EXISTING) return NULL;
|
|
|
|
if (cache) return cache;
|
|
|
|
|
|
|
|
cache = eet_data_read(icon_cache, efreet_icon_edd(), icon);
|
|
|
|
if (cache)
|
|
|
|
eina_hash_add(icons, icon, cache);
|
|
|
|
else
|
|
|
|
eina_hash_add(icons, icon, NON_EXISTING);
|
|
|
|
return cache;
|
2010-11-16 13:50:53 -08:00
|
|
|
}
|
2010-11-22 06:16:09 -08:00
|
|
|
|
2010-11-26 06:56:23 -08:00
|
|
|
Efreet_Cache_Fallback_Icon *
|
2010-11-22 12:50:46 -08:00
|
|
|
efreet_cache_icon_fallback_find(const char *icon)
|
|
|
|
{
|
2011-02-01 13:03:40 -08:00
|
|
|
Efreet_Cache_Fallback_Icon *cache;
|
|
|
|
|
2011-01-31 03:44:56 -08:00
|
|
|
if (!efreet_cache_check(&fallback_cache, efreet_icon_cache_file(EFREET_CACHE_ICON_FALLBACK), EFREET_ICON_CACHE_MAJOR)) return NULL;
|
2010-11-26 06:56:23 -08:00
|
|
|
|
2011-02-01 13:03:40 -08:00
|
|
|
cache = eina_hash_find(fallbacks, icon);
|
|
|
|
if (cache == NON_EXISTING) return NULL;
|
|
|
|
if (cache) return cache;
|
|
|
|
|
|
|
|
cache = eet_data_read(fallback_cache, efreet_icon_fallback_edd(), icon);
|
|
|
|
if (cache)
|
|
|
|
eina_hash_add(fallbacks, icon, cache);
|
|
|
|
else
|
|
|
|
eina_hash_add(fallbacks, icon, NON_EXISTING);
|
|
|
|
return cache;
|
2010-11-22 12:50:46 -08:00
|
|
|
}
|
2010-12-09 00:56:56 -08:00
|
|
|
|
|
|
|
Efreet_Icon_Theme *
|
|
|
|
efreet_cache_icon_theme_find(const char *theme)
|
|
|
|
{
|
2011-02-09 09:09:16 -08:00
|
|
|
Efreet_Cache_Icon_Theme *cache;
|
|
|
|
|
2010-12-09 00:56:56 -08:00
|
|
|
if (!efreet_cache_check(&icon_theme_cache, efreet_icon_theme_cache_file(), EFREET_ICON_CACHE_MAJOR)) return NULL;
|
2011-02-09 09:09:16 -08:00
|
|
|
|
|
|
|
cache = eina_hash_find(themes, theme);
|
|
|
|
if (cache == NON_EXISTING) return NULL;
|
|
|
|
if (cache) return &(cache->theme);
|
|
|
|
|
|
|
|
cache = eet_data_read(icon_theme_cache, efreet_icon_theme_edd(EINA_FALSE), theme);
|
|
|
|
if (cache)
|
2011-02-09 10:36:12 -08:00
|
|
|
{
|
2011-02-09 09:09:16 -08:00
|
|
|
eina_hash_add(themes, theme, cache);
|
2011-02-09 10:36:12 -08:00
|
|
|
return &(cache->theme);
|
|
|
|
}
|
2011-02-09 09:09:16 -08:00
|
|
|
else
|
|
|
|
eina_hash_add(themes, theme, NON_EXISTING);
|
2011-02-09 10:36:12 -08:00
|
|
|
return NULL;
|
2010-12-09 00:56:56 -08:00
|
|
|
}
|
|
|
|
|
2011-02-10 06:24:20 -08:00
|
|
|
static void
|
|
|
|
efreet_cache_icon_free(Efreet_Cache_Icon *icon)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
if (!icon) return;
|
|
|
|
if (icon == NON_EXISTING) return;
|
|
|
|
|
|
|
|
for (i = 0; i < icon->icons_count; ++i)
|
|
|
|
{
|
|
|
|
free(icon->icons[i]->paths);
|
|
|
|
free(icon->icons[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(icon->icons);
|
|
|
|
free(icon);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
efreet_cache_icon_fallback_free(Efreet_Cache_Fallback_Icon *icon)
|
|
|
|
{
|
|
|
|
if (!icon) return;
|
|
|
|
if (icon == NON_EXISTING) return;
|
|
|
|
|
|
|
|
free(icon->icons);
|
|
|
|
free(icon);
|
|
|
|
}
|
|
|
|
|
2011-02-10 06:24:09 -08:00
|
|
|
static void
|
2010-12-09 00:56:56 -08:00
|
|
|
efreet_cache_icon_theme_free(Efreet_Icon_Theme *theme)
|
|
|
|
{
|
|
|
|
void *data;
|
|
|
|
|
|
|
|
if (!theme) return;
|
2011-02-09 09:09:16 -08:00
|
|
|
if (theme == NON_EXISTING) return;
|
2010-12-09 00:56:56 -08:00
|
|
|
|
|
|
|
eina_list_free(theme->paths);
|
|
|
|
eina_list_free(theme->inherits);
|
|
|
|
EINA_LIST_FREE(theme->directories, data)
|
|
|
|
free(data);
|
|
|
|
|
|
|
|
free(theme);
|
|
|
|
}
|
|
|
|
|
2011-02-09 09:09:16 -08:00
|
|
|
Eina_List *
|
|
|
|
efreet_cache_icon_theme_list(void)
|
2010-12-09 00:56:56 -08:00
|
|
|
{
|
2011-02-09 09:09:16 -08:00
|
|
|
Eina_List *ret = NULL;
|
2010-12-09 00:56:56 -08:00
|
|
|
char **keys;
|
2011-02-09 09:09:16 -08:00
|
|
|
int i, num;
|
2010-12-09 00:56:56 -08:00
|
|
|
|
|
|
|
if (!efreet_cache_check(&icon_theme_cache, efreet_icon_theme_cache_file(), EFREET_ICON_CACHE_MAJOR)) return NULL;
|
2011-02-09 09:09:16 -08:00
|
|
|
keys = eet_list(icon_theme_cache, "*", &num);
|
2013-08-07 01:59:05 -07:00
|
|
|
if (!keys) return NULL;
|
2011-02-09 09:09:16 -08:00
|
|
|
for (i = 0; i < num; i++)
|
2010-12-09 00:56:56 -08:00
|
|
|
{
|
2011-02-09 09:09:16 -08:00
|
|
|
Efreet_Icon_Theme *theme;
|
|
|
|
if (!strncmp(keys[i], "__efreet", 8)) continue;
|
2011-02-10 06:26:30 -08:00
|
|
|
|
|
|
|
theme = eina_hash_find(themes, keys[i]);
|
|
|
|
if (!theme)
|
|
|
|
theme = efreet_cache_icon_theme_find(keys[i]);
|
|
|
|
if (theme && theme != NON_EXISTING)
|
|
|
|
ret = eina_list_append(ret, theme);
|
2010-12-09 00:56:56 -08:00
|
|
|
}
|
2011-02-09 09:09:16 -08:00
|
|
|
free(keys);
|
|
|
|
return ret;
|
2010-12-09 00:56:56 -08:00
|
|
|
}
|
|
|
|
|
2011-02-07 13:19:36 -08:00
|
|
|
/*
|
|
|
|
* Needs EAPI because of helper binaries
|
|
|
|
*/
|
2011-01-31 03:32:34 -08:00
|
|
|
EAPI void
|
|
|
|
efreet_cache_array_string_free(Efreet_Cache_Array_String *array)
|
|
|
|
{
|
2011-02-02 14:57:34 -08:00
|
|
|
if (!array) return;
|
2011-01-31 03:32:34 -08:00
|
|
|
free(array->array);
|
|
|
|
free(array);
|
|
|
|
}
|
|
|
|
|
2010-11-23 12:14:13 -08:00
|
|
|
Efreet_Desktop *
|
|
|
|
efreet_cache_desktop_find(const char *file)
|
|
|
|
{
|
2013-06-20 02:52:43 -07:00
|
|
|
Efreet_Cache_Desktop *cache = NULL;
|
2010-11-23 12:14:13 -08:00
|
|
|
|
2013-06-20 02:52:43 -07:00
|
|
|
eina_lock_take(&_lock);
|
|
|
|
if (!efreet_cache_check(&desktop_cache, efreet_desktop_cache_file(), EFREET_DESKTOP_CACHE_MAJOR)) goto error;
|
2010-11-23 12:14:13 -08:00
|
|
|
|
2012-10-18 01:10:35 -07:00
|
|
|
cache = eina_hash_find(desktops, file);
|
2013-06-20 02:52:43 -07:00
|
|
|
if (cache == NON_EXISTING) goto error;
|
2011-08-18 02:03:44 -07:00
|
|
|
if (cache)
|
|
|
|
{
|
|
|
|
/* If less than one second since last stat, return desktop */
|
|
|
|
if ((ecore_time_get() - cache->check_time) < 1)
|
|
|
|
{
|
2014-09-29 00:39:17 -07:00
|
|
|
INF("Return without stat %f %f for file '%s'", ecore_time_get(), cache->check_time, file);
|
2013-06-20 02:52:43 -07:00
|
|
|
eina_lock_release(&_lock);
|
2011-08-18 02:03:44 -07:00
|
|
|
return &cache->desktop;
|
|
|
|
}
|
|
|
|
if (cache->desktop.load_time == ecore_file_mod_time(cache->desktop.orig_path))
|
|
|
|
{
|
2014-09-29 00:39:17 -07:00
|
|
|
INF("Return with stat %f %f for file '%s'", ecore_time_get(), cache->check_time, file);
|
2011-08-18 02:03:44 -07:00
|
|
|
cache->check_time = ecore_time_get();
|
2013-06-20 02:52:43 -07:00
|
|
|
eina_lock_release(&_lock);
|
2011-08-18 02:03:44 -07:00
|
|
|
return &cache->desktop;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We got stale data. The desktop will be free'd eventually as
|
|
|
|
* users will call efreet_desktop_free */
|
2012-10-18 01:10:35 -07:00
|
|
|
eina_hash_set(desktops, file, NON_EXISTING);
|
2011-08-18 02:03:44 -07:00
|
|
|
cache = NULL;
|
|
|
|
}
|
2011-02-10 06:25:44 -08:00
|
|
|
|
2012-10-18 01:10:35 -07:00
|
|
|
cache = eet_data_read(desktop_cache, efreet_desktop_edd(), file);
|
2011-02-10 06:25:44 -08:00
|
|
|
if (cache)
|
|
|
|
{
|
2011-08-18 02:03:44 -07:00
|
|
|
if (cache->desktop.load_time != ecore_file_mod_time(cache->desktop.orig_path))
|
|
|
|
{
|
|
|
|
/* Don't return stale data */
|
2014-09-29 00:39:17 -07:00
|
|
|
INF("We got stale data in the desktop cache for file '%s'", cache->desktop.orig_path);
|
2011-08-18 02:03:44 -07:00
|
|
|
efreet_cache_desktop_free(&cache->desktop);
|
2012-10-18 01:10:35 -07:00
|
|
|
eina_hash_set(desktops, file, NON_EXISTING);
|
2011-08-18 02:03:44 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cache->desktop.eet = 1;
|
|
|
|
cache->check_time = ecore_time_get();
|
|
|
|
eina_hash_set(desktops, cache->desktop.orig_path, cache);
|
2013-06-20 02:52:43 -07:00
|
|
|
eina_lock_release(&_lock);
|
2011-08-18 02:03:44 -07:00
|
|
|
return &cache->desktop;
|
|
|
|
}
|
2011-02-10 06:25:44 -08:00
|
|
|
}
|
|
|
|
else
|
2012-10-18 01:10:35 -07:00
|
|
|
eina_hash_set(desktops, file, NON_EXISTING);
|
2013-06-20 02:52:43 -07:00
|
|
|
error:
|
|
|
|
eina_lock_release(&_lock);
|
2011-08-18 02:03:44 -07:00
|
|
|
return NULL;
|
2010-11-23 12:14:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
efreet_cache_desktop_free(Efreet_Desktop *desktop)
|
|
|
|
{
|
|
|
|
Efreet_Old_Cache *d;
|
|
|
|
Efreet_Desktop *curr;
|
|
|
|
Eina_List *l;
|
|
|
|
|
2011-02-10 06:25:44 -08:00
|
|
|
if (!desktop ||
|
|
|
|
desktop == NON_EXISTING ||
|
|
|
|
!desktop->eet) return;
|
|
|
|
|
2013-06-20 02:52:43 -07:00
|
|
|
eina_lock_take(&_lock);
|
2011-02-10 06:25:44 -08:00
|
|
|
curr = eina_hash_find(desktops, desktop->orig_path);
|
|
|
|
if (curr == desktop)
|
2011-08-18 02:03:44 -07:00
|
|
|
{
|
2014-09-29 00:39:17 -07:00
|
|
|
INF("Found '%s' in current cache, purge", desktop->orig_path);
|
2011-02-10 06:25:44 -08:00
|
|
|
eina_hash_del_by_key(desktops, desktop->orig_path);
|
2011-08-18 02:03:44 -07:00
|
|
|
}
|
2010-11-23 12:14:13 -08:00
|
|
|
|
|
|
|
EINA_LIST_FOREACH(old_desktop_caches, l, d)
|
|
|
|
{
|
|
|
|
curr = eina_hash_find(d->hash, desktop->orig_path);
|
2011-08-18 02:03:44 -07:00
|
|
|
if (curr == desktop)
|
2010-11-23 12:14:13 -08:00
|
|
|
{
|
2014-09-29 00:39:17 -07:00
|
|
|
INF("Found '%s' in old cache, purge", desktop->orig_path);
|
2010-11-23 12:14:13 -08:00
|
|
|
eina_hash_del_by_key(d->hash, desktop->orig_path);
|
|
|
|
if (eina_hash_population(d->hash) == 0)
|
|
|
|
{
|
2014-09-29 00:39:17 -07:00
|
|
|
INF("Cache empty, close file");
|
2010-11-23 12:14:13 -08:00
|
|
|
eina_hash_free(d->hash);
|
2011-08-18 00:34:40 -07:00
|
|
|
eet_close(d->ef);
|
|
|
|
free(d);
|
|
|
|
old_desktop_caches = eina_list_remove_list(old_desktop_caches, l);
|
2010-11-23 12:14:13 -08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-02-10 06:25:44 -08:00
|
|
|
|
2014-09-24 23:47:18 -07:00
|
|
|
/* Desktop Spec 1.0 */
|
2011-02-10 06:25:44 -08:00
|
|
|
eina_list_free(desktop->only_show_in);
|
|
|
|
eina_list_free(desktop->not_show_in);
|
|
|
|
eina_list_free(desktop->categories);
|
|
|
|
eina_list_free(desktop->mime_types);
|
|
|
|
IF_FREE_HASH(desktop->x);
|
2014-09-24 23:47:18 -07:00
|
|
|
/* Desktop Spec 1.1 */
|
|
|
|
eina_list_free(desktop->actions);
|
|
|
|
eina_list_free(desktop->implements);
|
|
|
|
eina_list_free(desktop->keywords);
|
|
|
|
|
2011-02-10 06:25:44 -08:00
|
|
|
free(desktop);
|
2013-06-20 02:52:43 -07:00
|
|
|
eina_lock_release(&_lock);
|
2010-11-23 12:14:13 -08:00
|
|
|
}
|
|
|
|
|
2011-02-10 06:25:23 -08:00
|
|
|
void
|
|
|
|
efreet_cache_desktop_add(Efreet_Desktop *desktop)
|
|
|
|
{
|
2015-06-24 03:24:21 -07:00
|
|
|
char *path;
|
|
|
|
|
|
|
|
if ((!efreet_cache_update) || (!ipc)) return;
|
|
|
|
if (!eina_main_loop_is()) return;
|
2013-06-20 02:52:43 -07:00
|
|
|
/*
|
|
|
|
* TODO: Call in thread with:
|
2015-06-24 03:24:21 -07:00
|
|
|
* ecore_thread_main_loop_begin();
|
|
|
|
* ecore_thread_main_loop_end();
|
2013-06-20 02:52:43 -07:00
|
|
|
*/
|
2015-06-24 03:24:21 -07:00
|
|
|
path = ecore_file_dir_get(desktop->orig_path);
|
|
|
|
if (!path) return;
|
|
|
|
ecore_ipc_server_send(ipc, 2, 0, 0, 0, 0, path, strlen(path));
|
|
|
|
free(path);
|
2011-02-10 06:25:23 -08:00
|
|
|
}
|
|
|
|
|
2012-11-01 18:46:44 -07:00
|
|
|
void
|
|
|
|
efreet_cache_icon_exts_add(Eina_List *exts)
|
2011-02-10 06:25:23 -08:00
|
|
|
{
|
2015-06-24 03:24:21 -07:00
|
|
|
Eina_List *l;
|
|
|
|
const char *s;
|
|
|
|
Eina_Binbuf *buf;
|
|
|
|
int num = 0;
|
|
|
|
unsigned char nil[1] = { 0 };
|
|
|
|
|
|
|
|
if ((!efreet_cache_update) || (!ipc)) return;
|
|
|
|
buf = eina_binbuf_new();
|
|
|
|
if (!buf) return;
|
|
|
|
EINA_LIST_FOREACH(exts, l, s)
|
|
|
|
{
|
|
|
|
if (num > 0) eina_binbuf_append_length(buf, nil, 1);
|
|
|
|
eina_binbuf_append_length(buf, (unsigned char *)s, strlen(s));
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
ecore_ipc_server_send(ipc, 5 /* add icon exts */, 0, 0, 0, 0,
|
|
|
|
eina_binbuf_string_get(buf),
|
|
|
|
eina_binbuf_length_get(buf));
|
|
|
|
eina_binbuf_free(buf);
|
2011-02-10 06:25:23 -08:00
|
|
|
}
|
|
|
|
|
2011-02-10 06:24:20 -08:00
|
|
|
void
|
2012-11-01 18:46:44 -07:00
|
|
|
efreet_cache_icon_dirs_add(Eina_List *dirs)
|
2011-02-10 06:24:20 -08:00
|
|
|
{
|
2015-06-24 03:24:21 -07:00
|
|
|
Eina_List *l;
|
|
|
|
const char *s;
|
|
|
|
Eina_Binbuf *buf;
|
|
|
|
int num = 0;
|
|
|
|
unsigned char nil[1] = { 0 };
|
|
|
|
|
|
|
|
if ((!efreet_cache_update) || (!ipc)) return;
|
|
|
|
buf = eina_binbuf_new();
|
|
|
|
if (!buf) return;
|
|
|
|
EINA_LIST_FOREACH(dirs, l, s)
|
|
|
|
{
|
|
|
|
if (num > 0) eina_binbuf_append_length(buf, nil, 1);
|
|
|
|
eina_binbuf_append_length(buf, (unsigned char *)s, strlen(s));
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
ecore_ipc_server_send(ipc, 4 /* add icon dirs */, 0, 0, 0, 0,
|
|
|
|
eina_binbuf_string_get(buf),
|
|
|
|
eina_binbuf_length_get(buf));
|
|
|
|
eina_binbuf_free(buf);
|
2011-02-10 06:24:20 -08:00
|
|
|
}
|
|
|
|
|
2012-08-08 12:39:55 -07:00
|
|
|
void
|
|
|
|
efreet_cache_desktop_close(void)
|
|
|
|
{
|
|
|
|
IF_RELEASE(util_cache_names_key);
|
|
|
|
IF_RELEASE(util_cache_hash_key);
|
|
|
|
|
2013-06-20 02:52:43 -07:00
|
|
|
eina_lock_take(&_lock);
|
2012-08-08 12:39:55 -07:00
|
|
|
if ((desktop_cache) && (desktop_cache != NON_EXISTING))
|
|
|
|
{
|
|
|
|
Efreet_Old_Cache *d = NEW(Efreet_Old_Cache, 1);
|
|
|
|
if (d)
|
|
|
|
{
|
|
|
|
d->hash = desktops;
|
|
|
|
d->ef = desktop_cache;
|
|
|
|
old_desktop_caches = eina_list_append(old_desktop_caches, d);
|
|
|
|
}
|
|
|
|
|
|
|
|
desktops = eina_hash_string_superfast_new(NULL);
|
|
|
|
}
|
|
|
|
desktop_cache = NULL;
|
2013-11-21 00:27:28 -08:00
|
|
|
IF_RELEASE(desktop_cache_file);
|
2013-06-20 02:52:43 -07:00
|
|
|
eina_lock_release(&_lock);
|
2012-08-08 12:39:55 -07:00
|
|
|
|
|
|
|
efreet_cache_array_string_free(util_cache_names);
|
|
|
|
util_cache_names = NULL;
|
|
|
|
|
|
|
|
if (util_cache_hash)
|
|
|
|
{
|
|
|
|
eina_hash_free(util_cache_hash->hash);
|
|
|
|
free(util_cache_hash);
|
|
|
|
util_cache_hash = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
util_cache = efreet_cache_close(util_cache);
|
|
|
|
IF_RELEASE(util_cache_file);
|
|
|
|
}
|
|
|
|
|
2011-02-10 06:24:20 -08:00
|
|
|
void
|
2012-11-01 18:46:44 -07:00
|
|
|
efreet_cache_desktop_build(void)
|
2011-02-10 06:24:20 -08:00
|
|
|
{
|
2015-06-24 03:24:21 -07:00
|
|
|
const char *s;
|
|
|
|
int len = 0;
|
|
|
|
if ((!efreet_cache_update) || (!ipc)) return;
|
|
|
|
s = efreet_language_get();
|
|
|
|
if (s) len = strlen(s);
|
|
|
|
ecore_ipc_server_send(ipc, 3 /* build desktop cache */, 0, 0, 0, 0, s, len);
|
2011-02-10 06:24:20 -08:00
|
|
|
}
|
|
|
|
|
2011-02-10 06:24:40 -08:00
|
|
|
static Eina_Bool
|
2010-12-02 00:34:07 -08:00
|
|
|
efreet_cache_check(Eet_File **ef, const char *path, int major)
|
|
|
|
{
|
|
|
|
Efreet_Cache_Version *version;
|
|
|
|
|
|
|
|
if (*ef == NON_EXISTING) return EINA_FALSE;
|
2010-12-09 04:19:23 -08:00
|
|
|
if (*ef) return EINA_TRUE;
|
2010-12-02 00:34:07 -08:00
|
|
|
if (!*ef)
|
|
|
|
*ef = eet_open(path, EET_FILE_MODE_READ);
|
|
|
|
if (!*ef)
|
|
|
|
{
|
|
|
|
*ef = NON_EXISTING;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
version = eet_data_read(*ef, efreet_version_edd(), EFREET_CACHE_VERSION);
|
|
|
|
if ((!version) || (version->major != major))
|
|
|
|
{
|
|
|
|
IF_FREE(version);
|
|
|
|
eet_close(*ef);
|
|
|
|
*ef = NON_EXISTING;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
free(version);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-02-10 06:24:40 -08:00
|
|
|
static void *
|
2010-12-02 00:34:07 -08:00
|
|
|
efreet_cache_close(Eet_File *ef)
|
|
|
|
{
|
|
|
|
if (ef && ef != NON_EXISTING)
|
|
|
|
eet_close(ef);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-02-10 06:24:40 -08:00
|
|
|
Efreet_Cache_Hash *
|
|
|
|
efreet_cache_util_hash_string(const char *key)
|
|
|
|
{
|
|
|
|
if (util_cache_hash_key && !strcmp(key, util_cache_hash_key))
|
|
|
|
return util_cache_hash;
|
|
|
|
if (!efreet_cache_check(&util_cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
|
|
|
|
|
|
|
|
if (util_cache_hash)
|
|
|
|
{
|
|
|
|
/* free previous util_cache */
|
|
|
|
IF_RELEASE(util_cache_hash_key);
|
|
|
|
eina_hash_free(util_cache_hash->hash);
|
|
|
|
free(util_cache_hash);
|
|
|
|
}
|
|
|
|
util_cache_hash_key = eina_stringshare_add(key);
|
|
|
|
util_cache_hash = eet_data_read(util_cache, efreet_hash_string_edd(), key);
|
|
|
|
return util_cache_hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
Efreet_Cache_Hash *
|
|
|
|
efreet_cache_util_hash_array_string(const char *key)
|
|
|
|
{
|
|
|
|
if (util_cache_hash_key && !strcmp(key, util_cache_hash_key))
|
|
|
|
return util_cache_hash;
|
|
|
|
if (!efreet_cache_check(&util_cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
|
|
|
|
|
|
|
|
IF_RELEASE(util_cache_hash_key);
|
|
|
|
if (util_cache_hash)
|
|
|
|
{
|
|
|
|
/* free previous cache */
|
|
|
|
eina_hash_free(util_cache_hash->hash);
|
|
|
|
free(util_cache_hash);
|
|
|
|
}
|
|
|
|
util_cache_hash_key = eina_stringshare_add(key);
|
|
|
|
util_cache_hash = eet_data_read(util_cache, efreet_hash_array_string_edd(), key);
|
|
|
|
return util_cache_hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
Efreet_Cache_Array_String *
|
|
|
|
efreet_cache_util_names(const char *key)
|
|
|
|
{
|
|
|
|
if (util_cache_names_key && !strcmp(key, util_cache_names_key))
|
|
|
|
return util_cache_names;
|
|
|
|
if (!efreet_cache_check(&util_cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
|
|
|
|
|
|
|
|
if (util_cache_names)
|
|
|
|
{
|
|
|
|
/* free previous util_cache */
|
|
|
|
IF_RELEASE(util_cache_names_key);
|
|
|
|
efreet_cache_array_string_free(util_cache_names);
|
|
|
|
}
|
|
|
|
util_cache_names_key = eina_stringshare_add(key);
|
|
|
|
util_cache_names = eet_data_read(util_cache, efreet_array_string_edd(), key);
|
|
|
|
return util_cache_names;
|
|
|
|
}
|
|
|
|
|
2010-12-11 12:37:17 -08:00
|
|
|
static void
|
|
|
|
icon_cache_update_free(void *data, void *ev)
|
|
|
|
{
|
|
|
|
Efreet_Old_Cache *d;
|
2011-02-09 09:09:16 -08:00
|
|
|
Eina_List *l;
|
2010-12-11 12:37:17 -08:00
|
|
|
|
2011-02-09 09:09:16 -08:00
|
|
|
l = data;
|
|
|
|
EINA_LIST_FREE(l, d)
|
|
|
|
{
|
|
|
|
if (d->hash)
|
|
|
|
eina_hash_free(d->hash);
|
|
|
|
efreet_cache_close(d->ef);
|
|
|
|
free(d);
|
|
|
|
}
|
2010-12-11 12:37:17 -08:00
|
|
|
free(ev);
|
|
|
|
}
|
2011-02-09 09:09:38 -08:00
|
|
|
|
|
|
|
static void *
|
|
|
|
hash_array_string_add(void *hash, const char *key, void *data)
|
|
|
|
{
|
|
|
|
if (!hash)
|
|
|
|
hash = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
|
|
|
|
if (!hash)
|
|
|
|
return NULL;
|
|
|
|
eina_hash_add(hash, key, data);
|
|
|
|
return hash;
|
|
|
|
}
|
2018-04-27 05:35:13 -07:00
|
|
|
|
|
|
|
EAPI void
|
|
|
|
efreet_cache_disable(void)
|
|
|
|
{
|
|
|
|
Eina_Bool prev = disable_cache;
|
|
|
|
|
|
|
|
disable_cache = EINA_TRUE;
|
|
|
|
|
|
|
|
if (_efreet_cache_log_dom < 0) return; // not yet initialized
|
|
|
|
if (prev == disable_cache) return; // same value
|
|
|
|
if (ipc)
|
|
|
|
{
|
|
|
|
ecore_ipc_server_del(ipc);
|
|
|
|
ipc = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
efreet_cache_enable(void)
|
|
|
|
{
|
|
|
|
Eina_Bool prev = disable_cache;
|
|
|
|
|
|
|
|
disable_cache = EINA_FALSE;
|
|
|
|
|
|
|
|
if (_efreet_cache_log_dom < 0) return; // not yet initialized
|
|
|
|
if (prev == disable_cache) return; // same value
|
|
|
|
if (!ipc) _ipc_launch();
|
|
|
|
}
|