Remove unreachable code because 'err' is always 0 or -1.
[platform/core/multimedia/media-server.git] / src / common / media-common-utils.c
1 /*
2  * Media Server
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <sys/types.h>
23 #include <fcntl.h>
24 #include <vconf.h>
25 #include <sys/statvfs.h>
26 #include <sys/stat.h>
27
28 #ifdef _SET_VIP_PROCESS
29 #include <sys/prctl.h>
30 #endif
31 #include <system_info.h>
32 #include <dd-display.h>
33
34 #ifndef _USE_DEVICED_DBUS
35 #include <usb-device.h>
36 #endif
37
38 #include "media-util.h"
39 #include "media-server-ipc.h"
40 #include "media-common-dbg.h"
41 #include "media-common-system.h"
42 #include "media-common-utils.h"
43
44 int ms_strappend(char *res, const int size, const char *pattern, const char *str1, const char *str2)
45 {
46         int len = 0;
47         int real_size = size - 1;
48
49         if (!res || !pattern || !str1 || !str2)
50                 return MS_MEDIA_ERR_INVALID_PARAMETER;
51
52         if (real_size < (int)(strlen(str1) + strlen(str2)))
53                 return MS_MEDIA_ERR_INVALID_PARAMETER;
54
55         len = snprintf(res, real_size, pattern, str1, str2);
56         if (len < 0)
57                 return MS_MEDIA_ERR_INVALID_PARAMETER;
58
59         res[len] = '\0';
60
61         return MS_MEDIA_ERR_NONE;
62 }
63
64 bool ms_config_get_int(const char *key, int *value)
65 {
66         int err;
67
68         if (!key || !value) {
69                 MS_DBG_ERR("Arguments key or value is NULL");
70                 return false;
71         }
72
73         err = vconf_get_int(key, value);
74         if (err == VCONF_OK)
75                 return true;
76
77         MS_DBG_ERR("Error code: %d", err);
78
79         return false;
80 }
81
82 bool ms_config_set_int(const char *key, int value)
83 {
84         int err;
85
86         if (!key) {
87                 MS_DBG_ERR("Arguments key is NULL");
88                 return false;
89         }
90
91         err = vconf_set_int(key, value);
92         if (err == VCONF_OK)
93                 return true;
94
95         MS_DBG_ERR("Error code: %d", err);
96
97         return false;
98 }
99
100 bool ms_config_get_str(const char *key, char **value)
101 {
102         char *res = NULL;
103
104         if (key == NULL || value == NULL) {
105                 MS_DBG_ERR("Arguments key or value is NULL");
106                 return false;
107         }
108
109         res = vconf_get_str(key);
110         if (MS_STRING_VALID(res)) {
111                 *value = strdup(res);
112                 MS_SAFE_FREE(res);
113                 return true;
114         }
115
116         return false;
117 }
118
119 int ms_get_remain_space(double *free_space)
120 {
121         int ret = MS_MEDIA_ERR_NONE;
122         const char *path = "/opt";
123         struct statvfs s;
124
125         ret = statvfs(path, &s);
126         if (ret != 0) {
127                 MS_DBG_ERR("statvfs failed[%d]", ret);
128                 MS_DBG_STRERROR();
129                 return MS_MEDIA_ERR_INTERNAL;
130         }
131
132         /* f_bsize:unsigned long, f_bavail:fsblkcnt_t(unsigned long) */
133         *free_space = (double)(s.f_bsize * s.f_bavail);
134
135         return MS_MEDIA_ERR_NONE;
136 }
137
138 #ifdef _USE_RECORDED_CONTENT
139 bool ms_is_support_pvr(void)
140 {
141
142         int nSupportPVR = 0;
143         if (system_info_get_value_int(SYSTEM_INFO_KEY_PVR_SUPPORTED, &nSupportPVR) != SYSTEM_INFO_ERROR_NONE) {
144                 MS_DBG_ERR("Get PVR Support failed");
145                 return false;
146         }
147
148         MS_DBG("PVR Support : [%d]", nSupportPVR);
149
150         return (nSupportPVR != 0);
151 }
152 #endif
153
154 #ifdef _USE_SENIOR_MODE
155 bool ms_is_support_senior_mode()
156 {
157         bool bSupportSeniorMode = false;
158
159         if (system_info_get_value_bool(SYSTEM_INFO_KEY_GET_SENIOR_MODE_SUPPORTED, &bSupportSeniorMode) != SYSTEM_INFO_ERROR_NONE) {
160                 MS_DBG_ERR("Get senior mode support failed");
161                 return false;
162         }
163
164         MS_DBG("Senior mode support : [%d]", bSupportSeniorMode);
165
166         return bSupportSeniorMode;
167 }
168 #endif
169
170 int ms_check_file_path(const char *file_path, uid_t uid)
171 {
172         ms_user_storage_type_e storage_type = -1;
173         int ret = MS_MEDIA_ERR_NONE;
174
175         if (!MS_STRING_VALID(file_path)) {
176                 MS_DBG_ERR("Invalid path");
177                 return MS_MEDIA_ERR_INVALID_PARAMETER;
178         }
179
180         ret = ms_user_get_storage_type(uid, file_path, &storage_type);
181         MS_DBG_RETVM_IF(ret != MS_MEDIA_ERR_NONE, MS_MEDIA_ERR_INVALID_PATH, "Invalid path");
182
183         if (!g_file_test(file_path, G_FILE_TEST_IS_REGULAR)) {
184                 MS_DBG_SERR("g_file_test fail [%s]", file_path);
185                 return MS_MEDIA_ERR_INVALID_PATH;
186         }
187
188         return MS_MEDIA_ERR_NONE;
189 }
190
191 int ms_check_ignore_dir(const char *full_path, uid_t uid)
192 {
193         int ret = MS_MEDIA_ERR_NONE;
194         char *dir_path = NULL;
195         char *leaf_path = NULL;
196         char *usr_path = NULL;
197
198         ret = ms_check_file_path(full_path, uid);
199         if (ret != MS_MEDIA_ERR_NONE) {
200                 MS_DBG_ERR("invalid path : %s", full_path);
201                 return MS_MEDIA_ERR_INVALID_PATH;
202         }
203
204         dir_path = g_path_get_dirname(full_path);
205         if (dir_path == NULL || strcmp(dir_path, ".") == 0) {
206                 MS_DBG_ERR("getting directory path is failed : %s", full_path);
207                 MS_SAFE_FREE(dir_path);
208                 return MS_MEDIA_ERR_INVALID_PATH;
209         }
210
211         ret = ms_user_get_internal_root_path(uid, &usr_path);
212         if (ret != MS_MEDIA_ERR_NONE) {
213                 MS_DBG_ERR("ms_user_get_internal_root_path() fail");
214                 MS_SAFE_FREE(dir_path);
215                 return MS_MEDIA_ERR_INTERNAL;
216         }
217
218         while (1) {
219                 if (ms_check_scan_ignore(dir_path) != MS_MEDIA_ERR_NONE) {
220                         ret = MS_MEDIA_ERR_INVALID_PATH;
221                         break;
222                 }
223
224 #ifdef _USE_SENIOR_MODE
225                 if (ms_is_support_senior_mode()) {
226                         if (strcmp(dir_path, MEDIA_ROOT_PATH_SENIOR_MODE) == 0)
227                                 break;
228                 }
229 #endif
230                 if (strcmp(dir_path, usr_path) == 0)
231                         break;
232                 else if (MS_STRING_VALID(MEDIA_ROOT_PATH_SDCARD) && (strncmp(dir_path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0))
233                         break;
234                 else if (MS_STRING_VALID(MEDIA_ROOT_PATH_USB) && (strncmp(dir_path, MEDIA_ROOT_PATH_USB, strlen(MEDIA_ROOT_PATH_USB)) == 0))
235                         break;
236                 else if (MS_STRING_VALID(MEDIA_ROOT_PATH_DISC) && (strncmp(dir_path, MEDIA_ROOT_PATH_DISC, strlen(MEDIA_ROOT_PATH_DISC)) == 0))
237                         break;
238
239                 leaf_path = strrchr(dir_path, '/');
240                 if (leaf_path != NULL) {
241                                 int seek_len = leaf_path -dir_path;
242                                 dir_path[seek_len] = '\0';
243                 } else {
244                         MS_DBG_ERR("Fail to find leaf path");
245                         ret = MS_MEDIA_ERR_INVALID_PATH;
246                         break;
247                 }
248         }
249
250         MS_SAFE_FREE(dir_path);
251         MS_SAFE_FREE(usr_path);
252
253         return ret;
254 }
255
256 int ms_check_scan_ignore(char * path)
257 {
258         int ret = MS_MEDIA_ERR_NONE;
259         const char *ignore_file = ".scan_ignore";
260         char ignore_path[MS_FILE_PATH_LEN_MAX] = {0, };
261
262         if (strstr(path, "/.")) {
263                 MS_DBG_ERR("hidden path");
264                 return MS_MEDIA_ERR_INVALID_PATH;
265         }
266
267         if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
268                 memset(ignore_path, 0, sizeof(ignore_path));
269                 snprintf(ignore_path, sizeof(ignore_path), "%s/%s", path, ignore_file);
270
271                 if (g_file_test(ignore_path, G_FILE_TEST_EXISTS)) {
272                         MS_DBG_WARN("scan ignore file exist [%s]", ignore_path);
273                         return MS_MEDIA_ERR_INVALID_PATH;
274                 }
275         } else {
276                 MS_DBG_ERR("g_file_test fails[%s]", path);
277                 ret = MS_MEDIA_ERR_INVALID_PATH;
278
279                 if (!MS_STRING_VALID(MEDIA_ROOT_PATH_USB)) {
280                         MS_DBG_ERR("Fail to get USB path");
281                         return ret;
282                 }
283
284                 if (strstr(path, MEDIA_ROOT_PATH_USB) != NULL) {
285                         /*if the directory does not exist, check the device is unmounted*/
286                         if (!ms_storage_mount_status(path)) {
287                                 MS_DBG_ERR("Device is unmounted[%s]", path);
288                                 return MS_MEDIA_ERR_USB_UNMOUNTED;
289                         }
290                 }
291         }
292
293         return ret;
294 }
295
296 bool ms_storage_mount_status(const char* start_path)
297 {
298         bool ret = false;
299 #ifndef _USE_DEVICED_DBUS
300         int count = 0;
301         int err = 0;
302         usb_device_list_h list;
303         usb_device_h device;
304         char *mount_path = NULL;
305
306         char *storage_path = NULL;
307         char *remain_path = NULL;
308         int remain_len = 0;
309
310         remain_path = strstr(start_path+strlen(MEDIA_ROOT_PATH_USB) +1, "/");
311         if (remain_path != NULL)
312                 remain_len = strlen(remain_path);
313
314         storage_path = strndup(start_path, strlen(start_path) - remain_len);
315
316         MS_DBG_WARN("storage_path [%s]", storage_path);
317
318         err = usb_device_get_device_list(USB_MASS_STORAGE, &list);
319         if (err == 0) {
320                 count = usb_device_list_get_count(list);
321                 if (count > 0) {
322                         err = usb_device_list_get_first(list, &device);
323                         if (err != USB_ERROR_LIST_FAILED_TO_GET && device != NULL) {
324                                 mount_path = usb_device_get_mountpath(device);
325                                 if (mount_path != NULL) {
326                                         MS_DBG_WARN("mount_path [%s]", mount_path);
327                                         if (strlen(mount_path) == strlen(storage_path)) {
328                                                 if (strncmp(mount_path, storage_path, strlen(mount_path)) == 0) {
329                                                         MS_DBG_WARN("start path is mounted [%s]", start_path);
330                                                         ret = true;
331                                                 }
332                                         }
333                                 }
334                         }
335
336                         if (ret != true) {
337                                 while (usb_device_list_get_next(list, &device) == 0) {
338                                         if (device != NULL) {
339                                                 mount_path = usb_device_get_mountpath(device);
340                                                 if (mount_path != NULL) {
341                                                         MS_DBG_WARN("mount_path [%s]", mount_path);
342                                                         if (strlen(mount_path) == strlen(storage_path)) {
343                                                                 if (strncmp(mount_path, storage_path, strlen(mount_path)) == 0) {
344                                                                         MS_DBG_WARN("start path is mounted [%s]", start_path);
345                                                                         ret = true;
346                                                                         break;
347                                                                 }
348                                                         }
349                                                 }
350                                         }
351                                 }
352                         }
353                 }
354
355                 usb_device_free_device_list(list);
356         } else {
357                 MS_DBG_ERR("usb_device_get_device_list falied [%d]", err);
358         }
359
360         MS_SAFE_FREE(storage_path);
361 #endif
362         return ret;
363 }
364
365 int ms_set_db_status(ms_db_status_type_t status, ms_user_storage_type_e storage_type)
366 {
367         int res = MS_MEDIA_ERR_NONE;
368         int err = 0;
369
370         if (status == MS_DB_UPDATING) {
371                 if (!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATING)) {
372                         res = MS_MEDIA_ERR_VCONF_SET_FAIL;
373                         MS_DBG_ERR("ms_config_set_int failed");
374                 }
375
376                 if (storage_type == MS_USER_STORAGE_EXTERNAL) {
377                         if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADING)) {
378                                 res = MS_MEDIA_ERR_VCONF_SET_FAIL;
379                                 MS_DBG_ERR("ms_config_set_int failed");
380                         }
381                 }
382         } else {
383                 if (!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATED)) {
384                         res = MS_MEDIA_ERR_VCONF_SET_FAIL;
385                         MS_DBG_ERR("ms_config_set_int failed");
386                 }
387
388                 if (storage_type == MS_USER_STORAGE_EXTERNAL) {
389                         if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADED)) {
390                                 res = MS_MEDIA_ERR_VCONF_SET_FAIL;
391                                 MS_DBG_ERR("ms_config_set_int failed");
392                         }
393                 }
394         }
395
396         err = ms_set_power_mode(status);
397         if (err != MS_MEDIA_ERR_NONE) {
398                 MS_DBG_ERR("ms_set_power_mode fail");
399                 res = err;
400         }
401
402         return res;
403 }
404
405 int ms_set_power_mode(ms_db_status_type_t status)
406 {
407         int res = MS_MEDIA_ERR_NONE;
408         int err;
409
410         switch (status) {
411         case MS_DB_UPDATING:
412                 err = display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
413                 if (err != 0)
414                         res = MS_MEDIA_ERR_INTERNAL;
415                 break;
416         case MS_DB_UPDATED:
417                 err = display_unlock_state(LCD_OFF, PM_RESET_TIMER);
418                 if (err != 0)
419                         res = MS_MEDIA_ERR_INTERNAL;
420                 break;
421         default:
422                 MS_DBG_ERR("Unacceptable type : %d", status);
423                 break;
424         }
425
426         return res;
427 }
428
429 void ms_trim_dir_path(char *dir_path)
430 {
431         /* need implementation */
432         /* if dir_path is not NULL terminated, this function will occure crash */
433         int len = strlen(dir_path);
434
435         if (dir_path[len -1] == '/')
436                 dir_path[len -1] = '\0';
437 }
438
439 int ms_check_size_mediadb(uid_t uid, double *db_size)
440 {
441         int ret = MS_MEDIA_ERR_NONE;
442         char *db_path = NULL;
443         struct stat buf;
444
445         ret = ms_user_get_media_db_path(uid, &db_path);
446
447         if (stat(db_path, &buf) == 0) {
448                 *db_size = buf.st_size;
449         } else {
450                 MS_DBG_STRERROR("stat failed");
451                 ret = MS_MEDIA_ERR_INTERNAL;
452         }
453
454         MS_SAFE_FREE(db_path);
455
456         return ret;
457 }
458
459 #ifdef _SET_VIP_PROCESS
460 #define PROC_OOM_SCORE_ADJ_PATH         "/proc/%d/oom_score_adj"
461 #define VIP_OOM_SCORE_ADJ                       (-1000)
462 #define PROC_NAME_MAX 1024
463 #define PROC_BUF_MAX 64
464
465 static int ms_get_cmdline_from_proc(pid_t pid, char *cmdline)
466 {
467         char buf[PROC_BUF_MAX];
468         char cmdline_buf[PROC_NAME_MAX];
469         char *filename;
470         FILE *fp;
471
472         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
473         fp = fopen(buf, "r");
474         if (fp == NULL)
475                 return MS_MEDIA_ERR_INTERNAL;
476
477         if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) {
478                 fclose(fp);
479                 return MS_MEDIA_ERR_INTERNAL;
480         }
481         fclose(fp);
482
483         filename = strrchr(cmdline_buf, '/');
484         if (filename == NULL)
485                 filename = cmdline_buf;
486         else
487                 filename = filename + 1;
488
489         SAFE_STRLCPY(cmdline, filename, PROC_NAME_MAX);
490
491         return MS_MEDIA_ERR_NONE;
492 }
493
494 int ms_set_vip_process(void)
495 {
496         char buf[100] = {0};
497         int id = 0;
498         static pid_t pid = 0;
499         static char process_name[PROC_NAME_MAX] = {0};
500         static char *appid = NULL;
501
502         /* Get Pid */
503         pid = getpid();
504         if (ms_get_cmdline_from_proc(pid, process_name)) {
505                 MS_DBG_ERR("%s: Read process name failed pid[%d]", __func__, pid);
506                 return MS_MEDIA_ERR_INTERNAL;
507         }
508         appid = process_name;
509
510         MS_DBG("Process name[%s]:Pid[%d]", appid, pid);
511
512         if (prctl(PR_GET_DUMPABLE) == 0)
513                 prctl(PR_SET_DUMPABLE, 1);
514
515         snprintf(buf, sizeof(buf), PROC_OOM_SCORE_ADJ_PATH, pid);
516         id = open(buf, O_WRONLY, 0777);
517         if (id < 0) {
518                 MS_DBG_ERR("fopen %s failed errno:%d", buf, errno);
519                 return MS_MEDIA_ERR_INTERNAL;
520         }
521         snprintf(buf, sizeof(buf), "%d", VIP_OOM_SCORE_ADJ);
522         if (write(id, buf, strlen(buf)) < 0) {
523                 MS_DBG_ERR("write() failed errno=%d", errno);
524                 close(id);
525                 return MS_MEDIA_ERR_INTERNAL;
526         }
527         close(id);
528         return MS_MEDIA_ERR_NONE;
529 }
530 #endif