enlightenment/src/bin/e_fm_mime.c

294 lines
6.3 KiB
C

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
typedef struct _E_Mime E_Mime;
struct _E_Mime
{
const char *glob;
const char *mime;
};
/* local subsystem functions */
static void _e_fm_mime_all_free(void);
static void _e_fm_mime_update(void);
static int _e_fm_mime_glob_remove(const char *glob);
static void _e_fm_mime_mime_types_load(char *file);
static void _e_fm_mime_shared_mimeinfo_globs_load(char *file);
static Evas_List *mimes = NULL;
/* externally accessible functions */
EAPI const char *
e_fm_mime_filename_get(const char *fname)
{
Evas_List *l;
E_Mime *mime;
_e_fm_mime_update();
/* case senstive match first */
for (l = mimes; l; l = l->next)
{
mime = l->data;
if (e_util_glob_match(fname, mime->glob))
{
mimes = evas_list_remove_list(mimes, l);
mimes = evas_list_prepend(mimes, mime);
return mime->mime;
}
}
/* case insenstive match second */
for (l = mimes; l; l = l->next)
{
mime = l->data;
if (e_util_glob_match(fname, mime->glob))
{
mimes = evas_list_remove_list(mimes, l);
mimes = evas_list_prepend(mimes, mime);
return mime->mime;
}
}
return NULL;
}
/* local subsystem functions */
static void
_e_fm_mime_all_free(void)
{
E_Mime *mime;
while (mimes)
{
mime = mimes->data;
mimes = evas_list_remove_list(mimes, mimes);
evas_stringshare_del(mime->glob);
evas_stringshare_del(mime->mime);
free(mime);
}
}
static void
_e_fm_mime_update(void)
{
static double last_t = 0.0, t;
char buf[4096];
char *homedir;
int reload = 0;
/* load /etc/mime.types
* load /usr/share/mime/
*
* load ~/.mime.types
* load ~/.local/share/mime/
*/
t = ecore_time_get();
if ((t - last_t) < 1.0) return;
homedir = e_user_homedir_get();
if (!homedir) return;
{
static time_t last_changed = 0;
time_t ch;
snprintf(buf, sizeof(buf), "/etc/mime.types");
ch = ecore_file_mod_time(buf);
if ((ch != last_changed) || (reload))
{
_e_fm_mime_all_free();
last_changed = ch;
_e_fm_mime_mime_types_load(buf);
reload = 1;
}
}
{
static time_t last_changed = 0;
time_t ch;
snprintf(buf, sizeof(buf), "/usr/share/mime/globs");
ch = ecore_file_mod_time(buf);
if ((ch != last_changed) || (reload))
{
last_changed = ch;
_e_fm_mime_shared_mimeinfo_globs_load(buf);
}
}
{
static time_t last_changed = 0;
time_t ch;
snprintf(buf, sizeof(buf), "%s/.mime.types", homedir);
ch = ecore_file_mod_time(buf);
if ((ch != last_changed) || (reload))
{
last_changed = ch;
_e_fm_mime_mime_types_load(buf);
}
}
{
static time_t last_changed = 0;
time_t ch;
snprintf(buf, sizeof(buf), "%s/.local/share/mime/globs", homedir);
ch = ecore_file_mod_time(buf);
if ((ch != last_changed) || (reload))
{
last_changed = ch;
_e_fm_mime_shared_mimeinfo_globs_load(buf);
}
}
free(homedir);
}
static int
_e_fm_mime_glob_remove(const char *glob)
{
Evas_List *l;
E_Mime *mime;
for (l = mimes; l; l = l->next)
{
mime = l->data;
if (!strcmp(glob, mime->glob))
{
mimes = evas_list_remove_list(mimes, l);
evas_stringshare_del(mime->glob);
evas_stringshare_del(mime->mime);
free(mime);
return 1;
}
}
return 0;
}
static void
_e_fm_mime_mime_types_load(char *file)
{
/* format:
# type of encoding.
#
###############################################################################
application/msaccess mdb
application/msword doc dot
application/news-message-id
*/
FILE *f;
char buf[4096], buf2[4096], mimetype[4096], ext[4096], *p, *pp;
E_Mime *mime;
f = fopen(file, "rb");
if (!f) return;
while (fgets(buf, sizeof(buf), f))
{
p = buf;
while (isblank(*p) && (*p != 0) && (*p != '\n')) p++;
if (*p == '#') continue;
if ((*p == '\n') || (*p == 0)) continue;
pp = p;
while (!isblank(*p) && (*p != 0) && (*p != '\n')) p++;
if ((*p == '\n') || (*p == 0)) continue;
strncpy(mimetype, pp, (p - pp));
mimetype[p - pp] = 0;
do
{
while (isblank(*p) && (*p != 0) && (*p != '\n')) p++;
if ((*p == '\n') || (*p == 0)) break;
pp = p;
while (!isblank(*p) && (*p != 0) && (*p != '\n')) p++;
strncpy(ext, pp, (p - pp));
ext[p - pp] = 0;
mime = E_NEW(E_Mime, 1);
if (mime)
{
mime->mime = evas_stringshare_add(mimetype);
snprintf(buf2, sizeof(buf2), "*.%s", ext);
mime->glob = evas_stringshare_add(buf2);
if ((!mime->mime) || (!mime->glob))
{
if (mime->mime) evas_stringshare_del(mime->mime);
if (mime->glob) evas_stringshare_del(mime->glob);
free(mime);
}
else
{
_e_fm_mime_glob_remove(buf2);
mimes = evas_list_append(mimes, mime);
}
}
}
while ((*p != '\n') && (*p != 0));
}
fclose(f);
}
static void
_e_fm_mime_shared_mimeinfo_globs_load(char *file)
{
/* format:
# This file was automatically generated by the
# update-mime-database command. DO NOT EDIT!
text/vnd.wap.wml:*.wml
application/x-7z-compressed:*.7z
application/vnd.corel-draw:*.cdr
text/spreadsheet:*.sylk
*/
FILE *f;
char buf[4096], buf2[4096], mimetype[4096], ext[4096], *p, *pp;
E_Mime *mime;
f = fopen(file, "rb");
if (!f) return;
while (fgets(buf, sizeof(buf), f))
{
p = buf;
while (isblank(*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;
mime = E_NEW(E_Mime, 1);
if (mime)
{
mime->mime = evas_stringshare_add(mimetype);
snprintf(buf2, sizeof(buf2), "*.%s", ext);
mime->glob = evas_stringshare_add(buf2);
if ((!mime->mime) || (!mime->glob))
{
if (mime->mime) evas_stringshare_del(mime->mime);
if (mime->glob) evas_stringshare_del(mime->glob);
free(mime);
}
else
{
_e_fm_mime_glob_remove(buf2);
mimes = evas_list_append(mimes, mime);
}
}
}
fclose(f);
}