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