60f85ee6c856d7c639b3e9dc5f824b1d8f7d0378
[platform/core/api/media-content.git] / src / media_util_private.c
1 /*
2 * Copyright (c) 2011 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
18 #include <dirent.h>
19 #include <fcntl.h>
20 #include <media_info_private.h>
21 #include <storage.h>
22 #include <system_info.h>
23 #include <sys/stat.h>
24
25 static int MEDIA_CONTENT_OTHER_SUPPORT = -1;
26
27 bool _media_util_check_support_media_type(const char *path)
28 {
29         int ret = SYSTEM_INFO_ERROR_NONE;
30         int media_type = -1;
31         bool is_supported = false;
32
33         content_retvm_if(!STRING_VALID(path), false, "path is empty");
34
35         if (MEDIA_CONTENT_OTHER_SUPPORT == -1) {
36                 ret = system_info_get_platform_bool("http://tizen.org/feature/content.scanning.others", &is_supported);
37                 if (ret != SYSTEM_INFO_ERROR_NONE) {
38                         content_debug("SYSTEM_INFO_ERROR: content.scanning.others [%d]", ret);
39                         return false;
40                 }
41
42                 MEDIA_CONTENT_OTHER_SUPPORT = is_supported;
43         }
44
45         /* If not, check media type */
46         if (!MEDIA_CONTENT_OTHER_SUPPORT) {
47                 ret = media_svc_get_media_type(path, &media_type);
48                 content_retvm_if(ret != MS_MEDIA_ERR_NONE, false, "Failed to get media type");
49
50                 if (media_type == MEDIA_CONTENT_TYPE_OTHERS)
51                         return false;
52         }
53
54         return true;
55 }
56
57 int _media_util_check_file_exist(const char *path)
58 {
59         int exist;
60
61         /* check the file exits actually */
62         exist = open(path, O_RDONLY);
63         if (exist < 0) {
64                 if (errno == EACCES || errno == EPERM) {
65                         content_stderror("open file fail");
66                         content_sec_debug("path [%s]", path);
67                         return MEDIA_CONTENT_ERROR_PERMISSION_DENIED;
68                 } else {
69                         content_stderror("open file fail");
70                         content_sec_debug("path [%s]", path);
71                         return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
72                 }
73         }
74
75         close(exist);
76
77         return MEDIA_CONTENT_ERROR_NONE;
78 }
79
80 int _media_util_get_file_time(const char *path)
81 {
82         struct stat statbuf;
83         int ret = 0;
84
85         memset(&statbuf, 0, sizeof(struct stat));
86         ret = stat(path, &statbuf);
87         if (ret == -1) {
88                 content_stderror("stat failed");
89                 return ret;
90         }
91
92         return statbuf.st_mtime;
93 }
94
95 bool _media_util_is_ignorable_file(const char *path)
96 {
97         char *tmp_path = NULL;
98         char *org_path = NULL;
99
100 #ifndef _USE_TVPD_MODE
101         char replace[MAX_PATH_LEN] = {0, };
102 #endif
103
104         content_retip_if_fail(STRING_VALID(path));
105
106         /* Check is exist (It may be the path to the deleted file) */
107         if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
108                 content_sec_debug("removed path[%s]", path);
109                 return false;
110         }
111
112         /* Check symbolic link file */
113         if (g_file_test(path, G_FILE_TEST_IS_SYMLINK)) {
114                 content_error("symbolic link(file)");
115                 content_sec_debug("path : %s", path);
116                 return true;
117         }
118
119         /* Check hidden path */
120         if (strstr(path, "/.") != NULL) {
121                 content_error("hidden path");
122                 content_sec_debug("path : %s", path);
123                 return true;
124         }
125
126         /* Check symbolic directory */
127         tmp_path = realpath(path, NULL);
128         /* Get trimmed path */
129         org_path = g_canonicalize_filename(path, NULL);
130
131 #ifdef _USE_TVPD_MODE
132         if (g_strcmp0(tmp_path, org_path) != 0) {
133                 content_error("symbolic link(directory)");
134                 content_sec_debug("path[%s] real[%s]", org_path, tmp_path);
135                 SAFE_FREE(tmp_path);
136                 g_free(org_path);
137                 return true;
138         }
139 #else
140         if (g_str_has_prefix(tmp_path, MEDIA_SHARE_PATH)) {
141                 /* If shared directory, it should be change path to TZ_USER_SHARE from realpath */
142                 snprintf(replace, MAX_PATH_LEN, "%s%s", tzplatform_getenv(TZ_USER_MEDIASHARED), tmp_path + strlen(MEDIA_SHARE_PATH));
143                 if (g_strcmp0(replace, org_path) != 0) {
144                         content_error("symbolic link(directory)");
145                         content_sec_debug("path[%s] real[%s]", org_path, tmp_path);
146                         SAFE_FREE(tmp_path);
147                         g_free(org_path);
148                         return true;
149                 }
150         } else {
151                 if (g_strcmp0(tmp_path, org_path) != 0) {
152                         content_error("symbolic link(directory)");
153                         content_sec_debug("path[%s] real[%s]", org_path, tmp_path);
154                         SAFE_FREE(tmp_path);
155                         g_free(org_path);
156                         return true;
157                 }
158         }
159 #endif
160         SAFE_FREE(tmp_path);
161         g_free(org_path);
162
163         return false;
164 }
165
166 static bool __is_scan_ignore_exist(const char *path)
167 {
168         const char *scan_ignore = ".scan_ignore";
169         char *ignore_path = NULL;
170         gboolean result = FALSE;
171
172         if (!STRING_VALID(path))
173                 return false;
174
175         ignore_path = g_build_path(G_DIR_SEPARATOR_S, path, scan_ignore, NULL);
176         result = g_file_test(ignore_path, G_FILE_TEST_EXISTS);
177
178         if (result)
179                 content_error("scan ignore file exist [%s]", ignore_path);
180
181         g_free(ignore_path);
182
183         return (bool)result;
184 }
185
186 bool _media_util_is_ignorable_dir(const char *dir_path)
187 {
188         int ret = MEDIA_CONTENT_ERROR_NONE;
189         ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL;
190
191         content_retip_if_fail(STRING_VALID(dir_path));
192
193         content_sec_debug("dir_path : %s", dir_path);
194
195         /*1. Check Hidden Directory*/
196         if (strstr(dir_path, "/.") != NULL) {
197                 content_error("hidden path");
198                 return true;
199         }
200
201         /*2. Check Scan Ignore Directory*/
202         ret = ms_user_get_storage_type(_content_get_uid(), dir_path, &storage_type);
203         if (ret != MS_MEDIA_ERR_NONE) {
204                 content_error("ms_user_get_storage_type failed : %d", ret);
205                 return false;
206         }
207
208         char *leaf_path = NULL;
209         char search_path[MAX_PATH_LEN] = {0, };
210
211         SAFE_STRLCPY(search_path, dir_path, sizeof(search_path));
212
213         while (STRING_VALID(search_path)) {
214                 if (__is_scan_ignore_exist(search_path))
215                         return true;
216
217                 leaf_path = strrchr(search_path, '/');
218                 if (!leaf_path)
219                         break;
220
221                 search_path[leaf_path - search_path] = '\0';
222         }
223
224         return false;
225 }
226
227 int _media_content_check_dir(const char *path)
228 {
229         DIR *dp = NULL;
230         char *real = NULL;
231         char *origin = NULL;
232 #ifndef _USE_TVPD_MODE
233         char result_path[MAX_PATH_LEN] = {0, };
234 #endif
235         dp = opendir(path);
236         if (dp == NULL) {
237                 if (errno == EACCES || errno == EPERM) {
238                         content_stderror("open dir fail");
239                         content_sec_error("path [%s]", path);
240                         return MEDIA_CONTENT_ERROR_PERMISSION_DENIED;
241                 } else {
242                         content_stderror("open dir fail");
243                         content_sec_error("path [%s]", path);
244                         return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
245                 }
246         }
247
248         closedir(dp);
249
250         /* Check symbolic link directory */
251         real = realpath(path, NULL);
252         /* Get trimmed path */
253         origin = g_canonicalize_filename(path, NULL);
254
255 #ifdef _USE_TVPD_MODE
256         if (g_strcmp0(real, origin) != 0) {
257                 content_error("symbolic link(directory)");
258                 content_sec_debug("path[%s] real[%s]", origin, real);
259                 SAFE_FREE(real);
260                 g_free(origin);
261                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
262         }
263 #else
264         if (g_str_has_prefix(real, MEDIA_SHARE_PATH)) {
265                 /* If shared directory, it should be change path to TZ_USER_SHARE from realpath */
266                 snprintf(result_path, MAX_PATH_LEN, "%s%s", tzplatform_getenv(TZ_USER_MEDIASHARED), real + strlen(MEDIA_SHARE_PATH));
267                 if (g_strcmp0(result_path, origin) != 0) {
268                         content_error("symbolic link(directory)");
269                         content_sec_debug("path[%s] real[%s]", origin, real);
270                         SAFE_FREE(real);
271                         g_free(origin);
272                         return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
273                 }
274         } else {
275                 if (g_strcmp0(real, origin) != 0) {
276                         content_error("symbolic link(directory)");
277                         content_sec_debug("path[%s] real[%s]", origin, real);
278                         SAFE_FREE(real);
279                         g_free(origin);
280                         return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
281                 }
282         }
283 #endif
284
285         SAFE_FREE(real);
286         g_free(origin);
287
288         return MEDIA_CONTENT_ERROR_NONE;
289 }