From 38c4f87e9b5cd624f8d56f73c3275cfa9484df12 Mon Sep 17 00:00:00 2001 From: Sehong Na Date: Sat, 31 May 2014 12:56:31 +0900 Subject: [PATCH 1/1] Initialize Tizen 2.3 --- CMakeLists.txt | 40 +++ LICENSE.APLv2 | 202 +++++++++++ NOTICE | 3 + appinfo/CMakeLists.txt | 54 +++ appinfo/appinfo.c | 383 +++++++++++++++++++++ appinfo/appinfo.h | 154 +++++++++ appinfo/appinfo.pc.in | 13 + osp-env-config.manifest | 5 + packaging/osp-env-config.spec | 72 ++++ src/osp-env-config.c | 772 ++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 1698 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE.APLv2 create mode 100644 NOTICE create mode 100644 appinfo/CMakeLists.txt create mode 100644 appinfo/appinfo.c create mode 100644 appinfo/appinfo.h create mode 100644 appinfo/appinfo.pc.in create mode 100644 osp-env-config.manifest create mode 100644 packaging/osp-env-config.spec create mode 100644 src/osp-env-config.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..aa0fc33 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(this_target osp-env-config) + +INCLUDE_DIRECTORIES( + /usr/include/vconf + /usr/include/dlog + appinfo +) + +SET (${this_target}_SOURCE_FILES + src/osp-env-config.c + ) + +ADD_SUBDIRECTORY(appinfo) + +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") + +ADD_DEPENDENCIES(${this_target} appinfo) + +TARGET_LINK_LIBRARIES(${this_target} "-ldl -lvconf -ldlog") +TARGET_LINK_LIBRARIES(${this_target} appinfo) + + +SET_TARGET_PROPERTIES(${this_target} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 + ) + +INSTALL(TARGETS ${this_target} DESTINATION ${LIB_INSTALL_DIR} + 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. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..0e0f016 --- /dev/null +++ b/NOTICE @@ -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/appinfo/CMakeLists.txt b/appinfo/CMakeLists.txt new file mode 100644 index 0000000..a46236d --- /dev/null +++ b/appinfo/CMakeLists.txt @@ -0,0 +1,54 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(this_target appinfo) + +SET(VERSION_MAJOR 0) +SET(VERSION "${VERSION_MAJOR}.1.2") + +#INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED + dlog +) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + + +SET (${this_target}_SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/appinfo.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") + +SET_TARGET_PROPERTIES(${this_target} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 + ) + +TARGET_LINK_LIBRARIES(${this_target} ${pkgs_LDFLAGS}) + + +SET(PC_NAME ${this_target}) +SET(PC_REQUIRED ${pc_requires}) +SET(PC_LDFLAGS -l${this_target}) + +CONFIGURE_FILE(appinfo.pc.in appinfo.pc @ONLY) + +INSTALL(TARGETS ${this_target} DESTINATION ${LIB_INSTALL_DIR}/osp + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/appinfo.h DESTINATION include/osp) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/appinfo.pc DESTINATION lib/pkgconfig) + diff --git a/appinfo/appinfo.c b/appinfo/appinfo.c new file mode 100644 index 0000000..b93f840 --- /dev/null +++ b/appinfo/appinfo.c @@ -0,0 +1,383 @@ +// +// 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. +// + +#include +#include +#include +#include + +#include + +#include "appinfo.h" + +#undef LOG_TAG +#define LOG_TAG "APPINFO" + +#ifdef _SECURE_LOG +#define _SECURE_LOGI LOGI +#define _SECURE_LOGE LOGE +#else +#define _SECURE_LOGI(...) +#define _SECURE_LOGE(...) +#endif + +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +static const char INVALID_EXEC_NAME[] = ""; +static app_info_version_e _current_api_ver = APP_INFO_VERSION_2_2; +static int _compat_mode = 0; +static int _app_info_init = 0; + +static int _argc = 0; +static char** _argv = NULL; + +#define MAX_OSP_PKGID 10 +#define MAX_APPID 256 + +static char __pkgid[MAX_OSP_PKGID+1]={'\0',}; +static char __appid[MAX_APPID]={'\0',}; +static const char* _pkgid = NULL; +static const char* _appid = NULL; +static const char* _execname = &INVALID_EXEC_NAME; + + +/** + * @brief Initializes the appinfo structure + * + * @param[in] appid The application id to initialize + * @param[in] is_invalid_appid @c 1 for invalid appid compatibility mode, @c 0 otherwise + * @return 0 on success, otherwise a negative error value + * @retval APP_INFO_ERROR_NONE Succesful + * @retval APP_INFO_ERROR_INVALID_ARG The appid is invalid + * @remarks It initialize the platform API version to APP_INFO_VERSION_3_0 and compat mode 0. + */ +int +appinfo_init(const char* appid, int is_invalid_appid) +{ + if (!appid || (appid && strlen(appid) >= sizeof(__appid))) + { + return APP_INFO_ERROR_INVALID_ARG; + } + + strncpy(__appid, appid, strlen(appid)); + if (is_invalid_appid) + { + // SLP-style old appid + _pkgid = __appid; + _appid = __appid; + _execname = __appid; + } + else + { + if (strlen(appid) < sizeof(MAX_OSP_PKGID)) + { + return APP_INFO_ERROR_INVALID_ARG; + } + // proper OSP or Web appid + strncpy(__pkgid, appid, MAX_OSP_PKGID); + _appid = __appid; + _pkgid = __pkgid; + _execname = __appid+(MAX_OSP_PKGID+1); + } + + _current_api_ver = APP_INFO_VERSION_2_2; + _compat_mode = 0; + _app_info_init = 1; + + return APP_INFO_ERROR_NONE; +} + +/** + * @brief Returns the API version + * + * @return app_info_version_e value + */ +int +appinfo_get_api_version(void) +{ + return _current_api_ver; +} + +/** + * @brief Sets the API version for the current process + * + * @param[in] ver Given API version + * @return 0 on success, otherwise a negative error value + * @retval APP_INFO_ERROR_NONE Succesful + */ + +int +appinfo_set_api_version(app_info_version_e ver) +{ + if (ver < 0) + { + return APP_INFO_ERROR_INVALID_ARG; + } + + _current_api_ver = ver; + + return 0; +} + +/* +int +appinfo_set_api_version(int ver) +{ + app_info_version_e temp_ver; + temp_ver = __get_api_version_from_str(appinfo_get_api_str_by_version(ver)); + + if ( temp_ver == APP_INFO_VERSION_INVALID) + { + return APP_INFO_ERROR_INVALID_ARG; + } + else + { + _current_api_ver = temp_ver; + return APP_INFO_ERROR_NONE; + } +} +*/ + +/** + * @brief Returns the API version string by given API version + * + * @param[in] ver Given API version + * @return the API version string by the given version + * @remakr If wrong API version, return NULL + */ +const char* +appinfo_get_api_str_by_version(int ver) +{ + switch (ver) { + case APP_INFO_VERSION_1_0 : + return "1.0"; + case APP_INFO_VERSION_1_0_2 : + return "1.0.2"; + case APP_INFO_VERSION_1_1 : + return "1.1"; + case APP_INFO_VERSION_1_2 : + return "1.2"; + case APP_INFO_VERSION_2_0 : + return "2.0"; + case APP_INFO_VERSION_2_1 : + return "2.1"; + case APP_INFO_VERSION_2_2 : + return "2.2"; + case APP_INFO_VERSION_3_0 : + return "3.0"; + default : + return NULL; + } +} + +app_info_version_e appinfo_get_api_version_from_str(const char * ver_str) +{ + if (ver_str == NULL) + { + return APP_INFO_VERSION_INVALID; + } + + if (!strcmp(ver_str,"3.0")) + { + return APP_INFO_VERSION_3_0; + } + else if (!strcmp(ver_str,"2.2")) + { + return APP_INFO_VERSION_2_2; + } + else if (!strcmp(ver_str,"2.1")) + { + return APP_INFO_VERSION_2_1; + } + else if (!strcmp(ver_str,"2.0")) + { + return APP_INFO_VERSION_2_0; + } + else if (!strcmp(ver_str,"1.2")) + { + return APP_INFO_VERSION_1_2; + } + else if (!strcmp(ver_str,"1.1")) + { + return APP_INFO_VERSION_1_1; + } + else if (!strcmp(ver_str,"1.0.2")) + { + return APP_INFO_VERSION_1_0_2; + } + else if (!strcmp(ver_str,"1.0")) + { + return APP_INFO_VERSION_1_0; + } + else + { + return APP_INFO_VERSION_INVALID; + } +} + +/** + * @brief Returns whether the application is compat mode or not + * + * @return @c 1 for compat mode, @c 0 otherwise + */ +int +appinfo_is_compat(void) +{ + return _compat_mode; +} + +/** + * @brief Sets the application compat mode + * + * @param[in] the compatibility mode + * @return 0 on success, otherwise a negative error value + * @retval APP_INFO_ERROR_NONE Succesful + * @retval APP_INFO_ERROR_INVALID_ARG compat should be either @c 0 or @c 1. + */ +int +appinfo_set_compat(int compat) +{ + if (compat == 0 || compat == 1) + { + _compat_mode = compat; + return APP_INFO_ERROR_NONE; + } + return APP_INFO_ERROR_INVALID_ARG; + +} + +/** + * @brief Returns the appid for the application + * + * @retval application ID if valid, @c NULL otherwise + */ +const char* +appinfo_get_appid(void) +{ + if (likely(_app_info_init)) + { + return _appid; + } + + return NULL; +} + +/** + * @brief Returns the exec name for the application + * + * @retval application exec name if valid, empty string otherwise + */ +const char* +appinfo_get_execname(void) +{ + return _execname; +} + + +/** + * @brief Returns the packageid for the application + * + * @retval package ID if valid, @c NULL otherwise + */ +const char* +appinfo_get_packageid(void) +{ + if (likely(_app_info_init)) + { + return _pkgid; + } + + return NULL; +} + +/** + * @brief Returns whether the appinfo is initialized or not + * + * @return @c 1 if initialized, @c 0 otherwise + */ +int +appinfo_is_initialized(void) +{ + return _app_info_init; +} + +int +appinfo_set_argv(int argc, char** argv) +{ + if (argc > 0 && argv) + { + _argc = argc; + _argv = argv; + return 1; + } + return 0; +} + +int appinfo_get_argv(int* argc, char*** argv) +{ + if (_app_info_init && argc && argv) + { + *argc = _argc; + *argv = _argv; + + return 1; + } + return 0; +} + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +int appinfo_update_submode_execname_and_appid(const char* execname) +{ + if (execname == NULL) + { + return 0; + } + + const size_t max_len = MAX_APPID - MAX_OSP_PKGID - 1; + const size_t size = MIN(strlen(execname), max_len - 1); + strncpy(__appid + MAX_OSP_PKGID + 1, execname, size); + __appid[size + MAX_OSP_PKGID + 1] = '\0'; + + return 1; +} + +int appinfo_update_submode_appid(const char* appid) +{ + if (appid == NULL) + { + return 0; + } + + strncpy(__appid, appid, MAX_APPID); + + return 1; +} + +#ifdef __cplusplus +} +#endif + diff --git a/appinfo/appinfo.h b/appinfo/appinfo.h new file mode 100644 index 0000000..fa28ece --- /dev/null +++ b/appinfo/appinfo.h @@ -0,0 +1,154 @@ +// +// Copyright (c) 2013 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 _APP_INFO_H_ +#define _APP_INFO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumeration of API version + */ +typedef enum +{ + APP_INFO_VERSION_INVALID = -1, + APP_INFO_VERSION_1_0 = 100, + APP_INFO_VERSION_1_0_2 = 102, + APP_INFO_VERSION_1_1 = 110, + APP_INFO_VERSION_1_2 = 120, + APP_INFO_VERSION_2_0 = 200, + APP_INFO_VERSION_2_1 = 210, + APP_INFO_VERSION_2_2 = 220, + APP_INFO_VERSION_3_0 = 300, + APP_INFO_VERSION_MAX = 65535, +} app_info_version_e; + + +/** + * @brief Enumerations of error code + */ +typedef enum +{ + APP_INFO_ERROR_NONE = 0, /**< Successful */ + APP_INFO_ERROR_INVALID_ARG = -1, /**< Invalid argument */ +} app_info_error_e; + +/** + * @brief Initializes the appinfo structure + * + * @param[in] appid The application id to initialize + * @param[in] is_invalid_appid @c 1 for invalid appid compatibility mode, @c 0 otherwise + * @return 0 on success, otherwise a negative error value + * @retval APP_INFO_ERROR_NONE Succesful + * @retval APP_INFO_ERROR_INVALID_ARG The appid is invalid + * @remarks It initialize the platform API version to APP_INFO_VERSION_3_0 and compat mode 0. + */ +int appinfo_init(const char* appid, int is_invalid_appid); + +/** + * @brief Returns the API version + * + * @return app_info_version_e value + */ +int appinfo_get_api_version(void); + +/** + * @brief Sets the API version for the current process + * + * @param[in] ver Given API version + * @return 0 on success, otherwise a negative error value + * @retval APP_INFO_ERROR_NONE Succesful + */ +//int appinfo_set_api_version(int ver); +int appinfo_set_api_version(app_info_version_e ver); + +/** + * @brief Returns the API version string by given API version + * + * @param[in] ver Given API version + * @return the API version string by the given version + */ +const char* appinfo_get_api_str_by_version(int ver); + +/** + * @brief Returns the API version by given version string + * + * @param[in] ver_str Given version string + * @return the API version + */ +app_info_version_e appinfo_get_api_version_from_str(const char* ver_str); + +/** + * @brief Returns whether the application is compat mode or not + * + * @return @c 1 for compat mode, @c 0 otherwise + */ +int appinfo_is_compat(void); + +/** + * @brief Sets the application compat mode + * + * @param[in] the compatibility mode + * @return 0 on success, otherwise a negative error value + * @retval APP_INFO_ERROR_NONE Succesful + * @retval APP_INFO_ERROR_INVALID_ARG compat should be either @c 0 or @c 1. + */ +int appinfo_set_compat(int compat); + +/** + * @brief Returns the appid for the application + * + * @retval application ID if valid, @c NULL otherwise + */ +const char* appinfo_get_appid(void); + +/** + * @brief Returns the exec name for the application + * + * @retval application exec name if valid, empty string otherwise + */ +const char* appinfo_get_execname(void); + +/** + * @brief Returns the packageid for the application + * + * @retval package ID if valid, @c NULL otherwise + */ +const char* appinfo_get_packageid(void); + +/** + * @brief Returns whether the appinfo is initialized or not + * + * @return @c 1 if initialized, @c 0 otherwise + */ +int appinfo_is_initialized(void); + +int appinfo_set_argv(int argc, char** argv); + +int appinfo_get_argv(int* argc, char*** argv); + +int appinfo_update_submode_execname_and_appid(const char* execname); + +int appinfo_update_submode_appid(const char* appid); + +#ifdef __cplusplus +} +#endif + +#endif //_APP_INFO_H_ + diff --git a/appinfo/appinfo.pc.in b/appinfo/appinfo.pc.in new file mode 100644 index 0000000..d83c28c --- /dev/null +++ b/appinfo/appinfo.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=/usr/lib/osp +includedir=/usr/include/osp + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: -I${includedir} 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 @@ + + + + + \ No newline at end of file diff --git a/packaging/osp-env-config.spec b/packaging/osp-env-config.spec new file mode 100644 index 0000000..d3ca86b --- /dev/null +++ b/packaging/osp-env-config.spec @@ -0,0 +1,72 @@ +Name: osp-env-config +Summary: osp application environment cofiguration serivce +Version: 1.2.2.1 +Release: 4 +Group: System/Libraries +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(vconf) + +Requires(post): coreutils +Requires(post): /sbin/ldconfig + +%description +osp application environment cofiguration serivce + +%package devel +Summary: osp application environment cofiguration serivce (devel) +Group: System/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +osp application environment cofiguration serivce (devel) + +%prep +%setup -q + +%build +%if 0%{?tizen_build_binary_release_type_eng} +CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE" +%endif +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` + +%ifarch %{ix86} x86_64 +%if 0%{?simulator} +CFLAGS="$CFLAGS -D_OSP_DEBUG_ -D_OSP_X86_ -D_OSP_EMUL_" %cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%else +CFLAGS="$CFLAGS -D_OSP_DEBUG_ -D_OSP_X86_" %cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%endif +%else +%if 0%{?tizen_build_binary_release_type_eng} +CFLAGS="-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_ -DTIZEN_ENGINEER_MODE" %cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%else +CFLAGS="-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 . -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%endif +%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} +%{_libdir}/*.so* +%{_libdir}/osp/libappinfo.so* + +%files devel +%{_includedir}/osp/*.h +%{_libdir}/pkgconfig/appinfo.pc diff --git a/src/osp-env-config.c b/src/osp-env-config.c new file mode 100644 index 0000000..b42c102 --- /dev/null +++ b/src/osp-env-config.c @@ -0,0 +1,772 @@ +// +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#undef LOG_TAG +#define LOG_TAG "ENV_CONFIG" + +#define _MAX_PACKAGEID_LENGTH 10 +#define _MAX_APIVERSION_LENGTH 3 + +#ifdef TIZEN_ENGINEER_MODE +#define _SECURE_LOGI SECURE_LOGI +#define _SECURE_LOGE SECURE_LOGE +#else +#define _SECURE_LOGI(...) +#define _SECURE_LOGE(...) +#endif + +static const char _OSP_COMPAT_SHARED_PATH[] = "/opt/usr/share/.osp-compat/"; +static const char _EXT_OSP_HOME_PATH[] = "/opt/storage/sdcard/osp/"; +static const char OSP_COMPAT_LIB[] = "/usr/lib/osp/libosp-compat.so"; +static const int MAX_PACKAGE_ID = NAME_MAX; + +struct _path_info +{ + char src_path[PATH_MAX]; + const 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); + if (length > (PATH_MAX - 1)) + { + LOGE("bin path (%s) is too long", bin_path); + return NULL; + } + + app_rootpath = (char *)malloc(length + 1); + if(app_rootpath == NULL) + { + LOGE("malloc() failed, errno: %d (%s)", errno, strerror(errno)); + return NULL; + } + + memset(app_rootpath, '\0', length + 1); + strncpy(app_rootpath, bin_path, length); + + _SECURE_LOGI("input bin_path: %s", app_rootpath); + + delimiter = strrchr(app_rootpath, '/'); + *delimiter = '\0'; + + delimiter = strrchr(app_rootpath, '/'); + *delimiter = '\0'; + + return app_rootpath; +} + +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_native_paths(const char* app_rootpath) +{ + int i = 0; + const struct _path_info mount_info[] = + { + //{ "/bin", "./bin" }, + { "/csa", "./csa" }, + { "/dev", "./dev" }, + { "/dev/pts", "./dev/pts" }, + { "/dev/shm", "./dev/shm" }, + { "/etc", "./etc" }, + { "/lib", "./lib" }, + { "/mnt", "./mnt" }, + { "/proc", "./proc" }, + { "/smack", "./smack" }, + { "/sys", "./sys" }, + { "/sys/kernel/debug", "./sys/kernel/debug" }, + { "/tmp", "./tmp" }, + { "/usr", "./usr" }, + { "/usr/share/locale", "./usr/share/locale" }, + { "/var", "./var" }, + { "/var/run", "./var/run" }, + { "/opt", "./opt" }, + { "/opt/usr", "./opt/usr" }, + { "/opt/var/kdb/db", "./opt/var/kdb/db" }, + //{ "/opt/storage/sdcard","./opt/storage/sdcard" } + }; + + 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_info1[] = + { + { "\0", "./data/Share" }, + { "\0", "./data/Share2" } + }; + const struct _path_info mount_info2[] = + { + { "/opt/usr/share/.osp-compat/share", "./Share" }, + { "/opt/usr/share/.osp-compat/share2", "./Share2" }, + { "/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, MAX_PACKAGE_ID); + + 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, MAX_PACKAGE_ID); + + strncpy(mount_info1[0].src_path, osp_share_pkgid_path, PATH_MAX - 1); + strncpy(mount_info1[1].src_path, osp_share2_pkgid_path, PATH_MAX - 1); + + 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_info1)/sizeof(struct _path_info); ++i) + { + if (mount(mount_info1[i].src_path, mount_info1[i].dest_path, NULL, MS_BIND, NULL) != 0) + { + LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)", + mount_info1[i].src_path, mount_info1[i].dest_path, errno, strerror(errno)); + + int j = 0; + for (j = i; j > 0; --j) + { + umount2(mount_info1[j-1].dest_path, MNT_DETACH); + } + return -1; + } + } + for (i = 0; i < sizeof(mount_info2)/sizeof(struct _path_info); ++i) + { + if (mount(mount_info2[i].src_path, mount_info2[i].dest_path, NULL, MS_BIND, NULL) != 0) + { + LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)", + mount_info2[i].src_path, mount_info2[i].dest_path, errno, strerror(errno)); + + int j = 0; + for (j = i; j > 0; --j) + { + umount2(mount_info2[j-1].dest_path, MNT_DETACH); + } + return -1; + } + } + + return 0; +} + +static int +mount_linux_paths(const char* app_rootpath) +{ + int i = 0; + const struct _path_info mount_info[] = + { + { "/bin", "./bin" }, + { "/csa", "./csa" }, + { "/dev", "./dev" }, + { "/dev/pts", "./dev/pts" }, + { "/dev/shm", "./dev/shm" }, + { "/etc", "./etc" }, + { "/lib", "./lib" }, + { "/lib/modules", "./lib/modules" }, + { "/media", "./media" }, + { "/mnt", "./mnt" }, + { "/proc", "./proc" }, + { "/run", "./run" }, + { "/smack", "./smack" }, + { "/sys", "./sys" }, + { "/sys/fs/cgroup", "./sys/fs/cgroup" }, + { "/sys/fs/cgroup/systemd", "./sys/fs/cgroup/systemd" }, + { "/tmp", "./tmp" }, + { "/usr", "./usr" }, + { "/usr/share/locale", "./usr/share/locale" }, + { "/var", "./var" }, + { "/var/run", "./var/run" }, + { "/opt", "./opt" }, + { "/opt/usr", "./opt/usr" }, + //{ "/opt/var/run", "./opt/var/run" }, + { "/opt/storage/sdcard","./opt/storage/sdcard" }, + }; + + 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 (i == 23) // /opt/storage/sdcard + { + int mmc_mounted = 0; + int 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 == 0) + { + continue; + } + } + + LOGI("src path: %s, dest path: %s", mount_info[i].src_path, mount_info[i].dest_path); + 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 +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, }; + const struct _dir_info external_dirs1[] = + { + { "./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 }, + { "/opt/storage/sdcard/Images", 0777, 0 }, + { "/opt/storage/sdcard/Sounds", 0777, 0 }, + { "/opt/storage/sdcard/Videos", 0777, 0 }, + { "/opt/storage/sdcard/Others", 0777, 0 } + }; + struct _dir_info external_dirs2[] = + { + { "\0", 0777, 0}, + { "\0", 0777, 0}, + { "\0", 0777, 0}, + { "\0", 0777, 0}, + { "\0", 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, MAX_PACKAGE_ID); + + strncpy(osp_ext_apps_pkgid_share_path, osp_ext_apps_pkgid_path, PATH_MAX - 1); + strncat(osp_ext_apps_pkgid_share_path, "/Share", 6); + + strncpy(osp_ext_apps_pkgid_share2_path, osp_ext_apps_pkgid_path, PATH_MAX - 1); + 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, MAX_PACKAGE_ID); + + 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, MAX_PACKAGE_ID); + + strncpy(external_dirs2[0].path, osp_ext_apps_pkgid_path, PATH_MAX - 1); + strncpy(external_dirs2[1].path, osp_ext_apps_pkgid_share_path, PATH_MAX - 1); + strncpy(external_dirs2[2].path, osp_ext_apps_pkgid_share2_path, PATH_MAX - 1); + strncpy(external_dirs2[3].path, osp_ext_share_pkgid_path, PATH_MAX - 1); + strncpy(external_dirs2[4].path, osp_ext_share2_pkgid_path, PATH_MAX - 1); + + if (chdir(app_rootpath) != 0) + { + LOGE("chdir() failed (%s), path: %s", strerror(errno), app_rootpath); + return -1; + } + + for (i = 0; i < sizeof(external_dirs1)/sizeof(struct _dir_info); i++) + { + int ret = mkdir(external_dirs1[i].path, external_dirs1[i].mode); + if (ret == -1 && errno != 17) // EEXIST + { + LOGE("mkdir() failed, path: %s, errno: %d (%s)", external_dirs1[i].path, errno, strerror(errno)); + return -1; + } + } + for (i = 0; i < sizeof(external_dirs2)/sizeof(struct _dir_info); i++) + { + int ret = mkdir(external_dirs2[i].path, external_dirs2[i].mode); + if (ret == -1 && errno != 17) // EEXIST + { + LOGE("mkdir() failed, path: %s, errno: %d (%s)", external_dirs2[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_info1[] = + { + { "/opt/storage/sdcard", "./Storagecard/Media" }, + { "/opt/storage/sdcard/osp/share", "./ShareExt" }, + { "/opt/storage/sdcard/osp/share2", "./Share2Ext" } + }; + struct _path_info mount_info2[] = + { + { "\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, MAX_PACKAGE_ID); + + 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, MAX_PACKAGE_ID); + + 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, MAX_PACKAGE_ID); + + strncpy(mount_info2[0].src_path, osp_ext_apps_pkgid_path, PATH_MAX - 1); + strncpy(mount_info2[1].src_path, osp_ext_share_pkgid_path, PATH_MAX - 1); + strncpy(mount_info2[2].src_path, osp_ext_share2_pkgid_path, PATH_MAX - 1); + + 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_info1)/sizeof(struct _path_info); i++) + { + if (mount(mount_info1[i].src_path, mount_info1[i].dest_path, NULL, MS_BIND, NULL) != 0) + { + LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)", + mount_info1[i].src_path, mount_info1[i].dest_path, errno, strerror(errno)); + + int j = 0; + for (j = i; j > 0; --j) + { + umount2(mount_info1[j-1].dest_path, MNT_DETACH); + } + return -1; + } + } + for (i = 0; i < sizeof(mount_info2)/sizeof(struct _path_info); i++) + { + if (mount(mount_info2[i].src_path, mount_info2[i].dest_path, NULL, MS_BIND, NULL) != 0) + { + LOGE("mount() failed, src path: %s, dest path: %s, errno: %d (%s)", + mount_info2[i].src_path, mount_info2[i].dest_path, errno, strerror(errno)); + + int j = 0; + for (j = i; j > 0; --j) + { + umount2(mount_info2[j-1].dest_path, MNT_DETACH); + } + return -1; + } + } + + return 0; +} + +int +do_pre_exe(const char* app_rootpath, const char* package_id) +{ + int mmc_mounted = 0; + + // preload libosp-compat.so.1 for compatibility + void* handle = dlopen(OSP_COMPAT_LIB, RTLD_GLOBAL); + if (handle) + { + LOGI("%s is preloaded.", OSP_COMPAT_LIB); + } + + umask(0000); + + if (!internal_is_mounted(package_id)) + { + if (mount_native_paths(app_rootpath) != 0) + { + goto ERROR; + } + if (mount_osp_internal_paths(app_rootpath, package_id) != 0) + { + goto ERROR; + } + } + + int 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; + } + } + } + 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."); + + if (chdir("/data") != 0) + { + LOGE("chdir() failed, path: /data, errno: %d (%s)", errno, strerror(errno)); + goto ERROR; + } + + umask(0022); + + LOGI("[data_caging] do_pre_exe() succeeded."); + return 0; + +ERROR: + umask(0022); + + LOGI("[data_caging] do_pre_exe() failed."); + return -1; +} + +static int +do_virtual_root(const char* virtual_root_path, const char* package_id) +{ + _SECURE_LOGI("[virtual_root] do_virtual_root() was called, virtual root path: %s, package id: %s", + virtual_root_path, package_id); + + umask(0000); + + if (!internal_is_mounted(package_id)) + { + if (mount_linux_paths(virtual_root_path) != 0) + { + goto ERROR; + } + } + LOGI("mount() succeeded."); + + if (chroot(virtual_root_path) != 0) + { + LOGE("chroot() failed. path: %s, errno: %d (%s)", virtual_root_path, errno, strerror(errno)); + goto ERROR; + } + if (chdir("/") != 0) + { + LOGE("chdir() failed. path: /, errno: %d (%s)", errno, strerror(errno)); + goto ERROR; + } + LOGI("chroot() succeeded."); + + umask(0022); + + LOGI("[virtual_root] do_virtual_root() succeeded."); + return 0; + +ERROR: + umask(0022); + + LOGI("[virtual_root] do_virtual_root() failed."); + return -1; +} + +int +do_pre_exec(const char* app_id, const char* bin_path) +{ + char app_compat_path[PATH_MAX] = { 0, }; + const char app_compat_file[] = "/info/compat.info"; + char app_data_path[PATH_MAX] = { 0, }; + int osp_compat = 0; + + const char* app_rootpath = get_app_rootpath_from_path(bin_path); + + strncpy(app_compat_path, app_rootpath, PATH_MAX - 1); + strncat(app_compat_path, app_compat_file, strlen(app_compat_file)); + if (access(app_compat_path, F_OK) == 0) + { + osp_compat = 1; + } + + appinfo_init(app_id, 0); + appinfo_set_compat(osp_compat); + + const char* package_id = appinfo_get_packageid(); + + _SECURE_LOGI("do_pre_exec() is called, bin path: %s, app root: %s, app id: %s, pkg id: %s, osp-compatible: %d", + bin_path, app_rootpath, app_id, package_id, osp_compat); + + // FIXME: Temporary code with security risk + prctl(PR_SET_KEEPCAPS, 1); + + if (osp_compat == 1) + { + //unshare(CLONE_NEWNS); + int ret = do_pre_exe(app_rootpath, package_id); + free(app_rootpath); + return ret; + } + + char virtual_root_file[PATH_MAX] = { 0, }; + const char virtual_root_info[] = "/info/virtualroot.info"; + strncpy(virtual_root_file, app_rootpath, PATH_MAX - 1); + strncat(virtual_root_file, virtual_root_info, strlen(virtual_root_info)); + if (access(virtual_root_file, F_OK) == 0) + { + LOGI("This is virtual root application."); + int fd = open(virtual_root_file, O_RDONLY); + if (fd < 0) + { + LOGE("failed to open %s, errno: %d (%s)", virtual_root_file, errno, strerror(errno)); + goto ERROR; + } + + char user_path[PATH_MAX] = { 0, }; + int read_bytes = read(fd, user_path, PATH_MAX - 1); + if (read_bytes < 0) + { + LOGE("failed to read %s, errno: %d (%s)", virtual_root_file, errno, strerror(errno)); + close(fd); + goto ERROR; + } + close(fd); + + char virtual_root_path[PATH_MAX] = { 0, }; + sprintf(virtual_root_path, "%s/data/%s", app_rootpath, user_path); + + int res = do_virtual_root(virtual_root_path, package_id); + free(app_rootpath); + return res; + } + + // Set current working dir to "/opt/usr/apps/{pkgId}/data" + strncpy(app_data_path, app_rootpath, PATH_MAX - 1); + strncat(app_data_path, "/data", strlen("/data")); + + if (chdir(app_data_path) != 0) + { + LOGE("chdir() failed, path: %s, errno: %d (%s)", app_data_path, errno, strerror(errno)); + goto ERROR; + } + + LOGI("[data_caging] do_pre_exec() succeeded."); + free(app_rootpath); + return 0; + +ERROR: + free(app_rootpath); + return -1; +} + -- 2.7.4