1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2
3 /*
4 * GImageView
5 * Copyright (C) 2001-2002 Takuro Ashie
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * $Id: gimv_mime_types.c,v 1.2 2003/06/13 09:43:32 makeinu Exp $
22 */
23
24 #include "gimv_mime_types.h"
25 #include "prefs.h"
26
27 #include <string.h>
28
29 #define MAX_EXT_LEN 32
30
31 static GHashTable *mime_types_table = NULL;
32
33 /* global extensions list */
34 static GList *known_ext_list = NULL;
35 static GList *known_enabled_ext_list = NULL;
36 static GHashTable *known_ext_mimetype_table = NULL;
37
38 static GList *userdef_ext_list = NULL;
39 static GHashTable *userdef_ext_mimetype_table = NULL;
40
41
42 static GimvMimeType *
gimv_mime_type_new_from_entry(GimvMimeTypeEntry * entry)43 gimv_mime_type_new_from_entry (GimvMimeTypeEntry *entry)
44 {
45 GimvMimeType *mtype;
46
47 g_return_val_if_fail (entry, FALSE);
48
49 mtype = g_new0 (GimvMimeType, 1);
50 mtype->mime_type = g_strdup (entry->mime_type);
51 mtype->extensions_list = NULL;
52 mtype->plugins_list = NULL;
53 mtype->icons_list = NULL;
54
55 /* FIXME!! add icon */
56
57 return mtype;
58 }
59
60
61 gboolean
gimv_mime_types_regist(GimvMimeTypeEntry * entry,GModule * module)62 gimv_mime_types_regist (GimvMimeTypeEntry *entry,
63 GModule *module)
64 {
65 GimvMimeType *mtype;
66 gint i;
67
68 g_return_val_if_fail (entry, FALSE);
69
70 if (!mime_types_table)
71 mime_types_table = g_hash_table_new (g_str_hash, g_str_equal);
72
73 mtype = g_hash_table_lookup (mime_types_table, entry->mime_type);
74 if (!mtype) {
75 mtype = gimv_mime_type_new_from_entry (entry);
76 mtype->plugins_list = g_list_append (mtype->plugins_list, module);
77 g_hash_table_insert (mime_types_table,
78 (gchar *) mtype->mime_type, mtype);
79 }
80
81 for (i = 0; i < entry->extensions_len; i++) {
82 gimv_mime_types_add_extension (entry->mime_type,
83 entry->extensions[i]);
84 }
85
86 return TRUE;
87 }
88
89
90 /* FIXME: use hash? */
91 static gboolean
sysdef_check_enable(const gchar * ext)92 sysdef_check_enable (const gchar *ext)
93 {
94 static gchar *old_conf = NULL, **sysdef_disables = NULL;
95 gint i;
96
97 /* create disabled list */
98 if ((old_conf != conf.imgtype_disables)
99 && conf.imgtype_disables && *conf.imgtype_disables)
100 {
101 if (sysdef_disables)
102 g_strfreev (sysdef_disables);
103 sysdef_disables = g_strsplit (conf.imgtype_disables, ",", -1);
104 if (sysdef_disables)
105 for (i = 0; sysdef_disables[i]; i++)
106 if (*sysdef_disables[i]) {
107 g_strstrip (sysdef_disables[i]);
108 g_strdown (sysdef_disables[i]);
109 }
110 old_conf = conf.imgtype_disables;
111 }
112
113 /* check */
114 for (i = 0; sysdef_disables && sysdef_disables[i]; i++) {
115 if (sysdef_disables[i] && *sysdef_disables[i]
116 && !strcmp (ext, sysdef_disables[i]))
117 {
118 return FALSE;
119 }
120 }
121
122 return TRUE;
123 }
124
125
126 gboolean
gimv_mime_types_add_extension(const gchar * mime_type,const gchar * extension)127 gimv_mime_types_add_extension (const gchar *mime_type,
128 const gchar *extension)
129 {
130 GimvMimeType *mtype = g_hash_table_lookup (mime_types_table, mime_type);
131 gchar ext[MAX_EXT_LEN];
132 gint len;
133
134 g_return_val_if_fail (mtype, FALSE);
135
136 if (!extension || !*extension) return FALSE;
137
138 len = strlen (extension);
139 g_return_val_if_fail (len < MAX_EXT_LEN, FALSE);
140
141 strcpy(ext, extension);
142 g_strdown (ext);
143
144 if (!g_list_find_custom (mtype->extensions_list,
145 (gpointer) ext,
146 (GCompareFunc) g_strcasecmp))
147 {
148 const gchar *known_mimetype;
149
150 mtype->extensions_list = g_list_append (mtype->extensions_list,
151 g_strdup (ext));
152
153 /* add to known exteions list */
154 /* FIXME */
155 if (!known_ext_mimetype_table)
156 known_ext_mimetype_table = g_hash_table_new (g_str_hash, g_str_equal);
157 known_mimetype = g_hash_table_lookup (known_ext_mimetype_table, ext);
158 if (!known_mimetype) {
159 gchar *str = g_strdup (ext);
160
161 g_hash_table_insert (known_ext_mimetype_table,
162 str, g_strdup (mime_type));
163
164 known_ext_list = g_list_append (known_ext_list, str);
165 g_list_sort (known_ext_list, (GCompareFunc) strcmp);
166
167 if (sysdef_check_enable (ext)) {
168 known_enabled_ext_list = g_list_append (known_enabled_ext_list,
169 str);
170 g_list_sort (known_enabled_ext_list, (GCompareFunc) strcmp);
171 }
172 }
173 return TRUE;
174 }
175
176 return FALSE;
177 }
178
179
180 void
gimv_mime_types_update_known_enabled_ext_list(void)181 gimv_mime_types_update_known_enabled_ext_list (void)
182 {
183 GList *node;
184
185 g_list_free (known_enabled_ext_list);
186 known_enabled_ext_list = NULL;
187
188 for (node = known_ext_list; node; node = g_list_next (node)) {
189 if (sysdef_check_enable (node->data)) {
190 known_enabled_ext_list = g_list_append (known_enabled_ext_list,
191 node->data);
192 }
193 }
194 }
195
196
197 void
gimv_mime_types_update_userdef_ext_list(void)198 gimv_mime_types_update_userdef_ext_list (void)
199 {
200 gchar **user_defs = NULL, **sections = NULL;
201 gchar *ext, *type;
202 gint i;
203 GList *node;
204
205 /* free old value */
206 for (node = userdef_ext_list; node; node = g_list_next (node)) {
207 gboolean found = FALSE;
208 gchar *key, *value;
209 if (node->data)
210 found = g_hash_table_lookup_extended (userdef_ext_mimetype_table,
211 node->data,
212 (gpointer) &key,
213 (gpointer) &value);
214 if (found) {
215 g_hash_table_remove (userdef_ext_mimetype_table, key);
216 g_free (key);
217 g_free (value);
218 }
219 }
220 g_list_free (userdef_ext_list);
221 userdef_ext_list = NULL;
222
223 /* create new list */
224 if (conf.imgtype_user_defs && *conf.imgtype_user_defs)
225 user_defs = g_strsplit (conf.imgtype_user_defs, ";", -1);
226 if (!user_defs) return;
227
228 if (!userdef_ext_mimetype_table)
229 userdef_ext_mimetype_table = g_hash_table_new (g_str_hash, g_str_equal);
230
231 for (i = 0; user_defs[i]; i++) {
232 if (!*user_defs[i]) continue;
233
234 sections = g_strsplit (user_defs[i], ",", 3);
235 if (!sections) continue;
236 g_strstrip (sections[0]);
237 g_strstrip (sections[1]);
238 g_strstrip (sections[2]);
239 if (!*sections[0]) goto ERROR;
240 /* if (filter_check_duplicate (sections[0], -1, FALSE)) goto ERROR; */
241
242 if (!*sections[2] || g_strcasecmp (sections[2], "ENABLE")) goto ERROR;
243
244 ext = g_strdup (sections[0]);
245 g_strdown (ext);
246 if (!*sections[1])
247 type = g_strdup ("UNKNOWN");
248 else
249 type = g_strdup (sections[1]);
250
251 userdef_ext_list
252 = g_list_append (userdef_ext_list, ext);
253 g_hash_table_insert (userdef_ext_mimetype_table, ext, type);
254
255 ERROR:
256 g_strfreev (sections);
257 }
258 }
259
260
261 GList *
gimv_mime_types_get_known_ext_list(void)262 gimv_mime_types_get_known_ext_list (void)
263 {
264 return known_ext_list;
265 }
266
267
268 GList *
gimv_mime_types_get_known_enabled_ext_list(void)269 gimv_mime_types_get_known_enabled_ext_list (void)
270 {
271 if (!known_enabled_ext_list
272 && conf.imgtype_disables && *conf.imgtype_disables)
273 {
274 gimv_mime_types_update_known_enabled_ext_list ();
275 }
276
277 return known_enabled_ext_list;
278 }
279
280
281 GList *
gimv_mime_types_get_userdef_ext_list(void)282 gimv_mime_types_get_userdef_ext_list (void)
283 {
284 if (!userdef_ext_list)
285 gimv_mime_types_update_userdef_ext_list ();
286 return NULL;
287 }
288
289
290 const gchar *
gimv_mime_types_get_type_from_ext(const gchar * extension)291 gimv_mime_types_get_type_from_ext (const gchar *extension)
292 {
293 const gchar *type = NULL;
294 gchar ext[MAX_EXT_LEN];
295 gint len;
296
297 if (!extension || !*extension) return NULL;
298
299 len = strlen (extension);
300 g_return_val_if_fail (len < MAX_EXT_LEN, NULL);
301
302 strcpy(ext, extension);
303 g_strdown (ext);
304
305 if (!known_enabled_ext_list)
306 gimv_mime_types_update_known_enabled_ext_list ();
307 if (known_ext_mimetype_table)
308 type = g_hash_table_lookup (known_ext_mimetype_table, ext);
309 if (type) return type;
310
311 if (!userdef_ext_mimetype_table
312 && conf.imgtype_user_defs && *conf.imgtype_user_defs)
313 {
314 gimv_mime_types_update_userdef_ext_list ();
315 }
316
317 if (userdef_ext_mimetype_table)
318 return g_hash_table_lookup (userdef_ext_mimetype_table, ext);
319
320 return NULL;
321 }
322
323
324 const gchar *
gimv_mime_types_get_extension(const gchar * filename)325 gimv_mime_types_get_extension (const gchar *filename)
326 {
327 gchar *ext;
328
329 if (!filename)
330 return NULL;
331
332 ext = strrchr(filename, '.');
333 if (ext)
334 ext = ext + 1;
335 else
336 return NULL;
337
338 if (ext == "\0")
339 return NULL;
340 else
341 return ext;
342 }
343
344
345 gboolean
gimv_mime_types_extension_is(const gchar * filename,const gchar * ext)346 gimv_mime_types_extension_is (const gchar *filename, const gchar *ext)
347 {
348 gint len1, len2;
349
350 if (!filename) return FALSE;
351 if (!*filename) return FALSE;
352 if (!ext) return FALSE;
353 if (!*ext) return FALSE;
354
355 len1 = strlen (filename);
356 len2 = strlen (ext);
357
358 if (len1 < len2) return FALSE;
359
360 return !g_strcasecmp (filename + len1 - len2, ext);
361 }
362