4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
8 * Jaewon Lim <jaewon81.lim@samsung.com>
9 * Woojin Jung <woojin2.jung@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
11 * Cherepanov Vitaliy <v.cherepanov@samsung.com>
12 * Nikita Kalyazin <n.kalyazin@samsung.com>
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
18 * http://www.apache.org/licenses/LICENSE-2.0
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
28 * - Samsung RnD Institute Russia
38 #include <unistd.h> // for unlink
39 #include <dirent.h> // for opendir, readdir
40 #include <sys/types.h> // for open
41 #include <sys/stat.h> // for open
42 #include <fcntl.h> // for open
43 #include <grp.h> // for setgroups
45 #include <sys/smack.h>
51 #define BUFFER_MAX 1024
52 #define APP_GROUPS_MAX 100
53 #define APP_GROUP_LIST "/usr/share/privilege-control/app_group_list"
54 #define SELF_LABEL_FILE "/proc/self/attr/current"
57 #define SMACK_LABEL_LEN 255
61 #define MANIFEST_PATH "/info/manifest.xml"
63 #define APPDIR1 "/opt/apps/"
64 #define APPDIR2 "/opt/usr/apps/"
66 uint64_t str_to_uint64(char* str)
72 while(*str >= '0' && *str <= '9')
74 res = res * 10 + (*str - '0');
82 int64_t str_to_int64(char* str)
100 while(*str >= '0' && *str <= '9')
102 res = res * 10 + (*str - '0');
107 return (res * factor);
110 int read_line(const int fd, char* ptr, const unsigned int maxlen)
118 if((rc = read(fd, c, 1)) != 1)
119 return -1; // eof or read err
128 return -1; // no space
132 int smack_set_label_for_self(const char *label)
138 len = strnlen(label, SMACK_LABEL_LEN + 1);
139 if (len > SMACK_LABEL_LEN)
142 fd = open(SELF_LABEL_FILE, O_WRONLY);
146 ret = write(fd, label, len);
149 return (ret < 0) ? -1 : 0;
153 void set_appuser_groups(void)
158 gid_t groups[APP_GROUPS_MAX] = {0, };
161 // groups[cnt++] = SID_DEVELOPER;
162 fd = open(APP_GROUP_LIST, O_RDONLY);
165 LOGE("cannot get app's group lists from %s", APP_GROUP_LIST);
171 if(read_line(fd, buffer, sizeof buffer) < 0)
176 t_gid = strtoul(buffer, 0, 10);
180 LOGE("cannot change string to integer: [%s]\n", buffer);
186 if(cnt < APP_GROUPS_MAX)
188 groups[cnt++] = t_gid;
192 LOGE("cannot add groups more than %d", APP_GROUPS_MAX);
200 if(setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0)
202 fprintf(stderr, "set groups failed errno: %d\n", errno);
211 int get_smack_label(const char* execpath, char* buffer, int buflen)
216 rc = smack_lgetlabel(execpath, &appid, SMACK_LABEL_ACCESS);
217 if(rc == 0 && appid != NULL)
219 strncpy(buffer, appid, (buflen < strlen(appid))? buflen:strlen(appid));
228 int get_appid(const char* execpath, char* buffer, int buflen)
232 if(strncmp(execpath, APPDIR1, strlen(APPDIR1)) == 0)
234 execpath = execpath + strlen(APPDIR1);
235 temp = strchr(execpath, '/');
236 for(i = 0; i < strlen(execpath); i++)
238 if(execpath + i == temp)
240 buffer[i] = execpath[i];
244 temp = strrchr(execpath, '/');
248 strcat(buffer, temp);
251 else if(strncmp(execpath, APPDIR2, strlen(APPDIR2)) == 0)
253 execpath = execpath + strlen(APPDIR2);
254 temp = strchr(execpath, '/');
255 for(i = 0; i < strlen(execpath); i++)
257 if(execpath + i == temp)
259 buffer[i] = execpath[i];
263 temp = strrchr(execpath, '/');
267 strcat(buffer, temp);
278 // return 0 if succeed
279 // return -1 if error occured
280 int remove_indir(const char *dirname)
283 struct dirent *entry;
286 dir = opendir(dirname);
292 while((entry = readdir(dir)) != NULL)
294 if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
296 snprintf(path, (size_t) PATH_MAX, "%s/%s", dirname, entry->d_name);
297 if (entry->d_type != DT_DIR) // file
301 else { } // directory
309 // get application name from executable binary path
310 char* get_app_name(char* binary_path)
314 pos = strrchr(binary_path, '/');
321 // return 0 to normal case
322 // return non-zero to error case
323 int get_manifest_path(const char* exec_path, char* buf, int buflen)
327 strcpy(buf, exec_path);
329 chr = strrchr(buf, '/');
335 chr = strrchr(buf, '/');
341 strcat(buf, MANIFEST_PATH);
345 // execute applcation with executable binary path
346 // return 0 to fail to execute
347 // return 1 to succeed to execute
348 int exec_app_tizen(const char *app_id, const char *exec_path)
350 LOGI("exec %s\n", exec_path);
352 //char command[PATH_MAX];
353 //char appid[PATH_MAX];
355 if (exec_path == NULL || !strlen(exec_path)) {
356 LOGE("Executable path is not correct\n");
364 return 0; // exit parent process with success
366 LOGI("launch app path is %s, executable path is %s\n"
367 "launch app name (%s), app_id (%s)\n",
368 LAUNCH_APP_PATH, exec_path,
369 LAUNCH_APP_NAME, app_id);
370 execl(LAUNCH_APP_PATH, LAUNCH_APP_NAME, app_id, LAUNCH_APP_SDK,
371 DA_PRELOAD_EXEC, NULL);
376 int exec_app_common(const char* exec_path)
378 LOGI("kill %s\n", exec_path);
382 char manifest[PATH_MAX];
383 char command[PATH_MAX];
385 // TODO: check if this makes sense
386 /* char appid[SMACK_LABEL_LEN]; */
388 if (exec_path == NULL || !strlen(exec_path)) {
389 LOGE("Executable path is not correct\n");
397 return 0; // exit parent process with success
399 if (get_manifest_path(exec_path, manifest, PATH_MAX) == 0) {
401 char buffer[BUFFER_MAX];
405 sprintf(command, "grep \"HwAcceleration=\\\"On\\\"\" %s",
407 fp = popen(command, "r");
410 res = fgets(buffer, BUFFER_MAX, fp);
411 if (res != NULL && strlen(buffer) != 0) {
418 // FIXME: I think the followin does not make sense
419 /* #ifndef LOCALTEST */
420 /* if (get_smack_label(exec_path, appid, SMACK_LABEL_LEN - 1) < 0) { */
421 /* LOGE("failed to get smack label\n"); */
426 /* #ifndef LOCALTEST */
427 /* LOGI("smack lable is %s\n", appid); */
428 /* if(smack_set_label_for_self(appid) < 0) { */
429 /* LOGE("failed to set label for self\n"); */
432 /* set_appuser_groups(); */
433 /* if (setgid(SID_APP) < 0) { */
434 /* LOGE("failed to setgid\n"); */
436 /* if (setuid(SID_APP) < 0) { */
437 /* LOGE("failed to setuid\n"); */
440 /* pid = getpid(); */
441 /* if (setpgid(pid, pid) < 0) { */
442 /* LOGE("failed to setpgid\n"); */
445 /* if (hw_acc != 0) { */
446 /* sprintf(command, "HWACC=USE %s %s", DA_PRELOAD(app_type), exec_path); */
448 /* sprintf(command, "%s %s", DA_PRELOAD(app_type), exec_path); */
451 /* LOGI("launch app path is %s, executable path is %s\n", LAUNCH_APP_PATH, exec_path); */
452 /* execl(SHELL_CMD, SHELL_CMD, "-c", command, NULL); */
457 /* sprintf(command, "HWACC=USE %s %s", */
458 /* DA_PRELOAD(app_type), exec_path); */
460 /* sprintf(command, "%s %s", */
461 /* DA_PRELOAD(app_type), exec_path); */
463 sprintf(command, "%s %s",
464 DA_PRELOAD_OSP, exec_path);
465 #else /* LOCALTEST */
466 sprintf(command, "%s", exec_path);
467 #endif /* LOCALTEST */
469 LOGI("cmd: %s\n", command);
470 execl(SHELL_CMD, SHELL_CMD, "-c", command, NULL);
475 // find process id from executable binary path
476 pid_t find_pid_from_path(const char* path)
480 char buffer [BUFFER_MAX];
481 char command [BUFFER_MAX];
483 sprintf(command, "/bin/pidof %s", path);
485 FILE *fp = popen(command, "r");
488 LOGW("Getting pidof %s is failed\n", path);
492 while (fgets(buffer, BUFFER_MAX, fp) != NULL)
494 LOGI("result of 'pidof' is %s\n", buffer);
499 if (strlen(buffer) > 0)
501 if (sscanf(buffer,"%d\n", &status) != 1)
503 LOGW("Failed to read result buffer of 'pidof',"
504 " status(%d) with cmd '%s'\n", status, command);
512 void kill_app(const char* binary_path)
514 LOGI("kill %s\n", binary_path);
517 char command[PATH_MAX];
519 pkg_pid = find_pid_from_path(binary_path);
521 sprintf(command, "kill -9 %d", pkg_pid);
526 int get_executable(char* appPath, char* buf, int buflen)
530 sprintf(buf, "%s.exe", appPath);
531 fd = open(buf, O_RDONLY);
538 strcpy(buf, appPath);
543 int get_app_install_path(char *strAppInstall, int length)
546 char buf[BUFFER_MAX];
550 if ((fp = fopen(DA_INSTALL_PATH, "r")) == NULL)
552 LOGE("Failed to open %s\n", DA_INSTALL_PATH);
556 /*ex : <15> DW_AT_comp_dir : (indirect string, offset: 0x25f): /home/yt/workspace/templatetest/Debug-Tizen-Emulator */
557 while (fgets(buf, BUFFER_MAX, fp) != NULL)
561 for (i = 0; i < BUFFER_MAX; i++)
574 for (; i < BUFFER_MAX; i++)
591 for (; i < BUFFER_MAX - 1; i++)
593 if (*p == ':' || *p == ' ' || *p == '\t')
600 if (strlen(p) <= length)
602 sprintf(strAppInstall, "%s", p);
603 for (i = 0; i < strlen(p); i++)
605 if (strAppInstall[i] == '\n' || strAppInstall[i] == '\t')
607 strAppInstall[i] = '\0';
619 int is_app_built_pie(void)
623 char buf[BUFFER_MAX];
625 if((fp = fopen(DA_BUILD_OPTION, "r")) == NULL)
627 LOGE("Failed to open %s\n", DA_BUILD_OPTION);
631 if(fgets(buf, BUFFER_MAX, fp) != NULL)
633 if(strcmp(buf, "DYN\n") == 0)
635 else if(strcmp(buf, "EXEC\n") == 0)
649 int get_app_base_address(int *baseAddress)
653 char buf[BUFFER_MAX];
655 if((fp = fopen(DA_BASE_ADDRESS, "r")) == NULL)
657 LOGE("Failed to open %s\n", DA_BASE_ADDRESS);
661 if(fgets(buf, BUFFER_MAX, fp) != NULL)
663 res = sscanf(buf, "%x", baseAddress);
674 int is_same_app_process(char* appPath, int pid)
679 char buf[BUFFER_MAX];
680 char cmdPath[PATH_MAX];
681 char tPath[PATH_MAX];
682 char buf_res[PATH_MAX];
683 char tPath_res[PATH_MAX];
685 strcpy(tPath, appPath);
686 tlen = strlen(tPath);
687 if(strcmp(tPath + tlen - 4, ".exe") == 0)
689 // remove .exe from tPath
690 tPath[tlen - 4] = '\0';
693 sprintf(cmdPath, "/proc/%d/cmdline", pid);
695 if((fp = fopen(cmdPath, "r")) == NULL)
700 if(fgets(buf, BUFFER_MAX, fp) != NULL)
703 if(strcmp(buf + tlen - 4, ".exe") == 0)
705 // remove .exe from tPath
706 buf[tlen - 4] = '\0';
709 dereference_tizen_exe_path(buf, buf_res);
710 dereference_tizen_exe_path(tPath, tPath_res);
712 if(strcmp(buf_res, tPath_res) == 0)
722 char *dereference_tizen_exe_path(const char *path, char *resolved)
725 char tmp_path[PATH_MAX];
728 //try resolve <path>.exe
729 sprintf(tmp_path, "%s.exe", path);
730 if ((res = realpath(tmp_path, resolved)) == NULL) {
731 //try to resolve path <path>
732 res = realpath(path, resolved);