efreetinternal_bindir=$(libdir)/efreet/$(MODULE_ARCH)
efreetinternal_bin_PROGRAMS = \
bin/efreet/efreet_desktop_cache_create \
-bin/efreet/efreet_icon_cache_create
+bin/efreet/efreet_icon_cache_create \
+bin/efreet/efreet_mime_cache_create
bin_efreet_efreet_desktop_cache_create_CPPFLAGS = -I$(top_builddir)/src/lib/efl $(EFREET_COMMON_CPPFLAGS)
bin_efreet_efreet_desktop_cache_create_LDADD = $(USE_EFREET_BIN_LIBS)
bin_efreet_efreet_icon_cache_create_DEPENDENCIES = @USE_EFREET_INTERNAL_LIBS@
bin_efreet_efreet_icon_cache_create_SOURCES = bin/efreet/efreet_icon_cache_create.c
+bin_efreet_efreet_mime_cache_create_CPPFLAGS = -I$(top_builddir)/src/lib/efl $(EFREET_COMMON_CPPFLAGS)
+bin_efreet_efreet_mime_cache_create_LDADD = $(USE_EFREET_BIN_LIBS)
+bin_efreet_efreet_mime_cache_create_DEPENDENCIES = @USE_EFREET_INTERNAL_LIBS@
+bin_efreet_efreet_mime_cache_create_SOURCES = bin/efreet/efreet_mime_cache_create.c
+
### Unit tests
if EFL_ENABLE_TESTS
/efreet_desktop_cache_create
/efreet_icon_cache_create
/efreetd
+/efreet_mime_cache_create
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+#ifdef _WIN32
+# include <winsock2.h>
+#endif
+#include <libgen.h>
+#include <ctype.h>
+
+#include <Eina.h>
+#include <Eet.h>
+#include <Ecore.h>
+#include <Ecore_File.h>
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+#define EFREET_MODULE_LOG_DOM _efreet_mime_cache_log_dom
+static int _efreet_mime_cache_log_dom = -1;
+static Eina_List *extra_dirs = NULL;
+
+static Eina_Hash *mimes = NULL;
+static Eina_Hash *extn_mimes = NULL;
+static Eina_Hash *glob_mimes = NULL;
+static Eina_List *mimes_sorted = NULL;
+static Eina_List *extn_mimes_sorted = NULL;
+static Eina_List *glob_mimes_sorted = NULL;
+
+#include "Efreet.h"
+#include "efreet_private.h"
+#include "efreet_cache_private.h"
+
+static int
+cache_lock_file(void)
+{
+ char file[PATH_MAX];
+ struct flock fl;
+ int lockfd;
+
+ snprintf(file, sizeof(file), "%s/efreet/mime_data.lock", efreet_cache_home_get());
+ lockfd = open(file, O_CREAT | O_BINARY | O_RDWR, S_IRUSR | S_IWUSR);
+ if (lockfd < 0) return -1;
+ efreet_fsetowner(lockfd);
+
+ memset(&fl, 0, sizeof(struct flock));
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ if (fcntl(lockfd, F_SETLK, &fl) < 0)
+ {
+ INF("LOCKED! You may want to delete %s if this persists", file);
+ close(lockfd);
+ return -1;
+ }
+
+ return lockfd;
+}
+
+static int
+hash_list_sort_insert_cmp(const char *key1, const char *key2)
+{
+ return strcmp(key1, key2);
+}
+
+static Eina_Bool
+hash_list_sort_each(const Eina_Hash *hash EINA_UNUSED, const void *key, void *value EINA_UNUSED, void *data)
+{
+ Eina_List **list = data;
+ *list = eina_list_sorted_insert(*list,
+ EINA_COMPARE_CB(hash_list_sort_insert_cmp),
+ key);
+ return EINA_TRUE;
+}
+
+static void
+hash_list_sort(Eina_Hash *hash, Eina_List **list)
+{
+ eina_hash_foreach(hash, hash_list_sort_each, list);
+}
+
+static void
+etc_mime_types_load(const char *file)
+{
+ int len;
+ char buf[4096], buf2[4096], buf3[4096], *p, *p2;
+ const char *mime;
+ FILE *f = fopen(file, "r");
+
+ if (!f) return;
+ while (fgets(buf, sizeof(buf), f))
+ {
+ // remove newline at end of line string if there
+ buf[sizeof(buf) - 1] = 0;
+ len = strlen(buf);
+ if ((len > 0) && (buf[len - 1] == '\n')) buf[len - 1] = 0;
+ // buf: "# comment"
+ // or
+ // buf: "mime/type"
+ // buf: "mime/type "
+ // buf: "mime/type ext1"
+ // buf: "mime/type ext1 ext2"
+ // buf: "mime/type ext1 ext2 ext3"
+ // ...
+ p = buf;
+ // find first token in line
+ while ((*p) && isspace(*p)) p++;
+ // if comment - skip line
+ if (*p == '#') continue;
+ p2 = p;
+ while ((*p2) && !isspace(*p2)) p2++;
+ // token is between p and p2 (not including p2)
+ strncpy(buf2, p, p2 - p);
+ buf2[p2 - p] = 0;
+ mime = eina_stringshare_add(buf2);
+ // buf2 is now the mime type token
+ eina_hash_del(mimes, buf2, NULL);
+ eina_hash_add(mimes, buf2, mime);
+ // now lookf for all extension tokens;
+ p = p2;
+ // find next token in line
+ while ((*p) && isspace(*p)) p++;
+ while (*p)
+ {
+ // find end of token
+ p2 = p;
+ while ((*p2) && !isspace(*p2)) p2++;
+ // buf3 is now the extension token
+ strncpy(buf3, p, p2 - p);
+ buf3[p2 - p] = 0;
+ eina_hash_del(extn_mimes, buf3, NULL);
+ eina_hash_add(extn_mimes, buf3, mime);
+ // go to next token if any
+ p = p2;
+ while ((*p) && isspace(*p)) p++;
+ }
+ }
+ fclose(f);
+}
+
+static void
+share_mime_globs_load(const char *file)
+{
+ int len;
+ char buf[4096], buf2[4096], buf3[4096], *p, *p2;
+ const char *mime;
+ FILE *f = fopen(file, "r");
+
+ if (!f) return;
+ while (fgets(buf, sizeof(buf), f))
+ {
+ // remove newline at end of line string if there
+ buf[sizeof(buf) - 1] = 0;
+ len = strlen(buf);
+ if ((len > 0) && (buf[len - 1] == '\n')) buf[len - 1] = 0;
+ // buf: "# comment"
+ // or
+ // buf: "mime/type:glob"
+ // ...
+ p = buf;
+ // find first token in line
+ while ((*p) && isspace(*p)) p++;
+ // if comment - skip line
+ if (*p == '#') continue;
+ p2 = p;
+ while ((*p2) && (*p2 != ':')) p2++;
+ // token is between p and p2 (not including p2)
+ strncpy(buf2, p, p2 - p);
+ buf2[p2 - p] = 0;
+ mime = eina_stringshare_add(buf2);
+ // buf2 is now the mime type token
+ eina_hash_del(mimes, buf2, NULL);
+ eina_hash_add(mimes, buf2, mime);
+ // now lookf for all extension tokens;
+ p = p2;
+ // find next token in line
+ while ((*p) && (*p == ':')) p++;
+ // find end of token
+ p2 = p;
+ while ((*p2) && !isspace(*p2)) p2++;
+ // buf3 is now the extension token
+ strncpy(buf3, p, p2 - p);
+ buf3[p2 - p] = 0;
+ // for a shortcut a glob of "*.xxx" is the same as just an ext of "xxx"
+ // so if this is the case then put into the extn mimes not
+ // the globl mimes for speed of lookup later on
+ if ((buf3[0] == '*') && (buf3[1] == '.') &&
+ (!strchr(buf3 + 2, '*')) && (!strchr(buf3 + 2, '?')) &&
+ (!strchr(buf3 + 2, '[')) && (!strchr(buf3 + 2, ']')) &&
+ (!strchr(buf3 + 2, '\\')))
+ {
+ eina_hash_del(extn_mimes, buf3 + 2, NULL);
+ eina_hash_add(extn_mimes, buf3 + 2, mime);
+ }
+ else
+ {
+ eina_hash_del(glob_mimes, buf3, NULL);
+ eina_hash_add(glob_mimes, buf3, mime);
+ }
+ }
+ fclose(f);
+}
+
+static void *
+find_off(const char *str, Eina_List *strlist, Eina_List *offlist)
+{
+ Eina_List *l, *ll;
+ const char *s;
+
+ ll = offlist;
+ EINA_LIST_FOREACH(strlist, l, s)
+ {
+ if (!strcmp(str, s)) return ll->data;
+ ll = ll->next;
+ }
+ return (void *)-1;
+}
+static void
+store_cache(const char *out)
+{
+ char buf[PATH_MAX];
+ FILE *f;
+ size_t mimes_str_len = 0;
+ size_t extn_mimes_str_len = 0;
+ size_t glob_mimes_str_len = 0;
+ size_t str_start;
+ Eina_List *mimes_str_offsets = NULL;
+ Eina_List *extn_mimes_str_offsets = NULL;
+ Eina_List *glob_mimes_str_offsets = NULL;
+ Eina_List *l, *ll;
+ const char *s;
+ void *ptr;
+ unsigned int val;
+
+ snprintf(buf, sizeof(buf), "%s.tmp", out);
+ f = fopen(buf, "wb");
+ if (!f) return;
+ // write file magic - first 16 bytes
+ fwrite("EfrEeT-MiMeS-001", 16, 1, f);
+ // note: all offsets are in bytes from start of file
+ //
+ // "EfrEeT-MiMeS-001" <- magic 16 byte header
+ // [int] <- size of mimes array in number of entries
+ // [int] <- str byte offset of 1st mime string (sorted)
+ // [int] <- str byte offset of 2nd mime string
+ // ...
+ // [int] <- size of extn_mimes array in number of entries
+ // [int] <- str byte offset of 1st extn string (sorted)
+ // [int] <- str byte offset of 1st mime string
+ // [int] <- str byte offset of 2nd extn string
+ // [int] <- str byte offset of 2nd mine string
+ // ...
+ // [int] <- size of globs array in number of entries
+ // [int] <- str byte offset of 1st glob string (sorted)
+ // [int] <- str byte offset of 1st mime string
+ // [int] <- str byte offset of 2nd glob string
+ // [int] <- str byte offset of 2nd mime string
+ // ...
+ // strine1\0string2\0string3\0string4\0....
+ EINA_LIST_FOREACH(mimes_sorted, l, s)
+ {
+ mimes_str_offsets = eina_list_append(mimes_str_offsets,
+ (void *)mimes_str_len);
+ mimes_str_len += strlen(s) + 1;
+ }
+ EINA_LIST_FOREACH(extn_mimes_sorted, l, s)
+ {
+ extn_mimes_str_offsets = eina_list_append(extn_mimes_str_offsets,
+ (void *)extn_mimes_str_len);
+ extn_mimes_str_len += strlen(s) + 1;
+ }
+ EINA_LIST_FOREACH(glob_mimes_sorted, l, s)
+ {
+ glob_mimes_str_offsets = eina_list_append(glob_mimes_str_offsets,
+ (void *)glob_mimes_str_len);
+ glob_mimes_str_len += strlen(s) + 1;
+ }
+
+ str_start = 16 + // magic header
+ sizeof(int) +
+ (eina_list_count(mimes_sorted) * sizeof(int)) +
+ sizeof(int) +
+ (eina_list_count(extn_mimes_sorted) * sizeof(int) * 2) +
+ sizeof(int) +
+ (eina_list_count(glob_mimes_sorted) * sizeof(int) * 2);
+
+ val = eina_list_count(mimes_sorted);
+ fwrite(&val, sizeof(val), 1, f);
+ EINA_LIST_FOREACH(mimes_str_offsets, l, ptr)
+ {
+ val = (int)((long)ptr) + str_start;
+ fwrite(&val, sizeof(val), 1, f);
+ }
+
+ val = eina_list_count(extn_mimes_sorted);
+ fwrite(&val, sizeof(val), 1, f);
+ ll = extn_mimes_sorted;
+ EINA_LIST_FOREACH(extn_mimes_str_offsets, l, ptr)
+ {
+ val = (int)((long)ptr) + str_start + mimes_str_len;
+ fwrite(&val, sizeof(val), 1, f);
+ s = eina_hash_find(extn_mimes, ll->data);
+ ptr = find_off(s, mimes_sorted, mimes_str_offsets);
+ val = (int)((long)ptr) + str_start;
+ fwrite(&val, sizeof(val), 1, f);
+ ll = ll->next;
+ }
+
+ val = eina_list_count(glob_mimes_sorted);
+ fwrite(&val, sizeof(val), 1, f);
+ ll = glob_mimes_sorted;
+ EINA_LIST_FOREACH(glob_mimes_str_offsets, l, ptr)
+ {
+ val = (int)((long)ptr) + str_start + mimes_str_len + extn_mimes_str_len;
+ fwrite(&val, sizeof(val), 1, f);
+ s = eina_hash_find(glob_mimes, ll->data);
+ ptr = find_off(s, mimes_sorted, mimes_str_offsets);
+ val = (int)((long)ptr) + str_start;
+ fwrite(&val, sizeof(val), 1, f);
+ ll = ll->next;
+ }
+ EINA_LIST_FOREACH(mimes_sorted, l, s)
+ {
+ fwrite(s, strlen(s) + 1, 1, f);
+ }
+ EINA_LIST_FOREACH(extn_mimes_sorted, l, s)
+ {
+ fwrite(s, strlen(s) + 1, 1, f);
+ }
+ EINA_LIST_FOREACH(glob_mimes_sorted, l, s)
+ {
+ fwrite(s, strlen(s) + 1, 1, f);
+ }
+ fclose(f);
+ rename(buf, out);
+}
+
+int
+main(int argc, char **argv)
+{
+ char buf[PATH_MAX];
+ const char *s;
+ int i;
+ int ret = -1, lockfd = -1;
+ Eina_List *datadirs, *l;
+
+ if (!eina_init()) goto eina_error;
+ if (!eet_init()) goto eet_error;
+ if (!ecore_init()) goto ecore_error;
+ if (!ecore_file_init()) goto ecore_file_error;
+ if (!efreet_init()) goto efreet_error;
+
+ _efreet_mime_cache_log_dom =
+ eina_log_domain_register("efreet_mime_cache", EFREET_DEFAULT_LOG_COLOR);
+ if (_efreet_mime_cache_log_dom < 0)
+ {
+ EINA_LOG_ERR("Efreet: Could not create a log domain for efreet_mime_cache.");
+ return -1;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ if (!strcmp(argv[i], "-v"))
+ eina_log_domain_level_set("efreet_mime_cache", EINA_LOG_LEVEL_DBG);
+ else if ((!strcmp(argv[i], "-h")) ||
+ (!strcmp(argv[i], "-help")) ||
+ (!strcmp(argv[i], "--h")) ||
+ (!strcmp(argv[i], "--help")))
+ {
+ printf("Options:\n");
+ printf(" -v Verbose mode\n");
+ printf(" -d dir1 dir2 Extra dirs\n");
+ exit(0);
+ }
+ else if (!strcmp(argv[i], "-d"))
+ {
+ while ((i < (argc - 1)) && (argv[(i + 1)][0] != '-'))
+ extra_dirs = eina_list_append(extra_dirs, argv[++i]);
+ }
+ }
+ extra_dirs = eina_list_sort(extra_dirs, -1, EINA_COMPARE_CB(strcmp));
+
+ /* create homedir */
+ snprintf(buf, sizeof(buf), "%s/efreet", efreet_cache_home_get());
+ if (!ecore_file_exists(buf))
+ {
+ if (!ecore_file_mkpath(buf)) goto error;
+ efreet_setowner(buf);
+ }
+
+ /* lock process, so that we only run one copy of this program */
+ lockfd = cache_lock_file();
+ if (lockfd == -1) goto error;
+
+ mimes = eina_hash_string_superfast_new(NULL);
+ extn_mimes = eina_hash_string_superfast_new(NULL);
+ glob_mimes = eina_hash_string_superfast_new(NULL);
+
+ etc_mime_types_load("/etc/mime.types");
+ share_mime_globs_load("/usr/share/mime/globs");
+ datadirs = efreet_data_dirs_get();
+ EINA_LIST_FOREACH(datadirs, l, s)
+ {
+ snprintf(buf, sizeof(buf), "%s/mime/globs", s);
+ share_mime_globs_load(buf);
+ }
+ EINA_LIST_FOREACH(extra_dirs, l, s)
+ {
+ snprintf(buf, sizeof(buf), "%s/mime/globs", s);
+ share_mime_globs_load(buf);
+ }
+ snprintf(buf, sizeof(buf), "%s/mime/globs", efreet_data_home_get());
+ share_mime_globs_load(buf);
+ // XXX: load user files and other dirs etc.
+ // XXX: load globs
+
+ hash_list_sort(mimes, &mimes_sorted);
+ hash_list_sort(extn_mimes, &extn_mimes_sorted);
+ hash_list_sort(glob_mimes, &glob_mimes_sorted);
+
+#ifdef WORDS_BIGENDIAN
+ snprintf(buf, sizeof(buf), "%s/efreet/mime_cache_%s.be.dat",
+ efreet_cache_home_get(), efreet_hostname_get());
+#else
+ snprintf(buf, sizeof(buf), "%s/efreet/mime_cache_%s.le.dat",
+ efreet_cache_home_get(), efreet_hostname_get());
+#endif
+ store_cache(buf);
+
+ ret = 0;
+ close(lockfd);
+error:
+ efreet_shutdown();
+efreet_error:
+ ecore_file_shutdown();
+ecore_file_error:
+ ecore_shutdown();
+ecore_error:
+ eet_shutdown();
+eet_error:
+ eina_list_free(extra_dirs);
+ eina_log_domain_unregister(_efreet_mime_cache_log_dom);
+ eina_shutdown();
+eina_error:
+ return ret;
+}
static Subdir_Cache *subdir_cache = NULL;
static Eina_Bool subdir_need_save = EINA_FALSE;
+static Eina_Hash *mime_monitors = NULL;
+static Ecore_Timer *mime_update_timer = NULL;
+static Ecore_Exe *mime_cache_exe = NULL;
+
+static void mime_cache_init(void);
+static void mime_cache_shutdown(void);
+
static void
subdir_cache_dir_free(Subdir_Cache_Dir *cd)
{
if ((ev->lines) && (*ev->lines->line == 'c')) update = EINA_TRUE;
send_signal_icon_cache_update(update);
}
+ else if (ev->exe == mime_cache_exe)
+ {
+ // XXX: ZZZ: handle stdout here from cache updater... if needed
+ }
return ECORE_CALLBACK_RENEW;
}
icon_cache_exe = NULL;
if (icon_queue) cache_icon_update(EINA_FALSE);
}
+ else if (ev->exe == mime_cache_exe)
+ {
+ mime_cache_exe = NULL;
+ send_signal_mime_cache_build();
+ }
return ECORE_CALLBACK_RENEW;
}
return desktop_exists;
}
+static void
+mime_update_launch(void)
+{
+ char file[PATH_MAX];
+
+ snprintf(file, sizeof(file),
+ "%s/efreet/" MODULE_ARCH "/efreet_mime_cache_create",
+ eina_prefix_lib_get(pfx));
+ mime_cache_exe = ecore_exe_pipe_run(file,
+ ECORE_EXE_PIPE_READ |
+ ECORE_EXE_PIPE_READ_LINE_BUFFERED,
+ NULL);
+}
+
+static Eina_Bool
+mime_update_cache_cb(void *data EINA_UNUSED)
+{
+ mime_update_timer = NULL;
+ if (mime_cache_exe)
+ {
+ ecore_exe_kill(mime_cache_exe);
+ ecore_exe_free(mime_cache_exe);
+ }
+ mime_update_launch();
+ return EINA_FALSE;
+}
+
+static void
+mime_changes_cb(void *data EINA_UNUSED, Ecore_File_Monitor *em EINA_UNUSED,
+ Ecore_File_Event event, const char *path EINA_UNUSED)
+{
+ switch (event)
+ {
+ case ECORE_FILE_EVENT_NONE:
+ /* noop */
+ break;
+
+ case ECORE_FILE_EVENT_CREATED_FILE:
+ case ECORE_FILE_EVENT_DELETED_FILE:
+ case ECORE_FILE_EVENT_MODIFIED:
+ case ECORE_FILE_EVENT_CLOSED:
+ case ECORE_FILE_EVENT_DELETED_DIRECTORY:
+ case ECORE_FILE_EVENT_CREATED_DIRECTORY:
+ case ECORE_FILE_EVENT_DELETED_SELF:
+ mime_cache_shutdown();
+ mime_cache_init();
+ if (mime_update_timer) ecore_timer_del(mime_update_timer);
+ mime_update_timer = ecore_timer_add(0.2, mime_update_cache_cb, NULL);
+ break;
+ }
+}
+
+static void
+mime_cache_init(void)
+{
+ Ecore_File_Monitor *mon;
+ Eina_List *datadirs, *l;
+ const char *s;
+ char buf[PATH_MAX];
+
+ mime_monitors = eina_hash_string_superfast_new(NULL);
+
+ mon = ecore_file_monitor_add("/etc/mime.types", mime_changes_cb, NULL);
+ if (mon) eina_hash_add(mime_monitors, "/etc/mime.types", mon);
+ mon = ecore_file_monitor_add("/usr/share/mime/globs", mime_changes_cb, NULL);
+ if (mon) eina_hash_add(mime_monitors, "/usr/share/mime/globs", mon);
+
+ datadirs = efreet_data_dirs_get();
+ EINA_LIST_FOREACH(datadirs, l, s)
+ {
+ snprintf(buf, sizeof(buf), "%s/mime/globs", s);
+ if (!eina_hash_find(mime_monitors, buf))
+ {
+ mon = ecore_file_monitor_add(buf, mime_changes_cb, NULL);
+ if (mon) eina_hash_add(mime_monitors, buf, mon);
+ }
+ }
+}
+
+static Eina_Bool
+mime_cache_monitor_del(const Eina_Hash *hash EINA_UNUSED,
+ const void *key EINA_UNUSED, void *value,
+ void *data EINA_UNUSED)
+{
+ Ecore_File_Monitor *mon = value;
+ ecore_file_monitor_del(mon);
+ return EINA_TRUE;
+}
+
+static void
+mime_cache_shutdown(void)
+{
+ if (mime_update_timer)
+ {
+ ecore_timer_del(mime_update_timer);
+ mime_update_timer = NULL;
+ }
+ if (mime_monitors)
+ {
+ eina_hash_foreach(mime_monitors, mime_cache_monitor_del, NULL);
+ eina_hash_free(mime_monitors);
+ mime_monitors = NULL;
+ }
+}
+
Eina_Bool
cache_init(void)
{
efreet_cache_update = 0;
if (!efreet_init()) goto error;
subdir_cache_init();
+ mime_cache_init();
+ mime_update_launch();
read_lists();
/* TODO: Should check if system dirs has changed and handles extra_dirs */
desktop_system_dirs = efreet_default_dirs_get(efreet_data_home_get(),
eina_prefix_free(pfx);
pfx = NULL;
+ mime_cache_shutdown();
subdir_cache_shutdown();
efreet_shutdown();
_broadcast(ipc, 1 /* desktop cache build */, 1, NULL, 0);
}
+void
+send_signal_mime_cache_build(void)
+{
+ _broadcast(ipc, 4 /* mime cache build */, 1, NULL, 0);
+}
+
Eina_Bool
ipc_init(void)
{
void send_signal_icon_cache_update(Eina_Bool update);
void send_signal_desktop_cache_update(Eina_Bool update);
void send_signal_desktop_cache_build(void);
+void send_signal_mime_cache_build(void);
Eina_Bool ipc_init(void);
Eina_Bool ipc_shutdown(void);
+++ /dev/null
-#include "codegen_example_generated.h"
-
-Evas_Object *
-codegen_example_layout_add(Evas_Object *o, Elm_Theme *th, const char *edje_file)
-{
- Evas_Object *l;
-
- if (edje_file)
- elm_theme_extension_add(th, edje_file);
- else
- elm_theme_extension_add(th, "./codegen_example.edj");
-
- l = elm_layout_add(o);
- if (!l) return NULL;
-
- if (!elm_layout_theme_set(l, "example", "mylayout", "default"))
- {
- evas_object_del(l);
- return NULL;
- }
-
- return l;
-}
-
-void
-codegen_example_title_set(Evas_Object *o, const char *value)
-{
- elm_layout_text_set(o, "example/title", value);
-}
-
-const char *
-codegen_example_title_get(const Evas_Object *o)
-{
- return elm_layout_text_get(o, "example/title");
-}
-
-void
-codegen_example_custom_set(Evas_Object *o, Evas_Object *value)
-{
- elm_layout_content_set(o, "example/custom", value);
-}
-
-Evas_Object *
-codegen_example_custom_unset(Evas_Object *o)
-{
- return elm_layout_content_unset(o, "example/custom");
-}
-
-Evas_Object *
-codegen_example_custom_get(const Evas_Object *o)
-{
- return elm_layout_content_get(o, "example/custom");
-}
-
-Eina_Bool
-codegen_example_box_append(Evas_Object *o, Evas_Object *child)
-{
- return elm_layout_box_append(o, "example/box", child);
-}
-
-Eina_Bool
-codegen_example_box_prepend(Evas_Object *o, Evas_Object *child)
-{
- return elm_layout_box_prepend(o, "example/box", child);
-}
-
-Eina_Bool
-codegen_example_box_insert_before(Evas_Object *o, Evas_Object *child, const Evas_Object *reference)
-{
- return elm_layout_box_insert_before(o, "example/box", child, reference);
-}
-
-Eina_Bool
-codegen_example_box_insert_at(Evas_Object *o, Evas_Object *child, unsigned int pos)
-{
- return elm_layout_box_insert_at(o, "example/box", child, pos);
-}
-
-Evas_Object *
-codegen_example_box_remove(Evas_Object *o, Evas_Object *child)
-{
- return elm_layout_box_remove(o, "example/box", child);
-}
-
-Eina_Bool
-codegen_example_box_remove_all(Evas_Object *o, Eina_Bool clear)
-{
- return elm_layout_box_remove_all(o, "example/box", clear);
-}
-
-Eina_Bool
-codegen_example_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
-{
- return elm_layout_table_pack(o, "example/table", child, col, row, colspan, rowspan);
-}
-
-Evas_Object *
-codegen_example_table_unpack(Evas_Object *o, Evas_Object *child)
-{
- return elm_layout_table_unpack(o, "example/table", child);
-}
-
-Eina_Bool
-codegen_example_table_clear(Evas_Object *o, Eina_Bool clear)
-{
- return elm_layout_table_clear(o, "example/table", clear);
-}
-
-void
-codegen_example_swallow_grow_emit(Evas_Object *o)
-{
- elm_layout_signal_emit(o, "button,enlarge", "");
-}
-
-void
-codegen_example_swallow_shrink_emit(Evas_Object *o)
-{
- elm_layout_signal_emit(o, "button,reduce", "");
-}
-
-void
-codegen_example_size_changed_callback_add(Evas_Object *o, Edje_Signal_Cb func, void *data)
-{
- elm_layout_signal_callback_add(o, "size,changed", "", func, data);
-}
-
-void
-codegen_example_size_changed_callback_del(Evas_Object *o, Edje_Signal_Cb func)
-{
- elm_layout_signal_callback_del(o, "size,changed", "", func);
-}
-
+++ /dev/null
-#ifndef _CODEGEN_EXAMPLE_GENERATED_H
-#define _CODEGEN_EXAMPLE_GENERATED_H
-
-#include <Edje.h>
-#include <Elementary.h>
-#include <Evas.h>
-
-#include <stdlib.h>
-
-/**
- * @brief Creates the layout object and set the theme
- * @param o The parent
- * @param th The theme to add to, or if NULL, the default theme
- * @param edje_file The path to edj, if NULL it's used the path given
- * to elementary_codegen
- */
-Evas_Object *codegen_example_layout_add(Evas_Object *o, Elm_Theme *th, const char *edje_file);
-
-/**
- * @brief The example title
- */
-void codegen_example_title_set(Evas_Object *o, const char *value);
-const char *codegen_example_title_get(const Evas_Object *o);
-
-/**
- * @brief The swallow part
- */
-void codegen_example_custom_set(Evas_Object *o, Evas_Object *value);
-Evas_Object *codegen_example_custom_unset(Evas_Object *o);
-Evas_Object *codegen_example_custom_get(const Evas_Object *o);
-
-/**
- * @brief The box part
- */
-Eina_Bool codegen_example_box_append(Evas_Object *o, Evas_Object *child);
-Eina_Bool codegen_example_box_prepend(Evas_Object *o, Evas_Object *child);
-Eina_Bool codegen_example_box_insert_before(Evas_Object *o, Evas_Object *child, const Evas_Object *reference);
-Eina_Bool codegen_example_box_insert_at(Evas_Object *o, Evas_Object *child, unsigned int pos);
-Evas_Object *codegen_example_box_remove(Evas_Object *o, Evas_Object *child);
-Eina_Bool codegen_example_box_remove_all(Evas_Object *o, Eina_Bool clear);
-
-/**
- * @brief The table part
- */
-Eina_Bool codegen_example_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan);
-Evas_Object *codegen_example_table_unpack(Evas_Object *o, Evas_Object *child);
-Eina_Bool codegen_example_table_clear(Evas_Object *o, Eina_Bool clear);
-
-/**
- * @brief Executed when the button enlarges
- */
-void codegen_example_swallow_grow_emit(Evas_Object *o);
-
-/**
- * @brief Executed when the button reduces
- */
-void codegen_example_swallow_shrink_emit(Evas_Object *o);
-
-/**
- * @brief Emit the signal size,changed
- */
-void codegen_example_size_changed_callback_add(Evas_Object *o, Edje_Signal_Cb func, void *data);
-void codegen_example_size_changed_callback_del(Evas_Object *o, Edje_Signal_Cb func);
-
-#endif /* _CODEGEN_EXAMPLE_GENERATED_H */
ecore_event_add(event_type, ev, icon_cache_update_free, l);
}
+EAPI void (*_efreet_mime_update_func) (void) = NULL;
+
static Eina_Bool
_cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
{
_icon_desktop_cache_update_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE);
}
+ else if (e->major == 4) // mime cache update
+ {
+ if (_efreet_mime_update_func) _efreet_mime_update_func();
+ }
return ECORE_CALLBACK_DONE;
}
#include "Efreet_Mime.h"
#include "efreet_private.h"
-static Eina_List *globs = NULL; /* contains Efreet_Mime_Glob structs */
-static Eina_List *magics = NULL; /* contains Efreet_Mime_Magic structs */
-static Eina_Hash *wild = NULL; /* contains *.ext and mime.types globs*/
-static Eina_Hash *monitors = NULL; /* contains file monitors */
-static Eina_Hash *mime_icons = NULL; /* contains cache with mime->icons */
+static Eina_List *magics = NULL; // contains Efreet_Mime_Magic structs
+static Eina_Hash *mime_icons = NULL; // contains cache with mime->icons
static Eina_Inlist *mime_icons_lru = NULL;
static unsigned int _efreet_mime_init_count = 0;
*/
//#define EFREET_MIME_ICONS_DEBUG
-typedef struct Efreet_Mime_Glob Efreet_Mime_Glob;
-struct Efreet_Mime_Glob
-{
- const char *glob;
- const char *mime;
-};
-
typedef struct Efreet_Mime_Magic Efreet_Mime_Magic;
struct Efreet_Mime_Magic
{
unsigned int size;
};
-static int efreet_mime_glob_remove(const char *glob);
-static void efreet_mime_mime_types_load(const char *file);
-static void efreet_mime_shared_mimeinfo_globs_load(const char *file);
static void efreet_mime_shared_mimeinfo_magic_load(const char *file);
static void efreet_mime_shared_mimeinfo_magic_parse(char *data, int size);
static const char *efreet_mime_magic_check_priority(const char *file,
static int efreet_mime_init_files(void);
static const char *efreet_mime_special_check(const char *file);
static const char *efreet_mime_fallback_check(const char *file);
-static void efreet_mime_glob_free(void *data);
static void efreet_mime_magic_free(void *data);
static void efreet_mime_magic_entry_free(void *data);
static int efreet_mime_glob_match(const char *str, const char *glob);
static int efreet_mime_glob_case_match(char *str, const char *glob);
static int efreet_mime_endian_check(void);
-static void efreet_mime_monitor_add(const char *file);
-static void efreet_mime_cb_update_file(void *data,
- Ecore_File_Monitor *monitor,
- Ecore_File_Event event,
- const char *path);
-
static void efreet_mime_icons_flush(double now);
static void efreet_mime_icon_entry_head_free(Efreet_Mime_Icon_Entry_Head *entry);
static void efreet_mime_icon_entry_add(const char *mime,
unsigned int size);
static void efreet_mime_icons_debug(void);
+
+
+
+
+
+
+
+
+
+
+
+static Eina_File *mimedb = NULL;
+static unsigned char *mimedb_ptr = NULL;
+static size_t mimedb_size = 0;
+
+static void
+_efreet_mimedb_shutdown(void)
+{
+ if (mimedb)
+ {
+ if (mimedb_ptr) eina_file_map_free(mimedb, mimedb_ptr);
+ eina_file_close(mimedb);
+ mimedb = NULL;
+ mimedb_ptr = NULL;
+ mimedb_size = 0;
+ }
+}
+
+static void
+_efreet_mimedb_update(void)
+{
+ char buf[PATH_MAX];
+
+ if (mimedb)
+ {
+ if (mimedb_ptr) eina_file_map_free(mimedb, mimedb_ptr);
+ eina_file_close(mimedb);
+ mimedb = NULL;
+ mimedb_ptr = NULL;
+ mimedb_size = 0;
+ }
+#ifdef WORDS_BIGENDIAN
+ snprintf(buf, sizeof(buf), "%s/efreet/mime_cache_%s.be.dat",
+ efreet_cache_home_get(), efreet_hostname_get());
+#else
+ snprintf(buf, sizeof(buf), "%s/efreet/mime_cache_%s.le.dat",
+ efreet_cache_home_get(), efreet_hostname_get());
+#endif
+ mimedb = eina_file_open(buf, EINA_FALSE);
+ if (mimedb)
+ {
+ mimedb_ptr = eina_file_map_all(mimedb, EINA_FILE_POPULATE);
+ if (mimedb_ptr)
+ {
+ mimedb_size = eina_file_size_get(mimedb);
+ if ((mimedb_size > (16 + 4 + 4 + 4) &&
+ (!strncmp((char *)mimedb_ptr, "EfrEeT-MiMeS-001", 16))))
+ {
+ // load ok - magic fine. more sanity checks?
+ }
+ else
+ {
+ eina_file_map_free(mimedb, mimedb_ptr);
+ mimedb_ptr = NULL;
+ eina_file_close(mimedb);
+ mimedb = NULL;
+ mimedb_size = 0;
+ }
+ }
+ else
+ {
+ eina_file_close(mimedb);
+ mimedb = NULL;
+ }
+ }
+}
+
+static const char *
+_efreet_mimedb_str_get(unsigned int offset)
+{
+ if (offset < (16 + 4 + 4 + 4)) return NULL;
+ if (offset >= mimedb_size) return NULL;
+ return (const char *)(mimedb_ptr + offset);
+}
+
+static unsigned int
+_efreet_mimedb_uint_get(unsigned int index)
+// index is the unit NUMBER AFTER the header
+{
+ unsigned int *ptr;
+ ptr = ((unsigned int *)(mimedb_ptr + 16)) + index;
+ if ((size_t)(((unsigned char *)ptr) - mimedb_ptr) >= (mimedb_size - 4))
+ return 0;
+ return *ptr;
+}
+
+static unsigned int
+_efreet_mimedb_mime_count(void)
+{
+ return _efreet_mimedb_uint_get(0);
+}
+
+/**** currently unused - here for symmetry and future use
+static const char *
+_efreet_mimedb_mime_get(unsigned int num)
+{
+ unsigned int offset = _efreet_mimedb_uint_get
+ (1 + num);
+ return _efreet_mimedb_str_get(offset);
+}
+*/
+
+static unsigned int
+_efreet_mimedb_extn_count(void)
+{
+ return _efreet_mimedb_uint_get(1 + _efreet_mimedb_mime_count());
+}
+
+static const char *
+_efreet_mimedb_extn_get(unsigned int num)
+{
+ unsigned int offset = _efreet_mimedb_uint_get
+ (1 + _efreet_mimedb_mime_count() + 1 + (num * 2));
+ return _efreet_mimedb_str_get(offset);
+}
+
+static const char *
+_efreet_mimedb_extn_mime_get(unsigned int num)
+{
+ unsigned int offset = _efreet_mimedb_uint_get
+ (1 + _efreet_mimedb_mime_count() + 1 + (num * 2) + 1);
+ return _efreet_mimedb_str_get(offset);
+}
+
+static const char *
+_efreet_mimedb_extn_find(const char *extn)
+{
+ unsigned int i, begin, end;
+ const char *s;
+
+ // binary search keys to get value
+ begin = 0;
+ end = _efreet_mimedb_extn_count();
+ i = (begin + end) / 2;
+ for (;;)
+ {
+ s = _efreet_mimedb_extn_get(i);
+ if (s)
+ {
+ int v = strcmp(extn, s);
+ if (v < 0)
+ {
+ end = i;
+ i = (begin + end) / 2;
+ if ((end - begin) == 0) break;
+ }
+ else if (v > 0)
+ {
+ if ((end - begin) > 1)
+ {
+ begin = i;
+ i = (begin + end) / 2;
+ if (i == end) break;
+ }
+ else
+ {
+ if ((end - begin) == 0) break;
+ begin = end;
+ i = end;
+ }
+ }
+ else if (v == 0)
+ return _efreet_mimedb_extn_mime_get(i);
+ }
+ else
+ {
+ break;
+ }
+ }
+ return NULL;
+}
+
+static unsigned int
+_efreet_mimedb_glob_count(void)
+{
+ return _efreet_mimedb_uint_get
+ (1 + _efreet_mimedb_mime_count() +
+ 1 + (_efreet_mimedb_extn_count() * 2));
+}
+
+static const char *
+_efreet_mimedb_glob_get(unsigned int num)
+{
+ unsigned int offset = _efreet_mimedb_uint_get
+ (1 + _efreet_mimedb_mime_count() +
+ 1 + (_efreet_mimedb_extn_count() * 2) +
+ 1 + (num * 2));
+ return _efreet_mimedb_str_get(offset);
+}
+
+static const char *
+_efreet_mimedb_glob_mime_get(unsigned int num)
+{
+ unsigned int offset = _efreet_mimedb_uint_get
+ (1 + _efreet_mimedb_mime_count() +
+ 1 + (_efreet_mimedb_extn_count() * 2) +
+ 1 + (num * 2) + 1);
+ return _efreet_mimedb_str_get(offset);
+}
+
+/** --------------------------------- **/
+
EAPI int
efreet_mime_init(void)
{
}
efreet_mime_endianess = efreet_mime_endian_check();
-
- monitors = eina_hash_string_superfast_new(EINA_FREE_CB(ecore_file_monitor_del));
-
efreet_mime_type_cache_clear();
+ _efreet_mimedb_update();
+
if (!efreet_mime_init_files())
goto unregister_log_domain;
+ _efreet_mime_update_func = _efreet_mimedb_update;
+
return _efreet_mime_init_count;
unregister_log_domain:
if (--_efreet_mime_init_count != 0)
return _efreet_mime_init_count;
+ _efreet_mimedb_shutdown();
+ _efreet_mime_update_func = NULL;
+
efreet_mime_icons_debug();
IF_RELEASE(_mime_inode_symlink);
IF_RELEASE(_mime_application_octet_stream);
IF_RELEASE(_mime_text_plain);
- IF_FREE_LIST(globs, efreet_mime_glob_free);
IF_FREE_LIST(magics, efreet_mime_magic_free);
- IF_FREE_HASH(monitors);
- IF_FREE_HASH(wild);
IF_FREE_HASH(mime_icons);
eina_log_domain_unregister(_efreet_mime_log_dom);
_efreet_mime_log_dom = -1;
EAPI const char *
efreet_mime_globs_type_get(const char *file)
{
- Eina_List *l;
- Efreet_Mime_Glob *g;
char *sl, *p;
- const char *s;
- char *ext, *mime;
+ const char *s, *mime;
+ char *ext;
+ unsigned int i, n;
EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
while (p)
{
p++;
- if (p && (mime = eina_hash_find(wild, p))) return mime;
+ if (p && (mime = _efreet_mimedb_extn_find(p))) return mime;
p = strchr(p, '.');
}
}
- /* Fallback to the other globs if not found */
- EINA_LIST_FOREACH(globs, l, g)
+ // Fallback to the other globs if not found
+ n = _efreet_mimedb_glob_count();
+ for (i = 0; i < n; i++)
{
- if (efreet_mime_glob_match(file, g->glob))
- return g->mime;
+ s = _efreet_mimedb_glob_get(i);
+ if (efreet_mime_glob_match(file, s))
+ return _efreet_mimedb_glob_mime_get(i);
}
-
ext = alloca(strlen(file) + 1);
for (s = file, p = ext; *s; s++, p++) *p = tolower(*s);
*p = 0;
- EINA_LIST_FOREACH(globs, l, g)
+ for (i = 0; i < n; i++)
{
- if (efreet_mime_glob_case_match(ext, g->glob))
- return g->mime;
+ s = _efreet_mimedb_glob_get(i);
+ if (efreet_mime_glob_case_match(ext, s))
+ return _efreet_mimedb_glob_mime_get(i);
}
return NULL;
}
/**
* @internal
- * @param file File to monitor
- * @return Returns no value.
- * @brief Creates a new file monitor if we aren't already monitoring the
- * given file
- */
-static void
-efreet_mime_monitor_add(const char *file)
-{
- Ecore_File_Monitor *fm = NULL;
-
- /* if this is already in our hash then we're already monitoring so no
- * reason to re-monitor */
- if (eina_hash_find(monitors, file))
- return;
-
- if ((fm = ecore_file_monitor_add(file, efreet_mime_cb_update_file, NULL)))
- {
- eina_hash_del(monitors, file, NULL);
- eina_hash_add(monitors, file, fm);
- }
-}
-
-/**
- * @internal
- * @param datadirs List of XDG data dirs
- * @param datahome Path to XDG data home directory
- * @return Returns no value
- * @brief Read all glob files in XDG data/home dirs.
- * Also reads the /etc/mime.types file.
- */
-static void
-efreet_mime_load_globs(Eina_List *datadirs, const char *datahome)
-{
- Eina_List *l;
- char buf[4096];
- const char *datadir = NULL;
-
- IF_FREE_HASH(wild);
- wild = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
- while (globs)
- {
- efreet_mime_glob_free(eina_list_data_get(globs));
- globs = eina_list_remove_list(globs, globs);
- }
-
- /*
- * This is here for legacy reasons. It is mentioned briefly
- * in the spec and seems to still be quite valid. It is
- * loaded first so the globs files will override anything
- * in here.
- */
- efreet_mime_mime_types_load("/etc/mime.types");
-
- datadir = datahome;
- snprintf(buf, sizeof(buf), "%s/mime/globs", datadir);
- efreet_mime_shared_mimeinfo_globs_load(buf);
-
- EINA_LIST_FOREACH(datadirs, l, datadir)
- {
- snprintf(buf, sizeof(buf), "%s/mime/globs", datadir);
- efreet_mime_shared_mimeinfo_globs_load(buf);
- }
-}
-
-/**
- * @internal
* @param datadirs List of XDG data dirs
* @param datahome Path to XDG data home directory
* @return Returns no value
/**
* @internal
- * @param data Data pointer passed to monitor_add
- * @param monitor Ecore_File_Monitor associated with this event
- * @param event The type of event
- * @param path Path to the file that was updated
- * @return Returns no value
- * @brief Callback for all file monitors. Just reloads the appropriate
- * list depending on which file changed. If it was a magic file
- * only the magic list is updated. If it was a glob file or /etc/mime.types,
- * the globs are updated.
- */
-static void
-efreet_mime_cb_update_file(void *data EINA_UNUSED,
- Ecore_File_Monitor *monitor EINA_UNUSED,
- Ecore_File_Event event EINA_UNUSED,
- const char *path)
-{
- Eina_List *datadirs = NULL;
- const char *datahome = NULL;
-
- if (!(datahome = efreet_data_home_get()))
- return;
-
- if (!(datadirs = efreet_data_dirs_get()))
- return;
-
- if (strstr(path, "magic"))
- efreet_mime_load_magics(datadirs, datahome);
- else
- efreet_mime_load_globs(datadirs, datahome);
-}
-
-/**
- * @internal
* @param datadirs List of XDG data dirs
* @param datahome Path to XDG data home directory
* @return Returns 1 on success, 0 on failure
static int
efreet_mime_init_files(void)
{
- Eina_List *l;
Eina_List *datadirs = NULL;
- char buf[PATH_MAX];
- const char *datahome, *datadir = NULL;
+ const char *datahome;
if (!(datahome = efreet_data_home_get()))
return 0;
if (!(datadirs = efreet_data_dirs_get()))
return 0;
- /*
- * Add our file monitors
- * We watch the directories so we can watch for new files
- */
- datadir = datahome;
- snprintf(buf, sizeof(buf), "%s/mime", datadir);
- efreet_mime_monitor_add(buf);
-
- EINA_LIST_FOREACH(datadirs, l, datadir)
- {
- snprintf(buf, sizeof(buf), "%s/mime", datadir);
- efreet_mime_monitor_add(buf);
- }
- efreet_mime_monitor_add("/etc/mime.types");
-
- /* Load our mime information */
- efreet_mime_load_globs(datadirs, datahome);
efreet_mime_load_magics(datadirs, datahome);
- _mime_inode_symlink = eina_stringshare_add("inode/symlink");
- _mime_inode_fifo = eina_stringshare_add("inode/fifo");
- _mime_inode_chardevice = eina_stringshare_add("inode/chardevice");
- _mime_inode_blockdevice = eina_stringshare_add("inode/blockdevice");
- _mime_inode_socket = eina_stringshare_add("inode/socket");
- _mime_inode_mountpoint = eina_stringshare_add("inode/mountpoint");
- _mime_inode_directory = eina_stringshare_add("inode/directory");
+ _mime_inode_symlink = eina_stringshare_add("inode/symlink");
+ _mime_inode_fifo = eina_stringshare_add("inode/fifo");
+ _mime_inode_chardevice = eina_stringshare_add("inode/chardevice");
+ _mime_inode_blockdevice = eina_stringshare_add("inode/blockdevice");
+ _mime_inode_socket = eina_stringshare_add("inode/socket");
+ _mime_inode_mountpoint = eina_stringshare_add("inode/mountpoint");
+ _mime_inode_directory = eina_stringshare_add("inode/directory");
_mime_application_x_executable = eina_stringshare_add("application/x-executable");
_mime_application_octet_stream = eina_stringshare_add("application/octet-stream");
_mime_text_plain = eina_stringshare_add("text/plain");
/**
* @internal
- * @param glob Glob to search for
- * @return Returns 1 on success, 0 on failure
- * @brief Removes a glob from the list
- */
-static int
-efreet_mime_glob_remove(const char *glob)
-{
- Efreet_Mime_Glob *mime = NULL;
-
- if ((mime = eina_list_search_unsorted(globs, EINA_COMPARE_CB(strcmp), glob)))
- {
- globs = eina_list_remove(globs, mime);
- IF_RELEASE(mime->glob);
- IF_RELEASE(mime->mime);
- FREE(mime);
- return 1;
- }
-
- return 0;
-}
-
-static inline const char *
-efreet_eat_space(const char *head, const Eina_File_Line *ln, Eina_Bool not)
-{
- if (not)
- {
- while (!isspace(*head) && (head < ln->end))
- head++;
- }
- else
- {
- while (isspace(*head) && (head < ln->end))
- head++;
- }
-
- return head;
-}
-
-/**
- * @internal
- * @param file mime.types file to load
- * @return Returns no value
- * @brief Loads values from a mime.types style file
- * into the globs list.
- * @note Format:
- * application/msaccess mdb
- * application/msword doc dot
- */
-static void
-efreet_mime_mime_types_load(const char *file)
-{
- const Eina_File_Line *ln;
- Eina_Iterator *it;
- Eina_File *f;
- const char *head_line;
- const char *word_start;
- const char *mimetype;
-
- EINA_SAFETY_ON_NULL_RETURN(file);
- f = eina_file_open(file, 0);
- if (!f) return;
-
- it = eina_file_map_lines(f);
- if (it)
- {
- Eina_Strbuf *ext;
-
- ext = eina_strbuf_new();
-
- EINA_ITERATOR_FOREACH(it, ln)
- {
- head_line = efreet_eat_space(ln->start, ln, EINA_FALSE);
- if (head_line == ln->end) continue ;
-
- if (*head_line == '#') continue ;
-
- word_start = head_line;
- head_line = efreet_eat_space(head_line, ln, EINA_TRUE);
-
- if (head_line == ln->end) continue ;
- mimetype = eina_stringshare_add_length(word_start, head_line - word_start);
- do
- {
- head_line = efreet_eat_space(head_line, ln, EINA_FALSE);
- if (head_line == ln->end) break ;
-
- word_start = head_line;
- head_line = efreet_eat_space(head_line, ln, EINA_TRUE);
-
- eina_strbuf_append_length(ext, word_start, head_line - word_start);
-
- eina_hash_del(wild,
- eina_strbuf_string_get(ext),
- NULL);
- eina_hash_add(wild,
- eina_strbuf_string_get(ext),
- eina_stringshare_ref(mimetype));
-
- eina_strbuf_reset(ext);
- }
- while (head_line < ln->end);
-
- eina_stringshare_del(mimetype);
- }
-
- eina_strbuf_free(ext);
- eina_iterator_free(it);
- }
- eina_file_close(f);
-}
-
-/**
- * @internal
- * @param file globs file to load
- * @return Returns no value
- * @brief Loads values from a mime.types style file
- * into the globs list.
- * @note Format:
- * text/vnd.wap.wml:*.wml
- * application/x-7z-compressed:*.7z
- * application/vnd.corel-draw:*.cdr
- * text/spreadsheet:*.sylk
- */
-static void
-efreet_mime_shared_mimeinfo_globs_load(const char *file)
-{
- FILE *f = NULL;
- char buf[4096], mimetype[4096], ext[4096], *p, *pp;
- Efreet_Mime_Glob *mime = NULL;
-
- f = fopen(file, "rb");
- if (!f) return;
-
- while (fgets(buf, sizeof(buf), f))
- {
- p = buf;
- while (isspace(*p) && (*p != 0) && (*p != '\n')) p++;
-
- if (*p == '#') continue;
- if ((*p == '\n') || (*p == 0)) continue;
-
- pp = p;
- while ((*p != ':') && (*p != 0) && (*p != '\n')) p++;
-
- if ((*p == '\n') || (*p == 0)) continue;
- strncpy(mimetype, pp, (p - pp));
- mimetype[p - pp] = 0;
- p++;
- pp = ext;
-
- while ((*p != 0) && (*p != '\n'))
- {
- *pp = *p;
- pp++;
- p++;
- }
-
- *pp = 0;
-
- if (ext[0] == '*' && ext[1] == '.')
- {
- eina_hash_del(wild, &(ext[2]), NULL);
- eina_hash_add(wild, &(ext[2]),
- (void*)eina_stringshare_add(mimetype));
- }
- else
- {
- mime = NEW(Efreet_Mime_Glob, 1);
- if (mime)
- {
- mime->mime = eina_stringshare_add(mimetype);
- mime->glob = eina_stringshare_add(ext);
- if ((!mime->mime) || (!mime->glob))
- {
- IF_RELEASE(mime->mime);
- IF_RELEASE(mime->glob);
- FREE(mime);
- }
- else
- {
- efreet_mime_glob_remove(ext);
- globs = eina_list_append(globs, mime);
- }
- }
- }
- }
-
- fclose(f);
-}
-
-/**
- * @internal
* @param in Number to count the digits
* @return Returns number of digits
* @brief Calculates and returns the number of digits
* @internal
* @param data Data pointer that is being destroyed
* @return Returns no value
- * @brief Callback for globs destroy
- */
-static void
-efreet_mime_glob_free(void *data)
-{
- Efreet_Mime_Glob *m = data;
-
- IF_RELEASE(m->mime);
- IF_RELEASE(m->glob);
- IF_FREE(m);
-}
-
-/**
- * @internal
- * @param data Data pointer that is being destroyed
- * @return Returns no value
* @brief Callback for magics destroy
*/
static void
EAPI extern int efreet_cache_update;
+EAPI extern void (*_efreet_mime_update_func) (void);
+
#undef EAPI
#define EAPI