1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* xdgmime.c: XDG Mime Spec mime resolver. Based on version 0.11 of the spec.
4 * More info can be found at http://www.freedesktop.org/standards/
6 * Copyright (C) 2003 Red Hat, Inc.
7 * Copyright (C) 2003 Jonathan Blandford <jrb@alum.mit.edu>
9 * Licensed under the Academic Free License version 2.0
10 * Or under the following terms:
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the
24 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 * Boston, MA 02111-1307, USA.
32 #include "xdgmimeint.h"
33 #include "xdgmimeglob.h"
34 #include "xdgmimemagic.h"
38 #include <sys/types.h>
41 static int initted
= 0;
42 static XdgGlobHash
*global_hash
= NULL
;
43 static XdgMimeMagic
*global_magic
= NULL
;
44 const char *xdg_mime_type_unknown
= "application/octet-stream";
47 _xdg_mime_init_from_directory (const char *directory
)
51 file_name
= malloc (strlen (directory
) + strlen ("/mime/globs") + 1);
52 strcpy (file_name
, directory
);
53 strcat (file_name
, "/mime/globs");
54 _xdg_mime_glob_read_from_file (global_hash
, file_name
);
57 file_name
= malloc (strlen (directory
) + strlen ("/mime/magic") + 1);
58 strcpy (file_name
, directory
);
59 strcat (file_name
, "/mime/magic");
60 _xdg_mime_magic_read_from_file (global_magic
, file_name
);
69 const char *xdg_data_home
;
70 const char *xdg_data_dirs
;
73 global_hash
= _xdg_glob_hash_new ();
74 global_magic
= _xdg_mime_magic_new ();
76 /* We look for globs and magic files based upon the XDG Base Directory
79 xdg_data_home
= getenv ("XDG_DATA_HOME");
82 _xdg_mime_init_from_directory (xdg_data_home
);
88 home
= getenv ("HOME");
91 char *guessed_xdg_home
;
93 guessed_xdg_home
= malloc (strlen (home
) + strlen ("/.local/share/") + 1);
94 strcpy (guessed_xdg_home
, home
);
95 strcat (guessed_xdg_home
, "/.local/share/");
96 _xdg_mime_init_from_directory (guessed_xdg_home
);
97 free (guessed_xdg_home
);
101 xdg_data_dirs
= getenv ("XDG_DATA_DIRS");
102 if (xdg_data_dirs
== NULL
)
103 xdg_data_dirs
= "/usr/local/share/:/usr/share/";
107 while (*ptr
!= '\000')
114 while (*end_ptr
!= ':' && *end_ptr
!= '\000')
126 len
= end_ptr
- ptr
+ 1;
127 dir
= malloc (len
+ 1);
128 strncpy (dir
, ptr
, len
);
130 _xdg_mime_init_from_directory (dir
);
140 xdg_mime_get_mime_type_for_data (const void *data
,
143 const char *mime_type
;
147 mime_type
= _xdg_mime_magic_lookup_data (global_magic
, data
, len
);
152 return XDG_MIME_TYPE_UNKNOWN
;
156 xdg_mime_get_mime_type_for_file (const char *file_name
)
158 const char *mime_type
;
164 const char *base_name
;
166 if (file_name
== NULL
)
168 if (! _xdg_utf8_validate (file_name
))
173 base_name
= _xdg_get_base_name (file_name
);
174 mime_type
= xdg_mime_get_mime_type_from_file_name (base_name
);
176 if (mime_type
!= XDG_MIME_TYPE_UNKNOWN
)
179 if (stat (file_name
, &statbuf
) != 0)
180 return XDG_MIME_TYPE_UNKNOWN
;
182 if (!S_ISREG (statbuf
.st_mode
))
183 return XDG_MIME_TYPE_UNKNOWN
;
185 /* FIXME: Need to make sure that max_extent isn't totally broken. This could
186 * be large and need getting from a stream instead of just reading it all
188 max_extent
= _xdg_mime_magic_get_buffer_extents (global_magic
);
189 data
= malloc (max_extent
);
191 return XDG_MIME_TYPE_UNKNOWN
;
193 file
= fopen (file_name
, "r");
197 return XDG_MIME_TYPE_UNKNOWN
;
200 bytes_read
= fread (data
, 1, max_extent
, file
);
205 return XDG_MIME_TYPE_UNKNOWN
;
208 mime_type
= _xdg_mime_magic_lookup_data (global_magic
, data
, bytes_read
);
216 return XDG_MIME_TYPE_UNKNOWN
;
220 xdg_mime_get_mime_type_from_file_name (const char *file_name
)
222 const char *mime_type
;
226 mime_type
= _xdg_glob_hash_lookup_file_name (global_hash
, file_name
);
230 return XDG_MIME_TYPE_UNKNOWN
;
234 xdg_mime_is_valid_mime_type (const char *mime_type
)
236 /* FIXME: We should make this a better test
238 return _xdg_utf8_validate (mime_type
);
242 xdg_mime_shutdown (void)
244 /* FIXME: Need to make this (and the whole library) thread safe */
247 _xdg_glob_hash_free (global_hash
);
250 _xdg_mime_magic_free (global_magic
);
258 xdg_mime_get_max_buffer_extents (void)
262 return _xdg_mime_magic_get_buffer_extents (global_magic
);