ef7f4edd98022a52f26356c00fd433599bb2e33b
[platform/framework/web/download-provider.git] / src / agent / download-agent-mime-util.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <string.h>
18 #include <stdlib.h>
19
20 #include <xdgmime.h>
21
22 #include "download-agent-debug.h"
23 #include "download-agent-mime-util.h"
24 #include "download-agent-pthread.h"
25
26 #define IS_PROHIBITED_CHAR(c)  ((c) == ';' || (c) == '\\' || (c) == '/' || (c) == ':' || (c) == '*' || (c) == '?' || (c) == '"' || (c) == '>' || (c) == '<' || (c) == '|' || (c) == '(' || (c) == ')')
27 #define IS_SPACE_CHARACTER(c)           ((c) == ' ' || (c) == '\t')
28
29 #define DD_MIME_STR "application/vnd.oma.dd+xml"
30 #define DD_EXT_STR "*.dd"
31 #define DRM_MIME_STR "application/vnd.oma.drm.message"
32 #define DRM_EXT_STR "*.dcf"
33 #define MAX_EXT_TABLE_INDEX 16
34 Ext_translation_table ext_trans_table [MAX_EXT_TABLE_INDEX] = {
35                 {"*.xla",                       "*.xls"},
36                 {"*.pot",                       "*.ppt"},
37                 {"*.xsl",                       "*.xml"},
38                 {"*.spl",                       "*.swf"},
39                 {"*.oga",                       "*.ogg"},
40                 {"*.jpe",                       "*.jpg"},//5
41                 {"*.CSSL",                      "*.css"},
42                 {"*.htm",                       "*.html"},
43                 {"*.hxx",                       "*.hpp"},
44                 {"*.c++",                       "*.cpp"},
45                 {"CMakeLists.txt",      "*.cmake"},//10
46                 {"*.ime",                       "*.imy"},
47                 {"Makefile",            "makefile"},
48                 {"*.3g2",                       "*.3gp"},
49                 {"*.mp2",                       "*.mpg"},
50                 {"*.divx",                      "*.avi"},//15
51         };
52 /* This is samsung mime policy
53  * 1. if the mime is audio/m4a, the extension name is defined as "m4a" for launching music player
54 */
55 #ifdef _SAMSUNG_MIME_POLICY
56 #define MAX_SEC_MIME_TABLE_INDEX 1
57 struct sec_mime_table_t {
58         char *mime;
59         char *ext;
60 };
61 struct sec_mime_table_t sec_mime_table [MAX_SEC_MIME_TABLE_INDEX] = {
62         {"audio/m4a",           "m4a"},
63 };
64 #endif
65
66 const char *ambiguous_MIME_Type_list[] = {
67                 "text/plain",
68                 "application/octet-stream"
69 };
70
71 /* Because xdgmime is not thread safety, this mutex is necessary */
72 pthread_mutex_t mutex_for_xdgmime = PTHREAD_MUTEX_INITIALIZER;
73
74 da_bool_t is_ambiguous_MIME_Type(const char *in_mime_type)
75 {
76 //      DA_LOG_FUNC_START(Default);
77
78         if (!in_mime_type)
79                 return DA_FALSE;
80
81         int index = 0;
82         int list_size = sizeof(ambiguous_MIME_Type_list) / sizeof(const char *);
83         for (index = 0 ; index < list_size ; index++) {
84                 if (0 == strncmp(in_mime_type, ambiguous_MIME_Type_list[index],
85                                 strlen(ambiguous_MIME_Type_list[index]))) {
86                         DA_LOG(Default,"It is ambiguous! [%s]", ambiguous_MIME_Type_list[index]);
87                         return DA_TRUE;
88                 }
89         }
90
91         return DA_FALSE;
92 }
93
94 da_result_t da_mime_get_ext_name(char *mime, char **ext)
95 {
96         da_result_t ret = DA_RESULT_OK;
97         const char **extlist = DA_NULL;
98         const char *unaliased_mimetype = DA_NULL;
99         char ext_temp[DA_MAX_STR_LEN] = {0,};
100         char *temp = NULL;
101
102         DA_LOG_FUNC_START(Default);
103
104         if (DA_NULL == mime || DA_NULL == ext) {
105                 ret = DA_ERR_INVALID_ARGUMENT;
106                 DA_LOG_ERR(Default,"Invalid mime type");
107                 goto ERR;
108         }
109         DA_LOG_VERBOSE(Default,"mime str[%s]ptr[%p]len[%d]",mime,mime,strlen(mime));
110         /* unaliased_mimetype means representative mime among similar types */
111         _da_thread_mutex_lock(&mutex_for_xdgmime);
112         unaliased_mimetype = xdg_mime_unalias_mime_type(mime);
113         _da_thread_mutex_unlock(&mutex_for_xdgmime);
114
115         if (unaliased_mimetype == DA_NULL) {
116                 ret = DA_ERR_INVALID_MIME_TYPE;
117                 DA_LOG_ERR(Default,"Invalid mime type : No unsaliased mime type");
118                 goto ERR;
119         }
120         DA_LOG(Default,"unaliased_mimetype[%s]\n",unaliased_mimetype);
121
122         /* Get extension name from shared-mime-info */
123         _da_thread_mutex_lock(&mutex_for_xdgmime);
124         extlist = xdg_mime_get_file_names_from_mime_type(unaliased_mimetype);
125         _da_thread_mutex_unlock(&mutex_for_xdgmime);
126         if (extlist == DA_NULL || *extlist == DA_NULL) {
127                 int i = 0;
128                 ret = DA_ERR_INVALID_MIME_TYPE;
129                 DA_LOG(Default,"No extension list");
130 #ifdef _SAMSUNG_MIME_POLICY
131                 for (i = 0; i < MAX_SEC_MIME_TABLE_INDEX; i++)
132                 {
133                         if (strncmp(sec_mime_table[i].mime, mime, strlen(mime)) == 0) {
134                                 strncpy(ext_temp, sec_mime_table[i].ext, DA_MAX_STR_LEN-1);
135                                 ret = DA_RESULT_OK;
136                                 break;
137                         }
138                 }
139 #endif
140         } else { /* For drm case, this else statement is needed */
141                 DA_LOG(Default,"extlist[%s]\n",*extlist);
142                 strncpy(ext_temp, *extlist, DA_MAX_STR_LEN);
143                 /* If only one extension name is existed, don't enter here */
144                 while (*extlist != NULL) {
145                         int i = 0;
146                         /* If there are existed many extension names,
147                          *  try to search common extension name from table
148                          *  with first mime type at extension list*/
149                         for (i = 0; i < MAX_EXT_TABLE_INDEX; i++)
150                         {
151                                 if (strncmp(ext_trans_table[i].standard,*extlist,
152                                                 strlen(*extlist)) == 0) {
153                                         memset(ext_temp, 0x00, DA_MAX_STR_LEN);
154                                         strncpy(ext_temp,ext_trans_table[i].normal, DA_MAX_STR_LEN-1);
155                                         break;
156                                 }
157                         }
158                         DA_LOG(Default,"index[%d]\n",i);
159                         /* If there is a mime at extension transform table */
160                         if (i < MAX_EXT_TABLE_INDEX) {
161                                 break;
162                         }
163                         DA_LOG(Default,"extlist[%s]\n",*extlist);
164                         extlist++;
165                 }
166                 DA_LOG(Default,"extension from shared mime info[%s]",ext_temp);
167         }
168
169         if (strlen(ext_temp) < 1) {
170                 /* If there is no mime string for OMD descriptor mime type */
171                 if (strncmp(DD_MIME_STR,mime,strlen(DD_MIME_STR)) == 0) {
172                         strncpy(ext_temp, DD_EXT_STR, DA_MAX_STR_LEN-1);
173                         ret = DA_RESULT_OK;
174                         /* If there is no extension name for "applicaion/vnd.oma.drm.messeages"
175                          *  at shared-mime-info*/
176                 } else if (strncmp(DRM_MIME_STR,mime,strlen(DD_MIME_STR)) == 0) {
177                         strncpy(ext_temp, DRM_EXT_STR, DA_MAX_STR_LEN-1);
178                         /* If there is extension name at extlist, the return value can have an error.*/
179                         ret = DA_RESULT_OK;
180                 } else {
181                         ret = DA_ERR_INVALID_MIME_TYPE;
182                         DA_LOG_ERR(Default,"Invalid mime type : no extension name at list");
183                 }
184         }
185         if (ret != DA_RESULT_OK)
186                 goto ERR;
187
188         temp = strchr(ext_temp,'.');
189         if (temp == NULL)
190                 temp = ext_temp;
191         else
192                 temp++;
193
194         DA_LOG(Default,"final extension name:[%s]",temp);
195         *ext = (char*)calloc(1, strlen(temp) + 1);
196         if (*ext != DA_NULL) {
197                 strncpy(*ext, temp,strlen(temp));
198         } else  {
199                 ret = DA_ERR_FAIL_TO_MEMALLOC ;
200                 goto ERR ;
201         }
202 ERR:
203         return ret;
204 }
205
206 da_bool_t da_get_extension_name_from_url(char *url, char **ext)
207 {
208         da_bool_t ret = DA_TRUE;
209         char *buff = DA_NULL;
210         char *temp_str = DA_NULL;
211         int buf_len = 0;
212
213         DA_LOG_FUNC_START(Default);
214
215         if (DA_NULL == url || DA_NULL == ext) {
216                 ret = DA_FALSE;
217                 DA_LOG_ERR(Default,"Invalid Argument");
218                 return ret;
219         }
220
221         if ((temp_str = strrchr(url,'/'))) {
222                 if ((buff = strrchr(temp_str,'.'))) {
223                         char *q = DA_NULL;
224                         buff++;
225                         /* check to exist "?" after extension name */
226                         q = strrchr(buff,'?');
227                         if (q) {
228                                 buf_len = strlen(buff) - strlen(q);
229                         } else {
230                                 buf_len = strlen(buff);
231                         }
232                         *ext = (char*) calloc(1, buf_len + 1) ;
233
234                         if (DA_NULL == *ext) {
235                                 ret = DA_FALSE;
236                                 DA_LOG_ERR(Default,"Memory Fail");
237                                 goto ERR;
238                         }
239                         strncpy(*ext,buff,buf_len);
240                         DA_LOG(Default,"extention name[%s]",*ext);
241                         return ret;
242                 }
243         }
244 ERR:
245         if (*ext) {
246                 free(*ext);
247                 *ext = DA_NULL;
248         }
249         return ret;
250 }
251
252 /* FIXME move this function to another file */
253 da_bool_t da_get_file_name_from_url(char *url, char **name)
254 {
255         da_bool_t ret = DA_TRUE;
256         char *buff = DA_NULL;
257         char *Start = NULL;
258         char *End = NULL;
259         char c = 0;
260         int i = 0;
261         int j = 0;
262         int len_name = 0;
263         char name_buff[DA_MAX_FILE_PATH_LEN] = {0,};
264
265         DA_LOG_FUNC_START(Default);
266
267         if (DA_NULL == url || DA_NULL == name) {
268                 ret = DA_FALSE;
269                 DA_LOG_ERR(Default,"Invalid Argument");
270                 goto ERR;
271         }
272         *name = DA_NULL;
273         if (!strstr(url, "http") && !strstr(url, "https")) {
274                 ret = DA_FALSE;
275                 DA_LOG_ERR(Default,"Invalid Argument");
276                 goto ERR;
277     }
278
279         buff = (char*) calloc(1, strlen(url) +1);
280         if(DA_NULL == buff) {
281                 ret = DA_FALSE;
282                 DA_LOG_ERR(Default,"Memory Fail");
283                 goto ERR;
284     }
285
286         while((c = url[i++]) != 0) {
287                 if(c == '%') {
288                         char buffer[3] = {0,};
289                         buffer[0] = url[i++];
290                         buffer[1] = url[i++];
291                         buff[j++] = (char)strtol(buffer,NULL,16);
292                 } else {
293                         buff[j++] = c;
294                 }
295         }
296         End = strstr(buff, "?");
297         if (DA_NULL != End) {
298                 Start = End -1;
299                 while(*(Start) != '/') {
300                         Start--;
301                 }
302                 if ((*(Start) == '/') && ((len_name = (End - Start)) > 1)) {
303                         Start++;
304                         if (DA_MAX_FILE_PATH_LEN <= len_name)   {
305                                 strncpy(name_buff, Start, DA_MAX_FILE_PATH_LEN-1);
306                                 name_buff[DA_MAX_FILE_PATH_LEN-1] = '\0';
307                         } else {
308                                 strncpy(name_buff, Start, len_name);
309                                 name_buff[len_name] = '\0';
310                         }
311                 } else {
312                         ret = DA_FALSE;
313                         goto ERR ; /*Name not found*/
314                 }
315         } else {
316                 int urlLen = strlen (buff);
317                 int Start_pos = 0;
318                 Start_pos = urlLen - 1;
319
320                 while(Start_pos > 0) {
321                         if(buff[Start_pos] == '/')
322                                 break;
323                         Start_pos--;
324                 }
325                 Start_pos++;
326                 if (Start_pos == 0 || urlLen - Start_pos <= 0) {
327                         ret = DA_FALSE;
328                         goto ERR;
329                 }
330                 while(Start_pos < urlLen) {
331                         name_buff[len_name++] = buff[Start_pos++];
332                         if (DA_MAX_FILE_PATH_LEN <= len_name) {
333                                 name_buff[DA_MAX_FILE_PATH_LEN-1] ='\0';
334                                 break;
335                         }
336                 }
337         }
338
339         if (len_name) {
340                 End = strrchr(name_buff, '.');
341                 if (End != NULL) {
342                         *End = '\0';
343                 }
344                 DA_LOG(Default,"file name BEFORE removing prohibited character = %s", name_buff);
345                 delete_prohibited_char(name_buff, strlen(name_buff));
346                 DA_LOG(Default,"file name AFTER removing prohibited character = %s", name_buff);
347                 len_name = strlen(name_buff);
348                 *name = (char*) calloc(1, len_name + 1);
349                 if (*name) {
350                         strncpy(*name, name_buff,len_name);
351                 }
352         }
353         DA_LOG(Default,"Extracted file name : %s", *name);
354 ERR:
355         if (buff) {
356                 free (buff);
357                 buff = DA_NULL;
358     }
359         return ret;
360 }
361
362 void delete_prohibited_char(char *szTarget, int str_len)
363 {
364         char *chk_str = NULL;
365         int i = 0;
366         int j = 0;
367         int tar_len = 0;
368
369         if(szTarget == NULL || str_len <= 0 || strlen(szTarget) != str_len) {
370                 DA_LOG_ERR(Default,"Invaild Parameter\n");
371                 return;
372         }
373
374         chk_str = (char *)calloc(1, str_len + 1);
375         if(chk_str == NULL)
376                 return;
377
378         while(szTarget[j] != '\0') {
379                 if(IS_PROHIBITED_CHAR(szTarget[j]) == DA_FALSE &&
380                                         IS_SPACE_CHARACTER(szTarget[j]) == DA_FALSE) {
381                         chk_str[i] = szTarget[j];
382                         i++;
383                 }
384                 j++;
385         }
386
387         chk_str[i] = '\0';
388         tar_len = strlen(chk_str);
389
390         if(tar_len <= 0)
391                 szTarget[0] = '\0';
392         else {
393                 for(i = 0; i < tar_len; i++)
394                 {
395                         szTarget[i] = chk_str[i];
396                 }
397                 szTarget[i] = '\0';
398         }
399
400         if(chk_str != NULL)     {
401                 free(chk_str);
402         }
403         return;
404 }
405