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