forked from AuroraMiddleware/gtk
Sync from upstream
2004-11-08 Matthias Clasen <mclasen@redhat.com> * Sync from upstream
This commit is contained in:
parent
9b86c72c96
commit
d0e90e40b1
@ -1,3 +1,7 @@
|
|||||||
|
2004-11-08 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
* Sync from upstream
|
||||||
|
|
||||||
2004-10-27 Matthias Clasen <mclasen@redhat.com>
|
2004-10-27 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* === Released 2.5.4 ===
|
* === Released 2.5.4 ===
|
||||||
|
@ -5,12 +5,16 @@ noinst_LTLIBRARIES = libxdgmime.la
|
|||||||
libxdgmime_la_SOURCES = \
|
libxdgmime_la_SOURCES = \
|
||||||
xdgmime.c \
|
xdgmime.c \
|
||||||
xdgmime.h \
|
xdgmime.h \
|
||||||
|
xdgmimealias.c \
|
||||||
|
xdgmimealias.h \
|
||||||
xdgmimeglob.c \
|
xdgmimeglob.c \
|
||||||
xdgmimeglob.h \
|
xdgmimeglob.h \
|
||||||
xdgmimeint.c \
|
xdgmimeint.c \
|
||||||
xdgmimeint.h \
|
xdgmimeint.h \
|
||||||
xdgmimemagic.c \
|
xdgmimemagic.c \
|
||||||
xdgmimemagic.h
|
xdgmimemagic.h \
|
||||||
|
xdgmimeparent.c \
|
||||||
|
xdgmimeparent.h
|
||||||
|
|
||||||
noinst_PROGRAMS = test-mime
|
noinst_PROGRAMS = test-mime
|
||||||
|
|
||||||
|
@ -1,31 +1,3 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
|
||||||
/* test-mime.c: Test program for mime type identification
|
|
||||||
*
|
|
||||||
* More info can be found at http://www.freedesktop.org/standards/
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Red Hat, Inc.
|
|
||||||
* Copyright (C) 2003 Jonathan Blandford <jrb@alum.mit.edu>
|
|
||||||
*
|
|
||||||
* Licensed under the Academic Free License version 2.0
|
|
||||||
* Or under the following terms:
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
* Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include "xdgmime.h"
|
#include "xdgmime.h"
|
||||||
#include "xdgmimeglob.h"
|
#include "xdgmimeglob.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -61,6 +33,67 @@ test_glob_type (void)
|
|||||||
test_individual_glob ("tree.[ch]", XDG_GLOB_FULL);
|
test_individual_glob ("tree.[ch]", XDG_GLOB_FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_alias (const char *mime_a,
|
||||||
|
const char *mime_b,
|
||||||
|
int expected)
|
||||||
|
{
|
||||||
|
int actual;
|
||||||
|
|
||||||
|
actual = xdg_mime_mime_type_equal (mime_a, mime_b);
|
||||||
|
|
||||||
|
if (actual != expected)
|
||||||
|
{
|
||||||
|
printf ("Test Failed: %s is %s to %s\n",
|
||||||
|
mime_a, actual ? "equal" : "not equal", mime_b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_aliasing (void)
|
||||||
|
{
|
||||||
|
test_alias ("application/wordperfect", "application/vnd.wordperfect", 1);
|
||||||
|
test_alias ("application/x-gnome-app-info", "application/x-desktop", 1);
|
||||||
|
test_alias ("application/x-wordperfect", "application/vnd.wordperfect", 1);
|
||||||
|
test_alias ("application/x-wordperfect", "audio/x-midi", 0);
|
||||||
|
test_alias ("/", "vnd/vnd", 0);
|
||||||
|
test_alias ("application/octet-stream", "text/plain", 0);
|
||||||
|
test_alias ("text/plain", "text/*", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_subclass (const char *mime_a,
|
||||||
|
const char *mime_b,
|
||||||
|
int expected)
|
||||||
|
{
|
||||||
|
int actual;
|
||||||
|
|
||||||
|
actual = xdg_mime_mime_type_subclass (mime_a, mime_b);
|
||||||
|
|
||||||
|
if (actual != expected)
|
||||||
|
{
|
||||||
|
printf ("Test Failed: %s is %s of %s\n",
|
||||||
|
mime_a, actual ? "subclass" : "not subclass", mime_b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_subclassing (void)
|
||||||
|
{
|
||||||
|
test_subclass ("application/rtf", "text/plain", 1);
|
||||||
|
test_subclass ("message/news", "text/plain", 1);
|
||||||
|
test_subclass ("message/news", "message/*", 1);
|
||||||
|
test_subclass ("message/news", "text/*", 1);
|
||||||
|
test_subclass ("message/news", "application/octet-stream", 1);
|
||||||
|
test_subclass ("application/rtf", "application/octet-stream", 1);
|
||||||
|
test_subclass ("application/x-gnome-app-info", "text/plain", 1);
|
||||||
|
test_subclass ("image/x-djvu", "image/vnd.djvu", 1);
|
||||||
|
test_subclass ("image/vnd.djvu", "image/x-djvu", 1);
|
||||||
|
test_subclass ("image/vnd.djvu", "text/plain", 0);
|
||||||
|
test_subclass ("image/vnd.djvu", "text/*", 0);
|
||||||
|
test_subclass ("text/*", "text/plain", 0);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -69,6 +102,9 @@ main (int argc, char *argv[])
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
test_glob_type ();
|
test_glob_type ();
|
||||||
|
test_aliasing ();
|
||||||
|
test_subclassing ();
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
file_name = argv[i];
|
file_name = argv[i];
|
||||||
@ -76,6 +112,9 @@ main (int argc, char *argv[])
|
|||||||
printf ("File \"%s\" has a mime-type of %s\n", file_name, result);
|
printf ("File \"%s\" has a mime-type of %s\n", file_name, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
xdg_mime_dump ();
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
*
|
*
|
||||||
* More info can be found at http://www.freedesktop.org/standards/
|
* More info can be found at http://www.freedesktop.org/standards/
|
||||||
*
|
*
|
||||||
* Copyright (C) 2003 Red Hat, Inc.
|
* Copyright (C) 2003,2004 Red Hat, Inc.
|
||||||
* Copyright (C) 2003 Jonathan Blandford <jrb@alum.mit.edu>
|
* Copyright (C) 2003,2004 Jonathan Blandford <jrb@alum.mit.edu>
|
||||||
*
|
*
|
||||||
* Licensed under the Academic Free License version 2.0
|
* Licensed under the Academic Free License version 2.0
|
||||||
* Or under the following terms:
|
* Or under the following terms:
|
||||||
@ -30,54 +30,156 @@
|
|||||||
#include "xdgmimeint.h"
|
#include "xdgmimeint.h"
|
||||||
#include "xdgmimeglob.h"
|
#include "xdgmimeglob.h"
|
||||||
#include "xdgmimemagic.h"
|
#include "xdgmimemagic.h"
|
||||||
|
#include "xdgmimealias.h"
|
||||||
|
#include "xdgmimeparent.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
typedef struct XdgDirTimeList XdgDirTimeList;
|
||||||
|
typedef struct XdgCallbackList XdgCallbackList;
|
||||||
|
|
||||||
|
static int need_reread = TRUE;
|
||||||
|
static time_t last_stat_time = 0;
|
||||||
|
|
||||||
static int initted = 0;
|
|
||||||
static XdgGlobHash *global_hash = NULL;
|
static XdgGlobHash *global_hash = NULL;
|
||||||
static XdgMimeMagic *global_magic = NULL;
|
static XdgMimeMagic *global_magic = NULL;
|
||||||
|
static XdgAliasList *alias_list = NULL;
|
||||||
|
static XdgParentList *parent_list = NULL;
|
||||||
|
static XdgDirTimeList *dir_time_list = NULL;
|
||||||
|
static XdgCallbackList *callback_list = NULL;
|
||||||
const char *xdg_mime_type_unknown = "application/octet-stream";
|
const char *xdg_mime_type_unknown = "application/octet-stream";
|
||||||
|
|
||||||
static void
|
|
||||||
_xdg_mime_init_from_directory (const char *directory)
|
enum
|
||||||
{
|
{
|
||||||
char *file_name;
|
XDG_CHECKED_UNCHECKED,
|
||||||
|
XDG_CHECKED_VALID,
|
||||||
|
XDG_CHECKED_INVALID
|
||||||
|
};
|
||||||
|
|
||||||
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
|
struct XdgDirTimeList
|
||||||
strcpy (file_name, directory);
|
{
|
||||||
strcat (file_name, "/mime/globs");
|
time_t mtime;
|
||||||
_xdg_mime_glob_read_from_file (global_hash, file_name);
|
char *directory_name;
|
||||||
free (file_name);
|
int checked;
|
||||||
|
XdgDirTimeList *next;
|
||||||
|
};
|
||||||
|
|
||||||
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
struct XdgCallbackList
|
||||||
strcpy (file_name, directory);
|
{
|
||||||
strcat (file_name, "/mime/magic");
|
XdgCallbackList *next;
|
||||||
_xdg_mime_magic_read_from_file (global_magic, file_name);
|
XdgCallbackList *prev;
|
||||||
free (file_name);
|
int callback_id;
|
||||||
|
XdgMimeCallback callback;
|
||||||
|
void *data;
|
||||||
|
XdgMimeDestroy destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Function called by xdg_run_command_on_dirs. If it returns TRUE, further
|
||||||
|
* directories aren't looked at */
|
||||||
|
typedef int (*XdgDirectoryFunc) (const char *directory,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
static XdgDirTimeList *
|
||||||
|
xdg_dir_time_list_new (void)
|
||||||
|
{
|
||||||
|
XdgDirTimeList *retval;
|
||||||
|
|
||||||
|
retval = calloc (1, sizeof (XdgDirTimeList));
|
||||||
|
retval->checked = XDG_CHECKED_UNCHECKED;
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xdg_mime_init (void)
|
xdg_dir_time_list_free (XdgDirTimeList *list)
|
||||||
{
|
{
|
||||||
if (initted == 0)
|
XdgDirTimeList *next;
|
||||||
|
|
||||||
|
while (list)
|
||||||
|
{
|
||||||
|
next = list->next;
|
||||||
|
free (list->directory_name);
|
||||||
|
free (list);
|
||||||
|
list = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xdg_mime_init_from_directory (const char *directory)
|
||||||
|
{
|
||||||
|
char *file_name;
|
||||||
|
struct stat st;
|
||||||
|
XdgDirTimeList *list;
|
||||||
|
|
||||||
|
assert (directory != NULL);
|
||||||
|
|
||||||
|
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
|
||||||
|
strcpy (file_name, directory); strcat (file_name, "/mime/globs");
|
||||||
|
if (stat (file_name, &st) == 0)
|
||||||
|
{
|
||||||
|
_xdg_mime_glob_read_from_file (global_hash, file_name);
|
||||||
|
|
||||||
|
list = xdg_dir_time_list_new ();
|
||||||
|
list->directory_name = file_name;
|
||||||
|
list->mtime = st.st_mtime;
|
||||||
|
list->next = dir_time_list;
|
||||||
|
dir_time_list = list;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free (file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
||||||
|
strcpy (file_name, directory); strcat (file_name, "/mime/magic");
|
||||||
|
if (stat (file_name, &st) == 0)
|
||||||
|
{
|
||||||
|
_xdg_mime_magic_read_from_file (global_magic, file_name);
|
||||||
|
|
||||||
|
list = xdg_dir_time_list_new ();
|
||||||
|
list->directory_name = file_name;
|
||||||
|
list->mtime = st.st_mtime;
|
||||||
|
list->next = dir_time_list;
|
||||||
|
dir_time_list = list;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free (file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_name = malloc (strlen (directory) + strlen ("/mime/aliases") + 1);
|
||||||
|
strcpy (file_name, directory); strcat (file_name, "/mime/aliases");
|
||||||
|
_xdg_mime_alias_read_from_file (alias_list, file_name);
|
||||||
|
free (file_name);
|
||||||
|
|
||||||
|
file_name = malloc (strlen (directory) + strlen ("/mime/subclasses") + 1);
|
||||||
|
strcpy (file_name, directory); strcat (file_name, "/mime/subclasses");
|
||||||
|
_xdg_mime_parent_read_from_file (parent_list, file_name);
|
||||||
|
free (file_name);
|
||||||
|
|
||||||
|
return FALSE; /* Keep processing */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Runs a command on all the directories in the search path */
|
||||||
|
static void
|
||||||
|
xdg_run_command_on_dirs (XdgDirectoryFunc func,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
const char *xdg_data_home;
|
const char *xdg_data_home;
|
||||||
const char *xdg_data_dirs;
|
const char *xdg_data_dirs;
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
|
|
||||||
global_hash = _xdg_glob_hash_new ();
|
|
||||||
global_magic = _xdg_mime_magic_new ();
|
|
||||||
|
|
||||||
/* We look for globs and magic files based upon the XDG Base Directory
|
|
||||||
* Specification
|
|
||||||
*/
|
|
||||||
xdg_data_home = getenv ("XDG_DATA_HOME");
|
xdg_data_home = getenv ("XDG_DATA_HOME");
|
||||||
if (xdg_data_home)
|
if (xdg_data_home)
|
||||||
{
|
{
|
||||||
_xdg_mime_init_from_directory (xdg_data_home);
|
if ((func) (xdg_data_home, user_data))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -87,12 +189,16 @@ xdg_mime_init (void)
|
|||||||
if (home != NULL)
|
if (home != NULL)
|
||||||
{
|
{
|
||||||
char *guessed_xdg_home;
|
char *guessed_xdg_home;
|
||||||
|
int stop_processing;
|
||||||
|
|
||||||
guessed_xdg_home = malloc (strlen (home) + strlen ("/.local/share/") + 1);
|
guessed_xdg_home = malloc (strlen (home) + strlen ("/.local/share/") + 1);
|
||||||
strcpy (guessed_xdg_home, home);
|
strcpy (guessed_xdg_home, home);
|
||||||
strcat (guessed_xdg_home, "/.local/share/");
|
strcat (guessed_xdg_home, "/.local/share/");
|
||||||
_xdg_mime_init_from_directory (guessed_xdg_home);
|
stop_processing = (func) (guessed_xdg_home, user_data);
|
||||||
free (guessed_xdg_home);
|
free (guessed_xdg_home);
|
||||||
|
|
||||||
|
if (stop_processing)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,6 +213,7 @@ xdg_mime_init (void)
|
|||||||
const char *end_ptr;
|
const char *end_ptr;
|
||||||
char *dir;
|
char *dir;
|
||||||
int len;
|
int len;
|
||||||
|
int stop_processing;
|
||||||
|
|
||||||
end_ptr = ptr;
|
end_ptr = ptr;
|
||||||
while (*end_ptr != ':' && *end_ptr != '\000')
|
while (*end_ptr != ':' && *end_ptr != '\000')
|
||||||
@ -125,12 +232,155 @@ xdg_mime_init (void)
|
|||||||
dir = malloc (len + 1);
|
dir = malloc (len + 1);
|
||||||
strncpy (dir, ptr, len);
|
strncpy (dir, ptr, len);
|
||||||
dir[len] = '\0';
|
dir[len] = '\0';
|
||||||
_xdg_mime_init_from_directory (dir);
|
stop_processing = (func) (dir, user_data);
|
||||||
free (dir);
|
free (dir);
|
||||||
|
|
||||||
|
if (stop_processing)
|
||||||
|
return;
|
||||||
|
|
||||||
ptr = end_ptr;
|
ptr = end_ptr;
|
||||||
}
|
}
|
||||||
initted = 1;
|
}
|
||||||
|
|
||||||
|
/* Checks file_path to make sure it has the same mtime as last time it was
|
||||||
|
* checked. If it has a different mtime, or if the file doesn't exist, it
|
||||||
|
* returns FALSE.
|
||||||
|
*
|
||||||
|
* FIXME: This doesn't protect against permission changes.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xdg_check_file (const char *file_path)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
/* If the file exists */
|
||||||
|
if (stat (file_path, &st) == 0)
|
||||||
|
{
|
||||||
|
XdgDirTimeList *list;
|
||||||
|
|
||||||
|
for (list = dir_time_list; list; list = list->next)
|
||||||
|
{
|
||||||
|
if (! strcmp (list->directory_name, file_path) &&
|
||||||
|
st.st_mtime == list->mtime)
|
||||||
|
{
|
||||||
|
if (list->checked == XDG_CHECKED_UNCHECKED)
|
||||||
|
list->checked = XDG_CHECKED_VALID;
|
||||||
|
else if (list->checked == XDG_CHECKED_VALID)
|
||||||
|
list->checked = XDG_CHECKED_INVALID;
|
||||||
|
|
||||||
|
return (list->checked != XDG_CHECKED_VALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xdg_check_dir (const char *directory,
|
||||||
|
int *invalid_dir_list)
|
||||||
|
{
|
||||||
|
int invalid;
|
||||||
|
char *file_name;
|
||||||
|
|
||||||
|
assert (directory != NULL);
|
||||||
|
|
||||||
|
/* Check the globs file */
|
||||||
|
file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
|
||||||
|
strcpy (file_name, directory); strcat (file_name, "/mime/globs");
|
||||||
|
invalid = xdg_check_file (file_name);
|
||||||
|
free (file_name);
|
||||||
|
if (invalid)
|
||||||
|
{
|
||||||
|
*invalid_dir_list = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the magic file */
|
||||||
|
file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
|
||||||
|
strcpy (file_name, directory); strcat (file_name, "/mime/magic");
|
||||||
|
invalid = xdg_check_file (file_name);
|
||||||
|
free (file_name);
|
||||||
|
if (invalid)
|
||||||
|
{
|
||||||
|
*invalid_dir_list = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE; /* Keep processing */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walks through all the mime files stat()ing them to see if they've changed.
|
||||||
|
* Returns TRUE if they have. */
|
||||||
|
static int
|
||||||
|
xdg_check_dirs (void)
|
||||||
|
{
|
||||||
|
XdgDirTimeList *list;
|
||||||
|
int invalid_dir_list = FALSE;
|
||||||
|
|
||||||
|
for (list = dir_time_list; list; list = list->next)
|
||||||
|
list->checked = XDG_CHECKED_UNCHECKED;
|
||||||
|
|
||||||
|
xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_check_dir,
|
||||||
|
&invalid_dir_list);
|
||||||
|
|
||||||
|
if (invalid_dir_list)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
for (list = dir_time_list; list; list = list->next)
|
||||||
|
{
|
||||||
|
if (list->checked != XDG_CHECKED_VALID)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We want to avoid stat()ing on every single mime call, so we only look for
|
||||||
|
* newer files every 5 seconds. This will return TRUE if we need to reread the
|
||||||
|
* mime data from disk.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xdg_check_time_and_dirs (void)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
time_t current_time;
|
||||||
|
int retval = FALSE;
|
||||||
|
|
||||||
|
gettimeofday (&tv, NULL);
|
||||||
|
current_time = tv.tv_sec;
|
||||||
|
|
||||||
|
if (current_time >= last_stat_time + 5)
|
||||||
|
{
|
||||||
|
retval = xdg_check_dirs ();
|
||||||
|
last_stat_time = current_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called in every public function. It reloads the hash function if need be.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xdg_mime_init (void)
|
||||||
|
{
|
||||||
|
if (xdg_check_time_and_dirs ())
|
||||||
|
{
|
||||||
|
xdg_mime_shutdown ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_reread)
|
||||||
|
{
|
||||||
|
global_hash = _xdg_glob_hash_new ();
|
||||||
|
global_magic = _xdg_mime_magic_new ();
|
||||||
|
alias_list = _xdg_mime_alias_list_new ();
|
||||||
|
parent_list = _xdg_mime_parent_list_new ();
|
||||||
|
|
||||||
|
xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_mime_init_from_directory,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
need_reread = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,17 +489,36 @@ xdg_mime_is_valid_mime_type (const char *mime_type)
|
|||||||
void
|
void
|
||||||
xdg_mime_shutdown (void)
|
xdg_mime_shutdown (void)
|
||||||
{
|
{
|
||||||
|
XdgCallbackList *list;
|
||||||
|
|
||||||
/* FIXME: Need to make this (and the whole library) thread safe */
|
/* FIXME: Need to make this (and the whole library) thread safe */
|
||||||
if (initted)
|
if (dir_time_list)
|
||||||
|
{
|
||||||
|
xdg_dir_time_list_free (dir_time_list);
|
||||||
|
dir_time_list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global_hash)
|
||||||
{
|
{
|
||||||
_xdg_glob_hash_free (global_hash);
|
_xdg_glob_hash_free (global_hash);
|
||||||
global_hash = NULL;
|
global_hash = NULL;
|
||||||
|
}
|
||||||
|
if (global_magic)
|
||||||
|
{
|
||||||
_xdg_mime_magic_free (global_magic);
|
_xdg_mime_magic_free (global_magic);
|
||||||
global_magic = NULL;
|
global_magic = NULL;
|
||||||
|
|
||||||
initted = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alias_list)
|
||||||
|
{
|
||||||
|
_xdg_mime_alias_list_free (alias_list);
|
||||||
|
alias_list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (list = callback_list; list; list = list->next)
|
||||||
|
(list->callback) (list->data);
|
||||||
|
|
||||||
|
need_reread = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -259,3 +528,165 @@ xdg_mime_get_max_buffer_extents (void)
|
|||||||
|
|
||||||
return _xdg_mime_magic_get_buffer_extents (global_magic);
|
return _xdg_mime_magic_get_buffer_extents (global_magic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
unalias_mime_type (const char *mime_type)
|
||||||
|
{
|
||||||
|
const char *lookup;
|
||||||
|
|
||||||
|
if ((lookup = _xdg_mime_alias_list_lookup (alias_list, mime_type)) != NULL)
|
||||||
|
return lookup;
|
||||||
|
|
||||||
|
return mime_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xdg_mime_mime_type_equal (const char *mime_a,
|
||||||
|
const char *mime_b)
|
||||||
|
{
|
||||||
|
const char *unalias_a, *unalias_b;
|
||||||
|
|
||||||
|
xdg_mime_init ();
|
||||||
|
|
||||||
|
unalias_a = unalias_mime_type (mime_a);
|
||||||
|
unalias_b = unalias_mime_type (mime_b);
|
||||||
|
|
||||||
|
if (strcmp (unalias_a, unalias_b) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xdg_mime_media_type_equal (const char *mime_a,
|
||||||
|
const char *mime_b)
|
||||||
|
{
|
||||||
|
char *sep;
|
||||||
|
|
||||||
|
xdg_mime_init ();
|
||||||
|
|
||||||
|
sep = strchr (mime_a, '/');
|
||||||
|
|
||||||
|
if (sep && strncmp (mime_a, mime_b, sep - mime_a + 1) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int
|
||||||
|
xdg_mime_is_super_type (const char *mime)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
const char *type;
|
||||||
|
|
||||||
|
length = strlen (mime);
|
||||||
|
type = &(mime[length - 2]);
|
||||||
|
|
||||||
|
if (strcmp (type, "/*") == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
xdg_mime_mime_type_subclass (const char *mime,
|
||||||
|
const char *base)
|
||||||
|
{
|
||||||
|
const char *umime, *ubase;
|
||||||
|
const char **parents;
|
||||||
|
|
||||||
|
xdg_mime_init ();
|
||||||
|
|
||||||
|
umime = unalias_mime_type (mime);
|
||||||
|
ubase = unalias_mime_type (base);
|
||||||
|
|
||||||
|
if (strcmp (umime, ubase) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Handle supertypes */
|
||||||
|
if (xdg_mime_is_super_type (ubase) &&
|
||||||
|
xdg_mime_media_type_equal (umime, ubase))
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Handle special cases text/plain and application/octet-stream */
|
||||||
|
if (strcmp (ubase, "text/plain") == 0 &&
|
||||||
|
strncmp (umime, "text/", 5) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (strcmp (ubase, "application/octet-stream") == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
parents = _xdg_mime_parent_list_lookup (parent_list, umime);
|
||||||
|
for (; parents && *parents; parents++)
|
||||||
|
{
|
||||||
|
if (xdg_mime_mime_type_subclass (*parents, ubase))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xdg_mime_dump (void)
|
||||||
|
{
|
||||||
|
printf ("*** ALIASES ***\n\n");
|
||||||
|
_xdg_mime_alias_list_dump (alias_list);
|
||||||
|
printf ("\n*** PARENTS ***\n\n");
|
||||||
|
_xdg_mime_parent_list_dump (parent_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Registers a function to be called every time the mime database reloads its files
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xdg_mime_register_reload_callback (XdgMimeCallback callback,
|
||||||
|
void *data,
|
||||||
|
XdgMimeDestroy destroy)
|
||||||
|
{
|
||||||
|
XdgCallbackList *list_el;
|
||||||
|
static int callback_id = 1;
|
||||||
|
|
||||||
|
/* Make a new list element */
|
||||||
|
list_el = calloc (1, sizeof (XdgCallbackList));
|
||||||
|
list_el->callback_id = callback_id;
|
||||||
|
list_el->callback = callback;
|
||||||
|
list_el->data = data;
|
||||||
|
list_el->destroy = destroy;
|
||||||
|
list_el->next = callback_list;
|
||||||
|
if (list_el->next)
|
||||||
|
list_el->next->prev = list_el;
|
||||||
|
|
||||||
|
callback_list = list_el;
|
||||||
|
callback_id ++;
|
||||||
|
|
||||||
|
return callback_id - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xdg_mime_remove_callback (int callback_id)
|
||||||
|
{
|
||||||
|
XdgCallbackList *list;
|
||||||
|
|
||||||
|
for (list = callback_list; list; list = list->next)
|
||||||
|
{
|
||||||
|
if (list->callback_id == callback_id)
|
||||||
|
{
|
||||||
|
if (list->next)
|
||||||
|
list->next = list->prev;
|
||||||
|
|
||||||
|
if (list->prev)
|
||||||
|
list->prev->next = list->next;
|
||||||
|
else
|
||||||
|
callback_list = list->next;
|
||||||
|
|
||||||
|
/* invoke the destroy handler */
|
||||||
|
(list->destroy) (list->data);
|
||||||
|
free (list);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -41,15 +41,22 @@ extern "C" {
|
|||||||
#define _XDG_ENTRY3(prefix,func) prefix##_##func
|
#define _XDG_ENTRY3(prefix,func) prefix##_##func
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef void (*XdgMimeCallback) (void *user_data);
|
||||||
|
typedef void (*XdgMimeDestroy) (void *user_data);
|
||||||
|
|
||||||
|
|
||||||
#ifdef XDG_PREFIX
|
#ifdef XDG_PREFIX
|
||||||
#define xdg_mime_get_mime_type_for_data XDG_ENTRY(get_mime_type_for_data)
|
#define xdg_mime_get_mime_type_for_data XDG_ENTRY(get_mime_type_for_data)
|
||||||
#define xdg_mime_get_mime_type_for_file XDG_ENTRY(get_mime_type_for_file)
|
#define xdg_mime_get_mime_type_for_file XDG_ENTRY(get_mime_type_for_file)
|
||||||
#define xdg_mime_get_mime_type_from_file_name XDG_ENTRY(get_mime_type_from_file_name)
|
#define xdg_mime_get_mime_type_from_file_name XDG_ENTRY(get_mime_type_from_file_name)
|
||||||
#define xdg_mime_is_valid_mime_type XDG_ENTRY(is_valid_mime_type)
|
#define xdg_mime_is_valid_mime_type XDG_ENTRY(is_valid_mime_type)
|
||||||
|
#define xdg_mime_mime_type_equal XDG_ENTRY(mime_type_equal)
|
||||||
|
#define xdg_mime_mime_type_subclass XDG_ENTRY(mime_type_subclass)
|
||||||
#define xdg_mime_get_max_buffer_extents XDG_ENTRY(get_max_buffer_extents)
|
#define xdg_mime_get_max_buffer_extents XDG_ENTRY(get_max_buffer_extents)
|
||||||
#define xdg_mime_type_unknown XDG_ENTRY(type_unknown)
|
|
||||||
#define xdg_mime_shutdown XDG_ENTRY(shutdown)
|
#define xdg_mime_shutdown XDG_ENTRY(shutdown)
|
||||||
|
#define xdg_mime_register_reload_callback XDG_ENTRY(register_reload_callback)
|
||||||
|
#define xdg_mime_remove_callback XDG_ENTRY(remove_callback)
|
||||||
|
#define xdg_mime_type_unknown XDG_ENTRY(type_unknown)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const char *xdg_mime_type_unknown;
|
extern const char *xdg_mime_type_unknown;
|
||||||
@ -60,9 +67,19 @@ const char *xdg_mime_get_mime_type_for_data (const void *data,
|
|||||||
const char *xdg_mime_get_mime_type_for_file (const char *file_name);
|
const char *xdg_mime_get_mime_type_for_file (const char *file_name);
|
||||||
const char *xdg_mime_get_mime_type_from_file_name (const char *file_name);
|
const char *xdg_mime_get_mime_type_from_file_name (const char *file_name);
|
||||||
int xdg_mime_is_valid_mime_type (const char *mime_type);
|
int xdg_mime_is_valid_mime_type (const char *mime_type);
|
||||||
|
int xdg_mime_mime_type_equal (const char *mime_a,
|
||||||
|
const char *mime_b);
|
||||||
|
int xdg_mime_media_type_equal (const char *mime_a,
|
||||||
|
const char *mime_b);
|
||||||
|
int xdg_mime_mime_type_subclass (const char *mime_a,
|
||||||
|
const char *mime_b);
|
||||||
int xdg_mime_get_max_buffer_extents (void);
|
int xdg_mime_get_max_buffer_extents (void);
|
||||||
void xdg_mime_shutdown (void);
|
void xdg_mime_shutdown (void);
|
||||||
|
void xdg_mime_dump (void);
|
||||||
|
int xdg_mime_register_reload_callback (XdgMimeCallback callback,
|
||||||
|
void *data,
|
||||||
|
XdgMimeDestroy destroy);
|
||||||
|
void xdg_mime_remove_callback (int callback_id);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
177
gtk/xdgmime/xdgmimealias.c
Normal file
177
gtk/xdgmime/xdgmimealias.c
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||||
|
/* xdgmimealias.c: Private file. Datastructure for storing the aliases.
|
||||||
|
*
|
||||||
|
* More info can be found at http://www.freedesktop.org/standards/
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Red Hat, Inc.
|
||||||
|
* Copyright (C) 2004 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Academic Free License version 2.0
|
||||||
|
* Or under the following terms:
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include "xdgmimealias.h"
|
||||||
|
#include "xdgmimeint.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE (!FALSE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct XdgAlias XdgAlias;
|
||||||
|
|
||||||
|
struct XdgAlias
|
||||||
|
{
|
||||||
|
char *alias;
|
||||||
|
char *mime_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct XdgAliasList
|
||||||
|
{
|
||||||
|
struct XdgAlias *aliases;
|
||||||
|
int n_aliases;
|
||||||
|
};
|
||||||
|
|
||||||
|
XdgAliasList *
|
||||||
|
_xdg_mime_alias_list_new (void)
|
||||||
|
{
|
||||||
|
XdgAliasList *list;
|
||||||
|
|
||||||
|
list = malloc (sizeof (XdgAliasList));
|
||||||
|
|
||||||
|
list->aliases = NULL;
|
||||||
|
list->n_aliases = 0;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_alias_list_free (XdgAliasList *list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (list->aliases)
|
||||||
|
{
|
||||||
|
for (i = 0; i < list->n_aliases; i++)
|
||||||
|
{
|
||||||
|
free (list->aliases[i].alias);
|
||||||
|
free (list->aliases[i].mime_type);
|
||||||
|
}
|
||||||
|
free (list->aliases);
|
||||||
|
}
|
||||||
|
free (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
alias_entry_cmp (const void *v1, const void *v2)
|
||||||
|
{
|
||||||
|
return strcmp (((XdgAlias *)v1)->alias, ((XdgAlias *)v2)->alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
_xdg_mime_alias_list_lookup (XdgAliasList *list,
|
||||||
|
const char *alias)
|
||||||
|
{
|
||||||
|
XdgAlias *entry;
|
||||||
|
XdgAlias key;
|
||||||
|
|
||||||
|
key.alias = (char *)alias;
|
||||||
|
key.mime_type = 0;
|
||||||
|
|
||||||
|
entry = bsearch (&key, list->aliases, list->n_aliases,
|
||||||
|
sizeof (XdgAlias), alias_entry_cmp);
|
||||||
|
if (entry)
|
||||||
|
return entry->mime_type;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_alias_read_from_file (XdgAliasList *list,
|
||||||
|
const char *file_name)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
char line[255];
|
||||||
|
int alloc;
|
||||||
|
|
||||||
|
file = fopen (file_name, "r");
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars.
|
||||||
|
* Blah */
|
||||||
|
alloc = 16;
|
||||||
|
list->aliases = malloc (alloc * sizeof (XdgAlias));
|
||||||
|
while (fgets (line, 255, file) != NULL)
|
||||||
|
{
|
||||||
|
char *sep;
|
||||||
|
if (line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sep = strchr (line, ' ');
|
||||||
|
if (sep == NULL)
|
||||||
|
continue;
|
||||||
|
*(sep++) = '\000';
|
||||||
|
sep[strlen (sep) -1] = '\000';
|
||||||
|
if (list->n_aliases == alloc)
|
||||||
|
{
|
||||||
|
alloc <<= 1;
|
||||||
|
list->aliases = realloc (list->aliases,
|
||||||
|
alloc * sizeof (XdgAlias));
|
||||||
|
}
|
||||||
|
list->aliases[list->n_aliases].alias = strdup (line);
|
||||||
|
list->aliases[list->n_aliases].mime_type = strdup (sep);
|
||||||
|
list->n_aliases++;
|
||||||
|
}
|
||||||
|
list->aliases = realloc (list->aliases,
|
||||||
|
list->n_aliases * sizeof (XdgAlias));
|
||||||
|
|
||||||
|
fclose (file);
|
||||||
|
|
||||||
|
qsort (list->aliases, list->n_aliases,
|
||||||
|
sizeof (XdgAlias), alias_entry_cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_alias_list_dump (XdgAliasList *list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (list->aliases)
|
||||||
|
{
|
||||||
|
for (i = 0; i < list->n_aliases; i++)
|
||||||
|
{
|
||||||
|
printf ("%s %s\n",
|
||||||
|
list->aliases[i].alias,
|
||||||
|
list->aliases[i].mime_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
50
gtk/xdgmime/xdgmimealias.h
Normal file
50
gtk/xdgmime/xdgmimealias.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||||
|
/* xdgmimealias.h: Private file. Datastructure for storing the aliases.
|
||||||
|
*
|
||||||
|
* More info can be found at http://www.freedesktop.org/standards/
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Red Hat, Inc.
|
||||||
|
* Copyright (C) 200 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Academic Free License version 2.0
|
||||||
|
* Or under the following terms:
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XDG_MIME_ALIAS_H__
|
||||||
|
#define __XDG_MIME_ALIAS_H__
|
||||||
|
|
||||||
|
#include "xdgmime.h"
|
||||||
|
|
||||||
|
typedef struct XdgAliasList XdgAliasList;
|
||||||
|
|
||||||
|
#ifdef XDG_PREFIX
|
||||||
|
#define _xdg_mime_alias_read_from_file XDG_ENTRY(alias_read_from_file)
|
||||||
|
#define _xdg_mime_alias_list_new XDG_ENTRY(alias_list_new)
|
||||||
|
#define _xdg_mime_alias_list_free XDG_ENTRY(alias_list_free)
|
||||||
|
#define _xdg_mime_alias_list_lookup XDG_ENTRY(alias_list_lookup)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _xdg_mime_alias_read_from_file (XdgAliasList *list,
|
||||||
|
const char *file_name);
|
||||||
|
XdgAliasList *_xdg_mime_alias_list_new (void);
|
||||||
|
void _xdg_mime_alias_list_free (XdgAliasList *list);
|
||||||
|
const char *_xdg_mime_alias_list_lookup (XdgAliasList *list,
|
||||||
|
const char *alias);
|
||||||
|
void _xdg_mime_alias_list_dump (XdgAliasList *list);
|
||||||
|
|
||||||
|
#endif /* __XDG_MIME_ALIAS_H__ */
|
@ -348,6 +348,8 @@ _xdg_glob_hash_free_nodes (XdgGlobHashNode *node)
|
|||||||
_xdg_glob_hash_free_nodes (node->child);
|
_xdg_glob_hash_free_nodes (node->child);
|
||||||
if (node->next)
|
if (node->next)
|
||||||
_xdg_glob_hash_free_nodes (node->next);
|
_xdg_glob_hash_free_nodes (node->next);
|
||||||
|
if (node->mime_type)
|
||||||
|
free ((void *) node->mime_type);
|
||||||
free (node);
|
free (node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,16 @@
|
|||||||
|
|
||||||
#include "xdgmime.h"
|
#include "xdgmime.h"
|
||||||
|
|
||||||
/* FIXME: Should be configure check */
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE (!FALSE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: Needs to be configure check */
|
||||||
typedef unsigned int xdg_unichar_t;
|
typedef unsigned int xdg_unichar_t;
|
||||||
typedef unsigned char xdg_uchar8_t;
|
typedef unsigned char xdg_uchar8_t;
|
||||||
typedef unsigned short xdg_uint16_t;
|
typedef unsigned short xdg_uint16_t;
|
||||||
|
@ -636,9 +636,11 @@ _xdg_mime_magic_new (void)
|
|||||||
void
|
void
|
||||||
_xdg_mime_magic_free (XdgMimeMagic *mime_magic)
|
_xdg_mime_magic_free (XdgMimeMagic *mime_magic)
|
||||||
{
|
{
|
||||||
if (mime_magic)
|
if (mime_magic) {
|
||||||
|
_xdg_mime_magic_match_free (mime_magic->match_list);
|
||||||
free (mime_magic);
|
free (mime_magic);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_xdg_mime_magic_get_buffer_extents (XdgMimeMagic *mime_magic)
|
_xdg_mime_magic_get_buffer_extents (XdgMimeMagic *mime_magic)
|
||||||
|
211
gtk/xdgmime/xdgmimeparent.c
Normal file
211
gtk/xdgmime/xdgmimeparent.c
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||||
|
/* xdgmimealias.c: Private file. Datastructure for storing the hierarchy.
|
||||||
|
*
|
||||||
|
* More info can be found at http://www.freedesktop.org/standards/
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Red Hat, Inc.
|
||||||
|
* Copyright (C) 2004 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Academic Free License version 2.0
|
||||||
|
* Or under the following terms:
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include "xdgmimeparent.h"
|
||||||
|
#include "xdgmimeint.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE (!FALSE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct XdgMimeParents XdgMimeParents;
|
||||||
|
|
||||||
|
struct XdgMimeParents
|
||||||
|
{
|
||||||
|
char *mime;
|
||||||
|
char **parents;
|
||||||
|
int n_parents;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct XdgParentList
|
||||||
|
{
|
||||||
|
struct XdgMimeParents *parents;
|
||||||
|
int n_mimes;
|
||||||
|
};
|
||||||
|
|
||||||
|
XdgParentList *
|
||||||
|
_xdg_mime_parent_list_new (void)
|
||||||
|
{
|
||||||
|
XdgParentList *list;
|
||||||
|
|
||||||
|
list = malloc (sizeof (XdgParentList));
|
||||||
|
|
||||||
|
list->parents = NULL;
|
||||||
|
list->n_mimes = 0;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_parent_list_free (XdgParentList *list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char **p;
|
||||||
|
|
||||||
|
if (list->parents)
|
||||||
|
{
|
||||||
|
for (i = 0; i < list->n_mimes; i++)
|
||||||
|
{
|
||||||
|
for (p = list->parents[i].parents; *p; p++)
|
||||||
|
free (*p);
|
||||||
|
|
||||||
|
free (list->parents[i].parents);
|
||||||
|
free (list->parents[i].mime);
|
||||||
|
}
|
||||||
|
free (list->parents);
|
||||||
|
}
|
||||||
|
free (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parent_entry_cmp (const void *v1, const void *v2)
|
||||||
|
{
|
||||||
|
return strcmp (((XdgMimeParents *)v1)->mime, ((XdgMimeParents *)v2)->mime);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char **
|
||||||
|
_xdg_mime_parent_list_lookup (XdgParentList *list,
|
||||||
|
const char *mime)
|
||||||
|
{
|
||||||
|
XdgMimeParents *entry;
|
||||||
|
XdgMimeParents key;
|
||||||
|
|
||||||
|
key.mime = (char *)mime;
|
||||||
|
key.parents = NULL;
|
||||||
|
|
||||||
|
entry = bsearch (&key, list->parents, list->n_mimes,
|
||||||
|
sizeof (XdgMimeParents), &parent_entry_cmp);
|
||||||
|
if (entry)
|
||||||
|
return (const char **)entry->parents;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_parent_read_from_file (XdgParentList *list,
|
||||||
|
const char *file_name)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
char line[255];
|
||||||
|
int i, alloc;
|
||||||
|
XdgMimeParents *entry;
|
||||||
|
|
||||||
|
file = fopen (file_name, "r");
|
||||||
|
|
||||||
|
if (file == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars.
|
||||||
|
* Blah */
|
||||||
|
alloc = 16;
|
||||||
|
list->parents = malloc (alloc * sizeof (XdgMimeParents));
|
||||||
|
while (fgets (line, 255, file) != NULL)
|
||||||
|
{
|
||||||
|
char *sep;
|
||||||
|
if (line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sep = strchr (line, ' ');
|
||||||
|
if (sep == NULL)
|
||||||
|
continue;
|
||||||
|
*(sep++) = '\000';
|
||||||
|
sep[strlen (sep) -1] = '\000';
|
||||||
|
entry = NULL;
|
||||||
|
for (i = 0; i < list->n_mimes; i++)
|
||||||
|
{
|
||||||
|
if (strcmp (list->parents[i].mime, line) == 0)
|
||||||
|
{
|
||||||
|
entry = &(list->parents[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
{
|
||||||
|
if (list->n_mimes == alloc)
|
||||||
|
{
|
||||||
|
alloc <<= 1;
|
||||||
|
list->parents = realloc (list->parents,
|
||||||
|
alloc * sizeof (XdgMimeParents));
|
||||||
|
}
|
||||||
|
list->parents[list->n_mimes].mime = strdup (line);
|
||||||
|
entry = &(list->parents[list->n_mimes]);
|
||||||
|
list->n_mimes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entry->parents)
|
||||||
|
{
|
||||||
|
entry->n_parents = 1;
|
||||||
|
entry->parents = malloc ((entry->n_parents + 1) * sizeof (char *));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry->n_parents += 1;
|
||||||
|
entry->parents = realloc (entry->parents,
|
||||||
|
(entry->n_parents + 2) * sizeof (char *));
|
||||||
|
}
|
||||||
|
entry->parents[entry->n_parents - 1] = strdup (sep);
|
||||||
|
entry->parents[entry->n_parents] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->parents = realloc (list->parents,
|
||||||
|
list->n_mimes * sizeof (XdgMimeParents));
|
||||||
|
|
||||||
|
fclose (file);
|
||||||
|
|
||||||
|
qsort (list->parents, list->n_mimes,
|
||||||
|
sizeof (XdgMimeParents), &parent_entry_cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_xdg_mime_parent_list_dump (XdgParentList *list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char **p;
|
||||||
|
|
||||||
|
if (list->parents)
|
||||||
|
{
|
||||||
|
for (i = 0; i < list->n_mimes; i++)
|
||||||
|
{
|
||||||
|
for (p = list->parents[i].parents; *p; p++)
|
||||||
|
printf ("%s %s\n", list->parents[i].mime, *p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
50
gtk/xdgmime/xdgmimeparent.h
Normal file
50
gtk/xdgmime/xdgmimeparent.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||||
|
/* xdgmimeparent.h: Private file. Datastructure for storing the hierarchy.
|
||||||
|
*
|
||||||
|
* More info can be found at http://www.freedesktop.org/standards/
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Red Hat, Inc.
|
||||||
|
* Copyright (C) 200 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Academic Free License version 2.0
|
||||||
|
* Or under the following terms:
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XDG_MIME_PARENT_H__
|
||||||
|
#define __XDG_MIME_PARENT_H__
|
||||||
|
|
||||||
|
#include "xdgmime.h"
|
||||||
|
|
||||||
|
typedef struct XdgParentList XdgParentList;
|
||||||
|
|
||||||
|
#ifdef XDG_PREFIX
|
||||||
|
#define _xdg_mime_parent_read_from_file XDG_ENTRY(parent_read_from_file)
|
||||||
|
#define _xdg_mime_parent_list_new XDG_ENTRY(parent_list_new)
|
||||||
|
#define _xdg_mime_parent_list_free XDG_ENTRY(parent_list_free)
|
||||||
|
#define _xdg_mime_parent_list_lookup XDG_ENTRY(parent_list_lookup)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _xdg_mime_parent_read_from_file (XdgParentList *list,
|
||||||
|
const char *file_name);
|
||||||
|
XdgParentList *_xdg_mime_parent_list_new (void);
|
||||||
|
void _xdg_mime_parent_list_free (XdgParentList *list);
|
||||||
|
const char **_xdg_mime_parent_list_lookup (XdgParentList *list,
|
||||||
|
const char *mime);
|
||||||
|
void _xdg_mime_parent_list_dump (XdgParentList *list);
|
||||||
|
|
||||||
|
#endif /* __XDG_MIME_PARENT_H__ */
|
Loading…
Reference in New Issue
Block a user