4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>
7 * Contact: Seokkyu Jang <seokkyu.jang@samsung.com>
8 * Contact: Sangil Yoon <si83.yoon@samsung.com>
10 * This library is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU Lesser General Public License as published by the
12 * Free Software Foundation; either version 2.1 of the License, or (at your option)
15 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
16 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library; if not, write to the Free Software Foundation, Inc., 51
22 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include <sys/types.h>
36 #define API __attribute__ ((visibility("default")))
40 #define GLOBS2_PATH "/usr/share/mime/globs2"
41 #define MEM_INC_RATE 20
47 typedef struct mime_type_info
51 size_t file_names_size;
54 typedef struct mime_type_info_list
56 mime_type_info **mti_list;
59 } mime_type_info_list;
61 static mime_type_info_list *mti_list = NULL;
64 /***************************
65 * mime_type_info functions
66 ***************************/
67 static mime_type_info *
68 mime_type_info_new(void)
70 mime_type_info *mti = NULL;
72 mti = calloc(1, sizeof(mime_type_info));
73 mti->file_names = calloc(MEM_INC_RATE, sizeof(char *));
74 mti->file_names_size = MEM_INC_RATE;
80 mime_type_info_free(mime_type_info *mti)
84 if(mti->mime_type) free(mti->mime_type);
87 for(tmpstr = mti->file_names; *tmpstr; tmpstr++) {
90 free(mti->file_names);
96 mime_type_info_add_file_name(mime_type_info *mti,
97 const char *mime_type,
98 const char *file_name)
102 if(!mti->mime_type) {
103 mti->mime_type = strdup(mime_type);
106 /* mime_type already exist, but mime_type is different! */
107 if(strcmp(mti->mime_type, mime_type)) return -1;
112 for(pname = mti->file_names; pname < (mti->file_names + mti->file_names_size - 1) && *pname; pname++) {
113 if(!strcmp(file_name, *pname)) return 0; /* already exist! */
116 int old_file_names_size = mti->file_names_size;
118 if(pname == mti->file_names + old_file_names_size -1) {
120 /* memory full. realloc needed */
121 mti->file_names = realloc(mti->file_names, sizeof(char *)*(old_file_names_size+MEM_INC_RATE));
122 if(!mti->file_names) return -1;
124 memset(mti->file_names + old_file_names_size, 0x00, sizeof(char *)*MEM_INC_RATE);
125 pname = mti->file_names + old_file_names_size - 1;
126 mti->file_names_size += MEM_INC_RATE;
129 *pname = strdup(file_name);
136 /********************************
137 * mime_type_info_list functions
138 ********************************/
142 static mime_type_info_list *
143 mime_type_info_list_new(void)
145 mime_type_info_list *mtil;
147 mtil = calloc(1, sizeof(mime_type_info_list));
149 mtil->mti_list = calloc(MEM_INC_RATE, sizeof(mime_type_info *));
150 mtil->mti_list_size = MEM_INC_RATE;
157 /* free and init mtlist */
159 mime_type_info_list_free(mime_type_info_list *mtil)
161 mime_type_info **mti;
164 for(mti = mtil->mti_list;
167 mime_type_info_free(*mti);
170 free(mtil->mti_list);
175 mime_type_info_list_add_file_name(mime_type_info_list *mtil,
176 const char *mime_type,
177 const char *file_name)
179 if(!mtil || !mime_type || !file_name) return;
181 mime_type_info **mti;
184 for(mti = mtil->mti_list; mti < (mtil->mti_list + mtil->mti_list_size - 1) && *mti; mti++) {
185 if((*mti)->mime_type && mime_type && /* NULL check */
186 0 == strncmp((*mti)->mime_type,
188 strlen(mime_type))) {
195 /* New mime_type_info must be needed */
197 /* check memory full */
198 int old_mti_list_size = mtil->mti_list_size;
199 //printf("sizeof(mti_list)=%d, sizeof(mime_type_info *)=%d, old info_list_size=%d\n", sizeof(mtil->mti_list), sizeof(mime_type_info *), old_mti_list_size);
202 if(mti == mtil->mti_list + old_mti_list_size - 1) {
203 /* memory full. realloc needed */
204 mtil->mti_list = realloc(mtil->mti_list, sizeof(mime_type_info *) * (old_mti_list_size + MEM_INC_RATE));
205 if(!mtil->mti_list) return -1;
206 memset(mtil->mti_list + old_mti_list_size, 0x0, sizeof(mime_type_info *) * MEM_INC_RATE);
207 mti = mtil->mti_list + old_mti_list_size - 1;
209 mtil->mti_list_size += MEM_INC_RATE;
213 /* assign new data */
214 if(NULL == *mti) *mti = mime_type_info_new();
215 mime_type_info_add_file_name(*mti, mime_type, file_name);
221 /* create or renew mtlist */
223 mime_type_info_list_reload(mime_type_info_list *mtil)
226 struct stat globs2_stat;
232 /* Check glob2's mtime.
233 * If reconstruction is not needed, just exit function */
234 if( stat(GLOBS2_PATH, &globs2_stat) ||
235 globs2_stat.st_mtime <= mtil->globs2_mtime ) return;
238 mime_type_info **mti;
239 for(mti = mtil->mti_list;
242 mime_type_info_free(*mti);
246 /* save globs2's mtime */
247 mtil->globs2_mtime = globs2_stat.st_mtime;
249 /* read globs2, and construct data structure */
250 globs2 = fopen(GLOBS2_PATH, "r");
253 char *weight, *mime_type, *file_name, *saveptr = NULL;
254 while(fgets(buf, 255, globs2)) {
256 if(*buf == '#') continue;
257 /* weight:mime_type:file_name */
258 weight = strtok_r(buf, ":\n", &saveptr); /* ignored */
259 mime_type = strtok_r(NULL, ":\n", &saveptr);
260 file_name = strtok_r(NULL, ":\n", &saveptr);
262 mime_type_info_list_add_file_name(mtil, mime_type, file_name);
271 mime_type_info_list_get_file_names(mime_type_info_list *mtil,
272 const char *mime_type)
275 static const char *null_array[] = { NULL };
277 if(!mtil) return null_array;
279 mime_type_info **_mti;
280 for(_mti = mtil->mti_list; *_mti; _mti++) {
281 if((*_mti)->mime_type && mime_type && /* NULL check */
282 !strcmp((*_mti)->mime_type, mime_type)) {
283 return (const char **) (*_mti)->file_names;
292 * Get file names' list from mime type
295 xdg_mime_get_file_names_from_mime_type(const char *mime_type)
297 /* init data structure */
298 static mime_type_info_list *mtil = NULL;
299 if(!mtil) mtil = mime_type_info_list_new();
300 mime_type_info_list_reload(mtil);
302 return mime_type_info_list_get_file_names(mtil, mime_type);