diff options
-rw-r--r-- | CMakeLists.txt | 34 | ||||
-rw-r--r-- | LICENSE.APLv2 | 202 | ||||
-rw-r--r-- | NOTICE | 3 | ||||
-rw-r--r-- | osp-env-config.c | 691 | ||||
-rw-r--r-- | osp-env-config.manifest | 5 | ||||
-rwxr-xr-x | packaging/osp-env-config.spec | 47 |
6 files changed, 982 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..01972db --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,34 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(this_target osp-env-config) + +INCLUDE_DIRECTORIES( + /usr/include/vconf + /usr/include/dlog +) + +SET (${this_target}_SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/osp-env-config.c + ) + +ADD_LIBRARY(${this_target} SHARED ${${this_target}_SOURCE_FILES}) + +SET(CMAKE_C_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") +SET(CMAKE_CXX_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}") +SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--as-needed") + +TARGET_LINK_LIBRARIES(${this_target} "-lvconf -ldlog") + +SET_TARGET_PROPERTIES(${this_target} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 + ) + +INSTALL(TARGETS ${this_target} DESTINATION lib + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License terms and conditions. diff --git a/osp-env-config.c b/osp-env-config.c new file mode 100644 index 0000000..fbfa70e --- /dev/null +++ b/osp-env-config.c @@ -0,0 +1,691 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sched.h> +#include <sys/mount.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <limits.h> +#include <sys/prctl.h> +#include <sys/vfs.h> + +#include <dlog.h> +#include <vconf.h> + +#undef LOG_TAG +#define LOG_TAG "ENV_CONFIG" + +#define _MAX_PACKAGEID_LENGTH 10 +#define _MAX_APIVERSION_LENGTH 3 + +static const char* _OSP_HOME_PATH = "/opt/osp/\0"; // /opt/apps/com.samsung.osp +static const char* _OSP_COMPAT_SHARED_PATH = "/opt/usr/share/.osp-compat/\0"; +static const char* _EXT_OSP_HOME_PATH = "/opt/storage/sdcard/osp/\0"; + +struct _path_info +{ + char src_path[PATH_MAX]; + char dest_path[PATH_MAX]; +}; + +struct _dir_info +{ + char path[PATH_MAX]; + mode_t mode; + char app_privilege; // 0: root privilege +}; + +/* + * XXX: The returned app_roodir must be freed in caller. + */ +static char* +get_app_rootpath_from_path(const char* bin_path) +{ + char* app_rootpath = NULL; + char* delimiter = NULL; + size_t length = 0; + /* e.g., The specified bin_path is "/opt/apps/com.samsung.basicapp/bin/basicapp" */ + + length = strlen(bin_path); + app_rootpath = (char *)malloc(length + 1); + if(app_rootpath == NULL) + return NULL; + + memset(app_rootpath, '\0', length + 1); + strncpy(app_rootpath, bin_path, length); + + LOGI("input bin_path: %s", app_rootpath); + + delimiter = strrchr(app_rootpath, '/'); + *delimiter = '\0'; + + delimiter = strrchr(app_rootpath, '/'); + *delimiter = '\0'; + + return app_rootpath; +} + +static void +get_package_id_from_app_rootpath(const char* app_rootpath, char* package_id) +{ + const char* p = NULL; + if (strncmp(app_rootpath, "/opt/apps/org.tizen.", 19) == 0) + { + p = strrchr(app_rootpath, '.') + 1; + } + else + { + p = strrchr(app_rootpath, '/') + 1; + } + strncpy(package_id, p, _MAX_PACKAGEID_LENGTH); + package_id[_MAX_PACKAGEID_LENGTH] = '\0'; + LOGI("package id: %s", package_id); +} + +static void +get_package_id_from_package_name(const char* package_name, char* package_id) +{ + char* tmpbuf = NULL; + + if (strncmp(package_name, "com", 3) == 0) + { // in case of com.samsung.#osp#[package_id]#[serviceid] + tmpbuf = strstr(package_name, "#osp#"); + if (tmpbuf != NULL) + { + strncpy(package_id, tmpbuf + 5, _MAX_PACKAGEID_LENGTH); + } + } + else if (strncmp(package_name, "osp", 3) == 0) + { // in case of osp.[package_id].#osp#[serviceid] + tmpbuf = strstr(package_name, "osp."); + if (tmpbuf != NULL) + { + strncpy(package_id, tmpbuf + 4, _MAX_PACKAGEID_LENGTH); + } + } + else if (strncmp(package_name, "org.tizen", 9) == 0) + { + // in case of org.tizen.[package_id]#[serviceid] + tmpbuf = strstr(package_name, "org.tizen."); + if (tmpbuf != NULL) + { + strncpy(package_id, tmpbuf + 10, _MAX_PACKAGEID_LENGTH); + } + } + else if (strlen(package_name) == 10) + { + strncpy(package_id, package_name, _MAX_PACKAGEID_LENGTH); + } + else + { + LOGE("package name is invalid (%s)", package_name); + } + + package_id[_MAX_PACKAGEID_LENGTH] = '\0'; + LOGI("package_id: %s", package_id); +} + +static int +internal_is_mounted(const char* pkgid) +{ + char mount_flag[64] = { 0, }; + static const char dir[][64] = + { + { "/tmp/osp-compat" }, + { "/tmp/osp-compat/mount" }, + { "/tmp/osp-compat/mount/internal" } + }; + + sprintf(mount_flag, "/tmp/osp-compat/mount/internal/%s", pkgid); + int res = access(mount_flag, F_OK); + if (res == 0) + { + LOGI("Intenal path is already mounted."); + return 1; + } + else if (res == -1 && errno == ENOENT) + { + int i = 0; + for (i = 0; i < sizeof(dir)/64; ++i) + { + int res = mkdir(dir[i], 0755); + if (res == -1 && errno != EEXIST) + { + LOGE("Failed to create directory (%s), errno: %d (%s)", dir[i], errno, strerror(errno)); + return 1; + } + } + + int fd = creat(mount_flag, 0644); + if (fd == -1) + { + LOGE("Failed to create mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno)); + return 1; + } + close(fd); + } + else + { + LOGE("Failed to access mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno)); + return 1; + } + + LOGI("Intenal path mount succeeded."); + return 0; +} + +static int +external_is_mounted(const char* pkgid) +{ + char mount_flag[64] = { 0, }; + static const char dir[][64] = + { + { "/tmp/osp-compat" }, + { "/tmp/osp-compat/mount" }, + { "/tmp/osp-compat/mount/external" } + }; + + sprintf(mount_flag, "/tmp/osp-compat/mount/external/%s", pkgid); + int res = access(mount_flag, F_OK); + if (res == 0) + { + LOGI("Extenal path is already mounted."); + return 1; + } + else if (res == -1 && errno == ENOENT) + { + int i = 0; + for (i = 0; i < sizeof(dir)/64; ++i) + { + int res = mkdir(dir[i], 0755); + if (res == -1 && errno != EEXIST) + { + LOGE("Failed to create directory (%s), errno: %d (%s)", dir[i], errno, strerror(errno)); + return 1; + } + } + + int fd = creat(mount_flag, 0644); + if (fd == -1) + { + LOGE("Failed to create mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno)); + return 1; + } + close(fd); + } + else + { + LOGE("Failed to access mount flag (%s), errno: %d (%s)", mount_flag, errno, strerror(errno)); + return 1; + } + + LOGI("Extenal path mount succeeded."); + return 0; +} + +static int +mount_slp_paths(const char* app_rootpath) +{ + int i = 0; + static const struct _path_info mount_info[] = { + //{ "/bin", "./bin" }, + //{ "/boot", "./boot" }, + //{ "/cache", "./cache" }, + { "/csa", "./csa" }, + { "/dev", "./dev" }, + { "/dev/pts", "./dev/pts" }, + { "/dev/shm", "./dev/shm" }, + { "/etc", "./etc" }, + { "/lib", "./lib" }, + //{ "/lost+found", "./lost+found" }, + { "/media", "./media" }, + { "/mnt", "./mnt" }, + { "/opt", "./opt" }, + { "/opt/usr", "./opt/usr" }, + { "/opt/var/kdb/db", "./opt/var/kdb/db" }, + { "/opt/storage/sdcard","./opt/storage/sdcard" }, + //{ "/packaging", "./packaging" }, + { "/proc", "./proc" }, + { "/sbin", "./sbin" }, + { "/srv", "./srv" }, + { "/sys", "./sys" }, + { "/sys/kernel/debug", "./sys/kernel/debug" }, + { "/tmp", "./tmp" }, + { "/usr", "./usr" }, + { "/var", "./var" }, + { "/var/run", "./var/run" } + }; + + if (chdir(app_rootpath) != 0) + { + LOGE("chdir() failed path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno)); + return -1; + } + + for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i) + { + if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0) + { + LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)", + mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno)); + + int j = 0; + for (j = i; j > 0; --j) + { + umount2(mount_info[j-1].dest_path, MNT_DETACH); + } + return -1; + } + } + + return 0; +} + +static int +mount_osp_internal_paths(const char* app_rootpath, const char* pkgid) +{ + int i = 0; + char osp_share_pkgid_path[PATH_MAX] = {0, }; + char osp_share2_pkgid_path[PATH_MAX] = {0, }; + struct _path_info mount_info[] = { + { "\0", "./data/Share" }, + { "\0", "./data/Share2" }, + { "/opt/usr/share/.osp-compat/share", "./Share" }, + { "/opt/usr/share/.osp-compat/share2", "./Share2" }, + //{ "/opt/osp/clipboard", "./Clipboard" }, + //{ "/opt/osp/partner/npki", "./NPKI" }, + //{ "/opt/osp/system", "./System" }, + //{ "/opt/osp/Tmp", "./Tmp" }, + { "/opt/usr/media", "./Media" } + }; + + strncpy(osp_share_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH)); + strncat(osp_share_pkgid_path, "share/", 6); + strncat(osp_share_pkgid_path, pkgid, strlen(pkgid)); + + strncpy(osp_share2_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH)); + strncat(osp_share2_pkgid_path, "share2/", 7); + strncat(osp_share2_pkgid_path, pkgid, strlen(pkgid)); + + strncpy(mount_info[0].src_path, osp_share_pkgid_path, strlen(osp_share_pkgid_path)); + strncpy(mount_info[1].src_path, osp_share2_pkgid_path, strlen(osp_share2_pkgid_path)); + + if (chdir(app_rootpath) != 0) + { + LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno)); + return -1; + } + + for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); ++i) + { + if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0) + { + LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)", + mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno)); + + int j = 0; + for (j = i; j > 0; --j) + { + umount2(mount_info[j-1].dest_path, MNT_DETACH); + } + return -1; + } + } + + return 0; +} + +static int +link_osp_share_path(const char* app_rootpath, const char* pkgid) +{ + char osp_app_share_path[PATH_MAX] = {0, }; + char osp_share_pkgid_path[PATH_MAX] = {0, }; + + strncpy(osp_app_share_path, app_rootpath, strlen(app_rootpath)); + strncat(osp_app_share_path, "/shared/data", 12); + + strncpy(osp_share_pkgid_path, _OSP_COMPAT_SHARED_PATH, strlen(_OSP_COMPAT_SHARED_PATH)); + strncat(osp_share_pkgid_path, "share/", 6); + strncat(osp_share_pkgid_path, pkgid, strlen(pkgid)); + + unlink(osp_share_pkgid_path); + + int ret = symlink(osp_app_share_path, osp_share_pkgid_path); + if (ret == -1 && errno != 17) // EEXIST + { + LOGE("symlink() failed, src path: %s, dest path: %s, errno: %d (%s)", + osp_app_share_path, osp_share_pkgid_path, errno, strerror(errno)); + return -1; + } + + return 0; +} + +static int +create_osp_external_paths(const char* app_rootpath, const char* pkgid) +{ + char osp_ext_apps_pkgid_path[PATH_MAX] = {0, }; + char osp_ext_apps_pkgid_share_path[PATH_MAX] = {0, }; + char osp_ext_apps_pkgid_share2_path[PATH_MAX] = {0, }; + char osp_ext_share_pkgid_path[PATH_MAX] = {0, }; + char osp_ext_share2_pkgid_path[PATH_MAX] = {0, }; + struct _dir_info external_dirs[] = { + { "./HomeExt", 0000, 0}, + { "./ShareExt", 0000, 0}, + { "./Share2Ext", 0000, 0}, + { "/opt/storage/sdcard/osp", 0777, 0 }, + { "/opt/storage/sdcard/osp/apps", 0777, 0 }, + { "/opt/storage/sdcard/osp/share", 0777, 0 }, + { "/opt/storage/sdcard/osp/share2", 0777, 0 }, + { "\0", 0777, 0}, + { "\0", 0777, 0}, + { "\0", 0777, 0}, + { "\0", 0777, 0}, + { "\0", 0777, 0}, + { "/opt/storage/sdcard/Images", 0777, 0 }, + { "/opt/storage/sdcard/Sounds", 0777, 0 }, + { "/opt/storage/sdcard/Videos", 0777, 0 }, + //{ "/opt/storage/sdcard/Themes", 0777, 0 }, + { "/opt/storage/sdcard/Others", 0777, 0 } + }; + int i = 0; + + strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH)); + strncat(osp_ext_apps_pkgid_path, "apps/", 5); + strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid)); + + strncpy(osp_ext_apps_pkgid_share_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path)); + strncat(osp_ext_apps_pkgid_share_path, "/Share", 6); + + strncpy(osp_ext_apps_pkgid_share2_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path)); + strncat(osp_ext_apps_pkgid_share2_path, "/Share2", 7); + + strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH)); + strncat(osp_ext_share_pkgid_path, "share/", 6); + strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid)); + + strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH)); + strncat(osp_ext_share2_pkgid_path, "share2/", 7); + strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid)); + + strncpy(external_dirs[7].path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path)); + strncpy(external_dirs[8].path, osp_ext_apps_pkgid_share_path, strlen(osp_ext_apps_pkgid_share_path)); + strncpy(external_dirs[9].path, osp_ext_apps_pkgid_share2_path, strlen(osp_ext_apps_pkgid_share2_path)); + strncpy(external_dirs[10].path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path)); + strncpy(external_dirs[11].path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path)); + + if (chdir(app_rootpath) != 0) + { + LOGE("chdir() failed (%s), path: %s", strerror(errno), app_rootpath); + return -1; + } + + for (i = 0; i < sizeof(external_dirs)/sizeof(struct _dir_info); i++) + { + int ret = mkdir(external_dirs[i].path, external_dirs[i].mode); + if (ret == -1 && errno != 17) // EEXIST + { + LOGE("mkdir() failed, path: %s, errno: %d (%s)", external_dirs[i].path, errno, strerror(errno)); + return -1; + } + } + + return 0; +} + +static int +mount_osp_external_paths(const char* app_rootpath, const char* pkgid) +{ + char osp_ext_apps_pkgid_path[PATH_MAX] = {0, }; + char osp_ext_share_pkgid_path[PATH_MAX] = {0, }; + char osp_ext_share2_pkgid_path[PATH_MAX] = {0, }; + struct _path_info mount_info[] = { + { "/opt/storage/sdcard", "./Storagecard/Media" }, + //{ "/opt/storage/sdcard/osp/share", "./ShareExt" }, + //{ "/opt/storage/sdcard/osp/share2", "./Share2Ext" }, + { "\0", "./HomeExt" }, + //{ "\0", "./HomeExt/Share" }, + //{ "\0", "./HomeExt/Share2" }, + }; + int i = 0; + + strncpy(osp_ext_apps_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH)); + strncat(osp_ext_apps_pkgid_path, "apps/", 5); + strncat(osp_ext_apps_pkgid_path, pkgid, strlen(pkgid)); + +#if 0 + strncpy(osp_ext_share_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH)); + strncat(osp_ext_share_pkgid_path, "share/", 6); + strncat(osp_ext_share_pkgid_path, pkgid, strlen(pkgid)); + + strncpy(osp_ext_share2_pkgid_path, _EXT_OSP_HOME_PATH, strlen(_EXT_OSP_HOME_PATH)); + strncat(osp_ext_share2_pkgid_path, "share2/", 7); + strncat(osp_ext_share2_pkgid_path, pkgid, strlen(pkgid)); + + strncpy(mount_info[3].src_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path)); + strncpy(mount_info[4].src_path, osp_ext_share_pkgid_path, strlen(osp_ext_share_pkgid_path)); + strncpy(mount_info[5].src_path, osp_ext_share2_pkgid_path, strlen(osp_ext_share2_pkgid_path)); +#else + strncpy(mount_info[1].src_path, osp_ext_apps_pkgid_path, strlen(osp_ext_apps_pkgid_path)); +#endif + + if (chdir(app_rootpath) != 0) + { + LOGE("chdir() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno)); + return -1; + } + LOGI("app_rootpath: %s", app_rootpath); + + for (i = 0; i < sizeof(mount_info)/sizeof(struct _path_info); i++) + { + if (mount(mount_info[i].src_path, mount_info[i].dest_path, NULL, MS_BIND, NULL) != 0) + { + LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)", + mount_info[i].src_path, mount_info[i].dest_path, errno, strerror(errno)); + + int j = 0; + for (j = i; j > 0; --j) + { + umount2(mount_info[j-1].dest_path, MNT_DETACH); + } + return -1; + } + } + + return 0; +} + +int +do_pre_exe(const char* package_name, const char* bin_path, const char* package_id) +{ + char* app_rootpath = NULL; + char osp_app_data_path[PATH_MAX] = {0, }; + //char internal_installed = 1; // true + int mmc_mounted = 0; + struct statfs fs; + + /* e.g., app_rootdir is "/opt/apps/com.samsung.basicapp or /opt/osp/applications/[appId] */ + app_rootpath = get_app_rootpath_from_path(bin_path); + + LOGI("[data_caging] do_pre_exe() was called, package name: %s, \ + binary path: %s, application root(home) path: %s, package id: %s", + package_name, bin_path, app_rootpath, package_id); + + umask(0000); + + // TODO: Check whether the application is installed in internal or external storage. + // Check installation position using the input path. + //if (internal_installed) + //{ + + if (!internal_is_mounted(package_id)) + { + if (mount_slp_paths(app_rootpath) != 0) + goto ERROR; + + if (mount_osp_internal_paths(app_rootpath, package_id) != 0) + goto ERROR; + } + + int ret = 0; + ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_mounted); + if (ret < 0) + { + LOGE("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed."); + } + if (mmc_mounted == 1) + { + LOGI("MMC is mounted."); + if (create_osp_external_paths(app_rootpath, package_id) != 0) + { + goto ERROR; + } + + if (!external_is_mounted(package_id)) + { + if (mount_osp_external_paths(app_rootpath, package_id) != 0) + { + goto ERROR; + } + } + } + /*} + else + { + // TODO mount_external_paths(app_rootpath); + }*/ + LOGI("mount() succeeded."); + + if (chroot(app_rootpath) != 0) + { + LOGE("chroot() failed, path: %s, errno: %d (%s)", app_rootpath, errno, strerror(errno)); + goto ERROR; + } + if (chdir("/") != 0) + { + LOGE("chdir() failed, path: /, errno: %d (%s)", errno, strerror(errno)); + goto ERROR; + } + LOGI("chroot() succeeded."); + + // set current working dir to "/opt/apps/{packageId}/data" +#if 0 + strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath)); + strncat(osp_app_data_path, "/data", strlen("/data")); +#endif + + if (chdir("/data") != 0) + { + LOGE("chdir() failed, path: /data, errno: %d (%s)", errno, strerror(errno)); + goto ERROR; + } + + free(app_rootpath); + umask(0022); + + LOGI("[data_caging] do_pre_exec() succeeded."); + return 0; + +ERROR: + free(app_rootpath); + umask(0022); + + LOGI("[data_caging] do_pre_exec() failed."); + return -1; +} + +int +do_pre_exec(const char* package_name, const char* bin_path) +{ + char* app_rootpath = NULL; + char app_compat_path[PATH_MAX] = { 0, }; + const char app_compat_file[] = "/info/compat.info\0"; + int pathlen = 0; + char package_id[_MAX_PACKAGEID_LENGTH + 1] = { 0, }; + char osp_app_data_path[PATH_MAX] = { 0, }; + int osp_compat = 0; + + LOGI("do_pre_exec() is called, package_name: %s, bin_path: %s", package_name, bin_path); + + app_rootpath = get_app_rootpath_from_path(bin_path); + + strncpy(app_compat_path, app_rootpath, strlen(app_rootpath)); + strncat(app_compat_path, app_compat_file, strlen(app_compat_file)); + if (access(app_compat_path, F_OK) == 0) + { + osp_compat = 1; + } + + // XXX: temp code + //if (package_name == NULL) + { + //LOGI("The package name is empty."); + get_package_id_from_app_rootpath(app_rootpath, package_id); + } +#if 0 + else + { + get_package_id_from_package_name(package_name, package_id); + } +#endif + // XXX-end + + LOGI("package name: %s, binary path: %s, package id: %s, OSP compatibility: %d", + package_name, bin_path, package_id, osp_compat); + + // FIXME: Temporary code with security risk + prctl(PR_SET_KEEPCAPS, 1); + + if (osp_compat == 1) + { + free(app_rootpath); + //unshare(CLONE_NEWNS); + return do_pre_exe(package_name, bin_path, package_id); + } + + // API version is equal to or greater than Tizen 2.0 + // Set current working dir to "/opt/apps/{pkgId}/data" + strncpy(osp_app_data_path, app_rootpath, strlen(app_rootpath)); + strncat(osp_app_data_path, "/data", strlen("/data")); + + if (chdir(osp_app_data_path) != 0) + { + LOGE("chdir() failed, path: %s, errno: %d (%s)", osp_app_data_path, errno, strerror(errno)); + goto ERROR; + } + + if (link_osp_share_path(app_rootpath, package_id) != 0) + { + goto ERROR; + } + + LOGI("[data_caging] do_pre_exec() succeeded."); + free(app_rootpath); + return 0; + +ERROR: + free(app_rootpath); + return -1; +} diff --git a/osp-env-config.manifest b/osp-env-config.manifest new file mode 100644 index 0000000..ae3e6f7 --- /dev/null +++ b/osp-env-config.manifest @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_"/> + </request> +</manifest>
\ No newline at end of file diff --git a/packaging/osp-env-config.spec b/packaging/osp-env-config.spec new file mode 100755 index 0000000..f913c65 --- /dev/null +++ b/packaging/osp-env-config.spec @@ -0,0 +1,47 @@ +Name: osp-env-config +Summary: osp application environment cofiguration serivce +Version: 1.2.0.0 +Release: 1 +Group: System/Libraries +License: Apache License, Version 2.0 or Flora +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(vconf) + +Requires(post): coreutils + +%description +osp application environment cofiguration serivce + +%prep +%setup -q + +%build +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +%ifarch %{ix86} +CXXFLAGS="$CXXFLAGS -D_OSP_DEBUG_ -D_OSP_X86_ -D_OSP_EMUL_" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%else +CXXFLAGS="-O2 -g -pipe -Wall -fno-exceptions -Wformat -Wformat-security -Wl,--as-needed -fmessage-length=0 -march=armv7-a -mtune=cortex-a8 -mlittle-endian -mfpu=neon -mfloat-abi=softfp -D__SOFTFP__ -mthumb -Wa,-mimplicit-it=thumb -funwind-tables -D_OSP_DEBUG_ -D_OSP_ARMEL_" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%endif + +# Call make instruction with smp support +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +cp %{_builddir}/%{name}-%{version}/LICENSE.APLv2 %{buildroot}/usr/share/license/%{name} + +%make_install + +%post +/sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%manifest osp-env-config.manifest +/usr/share/license/%{name} +/usr/lib/*.so* + |