From 7369e120bc65aebeb345bc118587bb8a32d5b08b Mon Sep 17 00:00:00 2001 From: Kibum Kim Date: Mon, 27 Feb 2012 21:16:42 +0900 Subject: [PATCH] tizen beta release --- AUTHORS | 4 + CMakeLists.txt | 102 ++ LICENSE | 204 ++++ client/include/package-manager.h | 384 ++++++ client/include/pkgmgr-api.h | 29 + client/include/pkgmgr-info.h | 58 + client/include/pkgmgr-internal.h | 72 ++ client/src/pkgmgr-info.c | 373 ++++++ client/src/pkgmgr-internal.c | 196 ++++ client/src/pkgmgr.c | 1220 +++++++++++++++++++ comm/CMakeLists.txt | 161 +++ comm/SLP_package_manager_frontend_backend_PG.h | 470 ++++++++ comm/build.sh | 30 + comm/comm_client.c | 216 ++++ comm/comm_client.h | 55 + comm/comm_client_dbus.c | 355 ++++++ comm/comm_config.h | 124 ++ comm/comm_pkg_mgr.xml | 16 + comm/comm_pkg_mgr_server.c | 203 ++++ comm/comm_pkg_mgr_server.h | 49 + comm/comm_socket.c | 215 ++++ comm/comm_socket.h | 35 + comm/comm_socket_client.c | 66 ++ comm/comm_socket_client.h | 30 + comm/comm_status_broadcast.xml | 13 + comm/comm_status_broadcast_server.c | 190 +++ comm/comm_status_broadcast_server.h | 42 + comm/comm_status_broadcast_server_dbus.c | 114 ++ comm/comm_status_broadcast_signal_marshaller.list | 2 + comm/error_report.h | 45 + comm/pkgmgr-installer-client.pc.in | 16 + .../pkgmgr-installer-status-broadcast-server.pc.in | 16 + comm/pkgmgr-installer.pc.in | 16 + comm/pkgmgr_installer.c | 277 +++++ comm/pkgmgr_installer.h | 362 ++++++ comm/pkgmgr_installer_config.h | 51 + comm/test/CMakeLists.txt | 33 + comm/test/test_comm_client.c | 61 + comm/test/test_comm_pkg_mgr_server.c | 68 ++ comm/test/test_comm_socket.c | 48 + comm/test/test_comm_status_broadcast_server.c | 50 + comm/test/test_pkgmgr_installer.c | 254 ++++ debian/changelog | 7 + debian/compat | 1 + debian/control | 48 + debian/docs | 0 debian/libpkgmgr-client-0.install.in | 6 + debian/libpkgmgr-client-0.postinst | 15 + debian/libpkgmgr-client-dev.install.in | 2 + debian/libpkgmgr-installer-dev.install.in | 4 + debian/libpkgmgr-installer.install.in | 3 + debian/libpkgmgr-types-dev.install.in | 3 + debian/pkgmgr-server.install.in | 3 + debian/pkgmgr-server.postinst | 13 + debian/rules | 129 +++ include/SLP_package_manager_PG.h | 276 +++++ include/package-manager-plugin.h | 1 + include/package-manager-types.h | 1 + include/package-manager.h | 1 + installers/CMakeLists.txt | 1 + installers/sample/CMakeLists.txt | 18 + installers/sample/sample_backend.c | 123 ++ installers/sample/sample_backendlib.c | 106 ++ org.tizen.slp.pkgmgr.service.in | 3 + packaging/pkgmgr.spec | 167 +++ pkg_path.conf.in | 6 + pkgmgr.pc.in | 16 + po/CMakeLists.txt | 24 + po/POTFILES.in | 2 + po/en_GB.po | 32 + po/en_US.po | 32 + po/ja_JP.po | 32 + po/ko_KR.po | 32 + po/package-manager.pot | 32 + po/update-po.sh | 60 + po/zh_CN.po | 32 + queue_status | 1 + server/include/pkgmgr-server.h | 64 + server/include/pm-queue.h | 50 + server/src/pkgmgr-server.c | 1222 ++++++++++++++++++++ server/src/pm-queue.c | 248 ++++ test.sh | 17 + tool/CMakeLists.txt | 33 + tool/mime.wac.xml | 12 + tool/org.tizen.pkgmgr-install.desktop.in | 9 + tool/pkg_cmd.c | 536 +++++++++ tool/pkgmgr-install.c | 98 ++ tool/stress_test.py | 36 + types/CMakeLists.txt | 9 + types/include/package-manager-plugin.h | 69 ++ types/include/package-manager-types.h | 120 ++ types/pkgmgr-types.pc.in | 16 + 92 files changed, 10096 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100755 client/include/package-manager.h create mode 100755 client/include/pkgmgr-api.h create mode 100755 client/include/pkgmgr-info.h create mode 100755 client/include/pkgmgr-internal.h create mode 100755 client/src/pkgmgr-info.c create mode 100755 client/src/pkgmgr-internal.c create mode 100755 client/src/pkgmgr.c create mode 100755 comm/CMakeLists.txt create mode 100755 comm/SLP_package_manager_frontend_backend_PG.h create mode 100755 comm/build.sh create mode 100755 comm/comm_client.c create mode 100755 comm/comm_client.h create mode 100755 comm/comm_client_dbus.c create mode 100755 comm/comm_config.h create mode 100644 comm/comm_pkg_mgr.xml create mode 100755 comm/comm_pkg_mgr_server.c create mode 100755 comm/comm_pkg_mgr_server.h create mode 100755 comm/comm_socket.c create mode 100755 comm/comm_socket.h create mode 100755 comm/comm_socket_client.c create mode 100755 comm/comm_socket_client.h create mode 100644 comm/comm_status_broadcast.xml create mode 100755 comm/comm_status_broadcast_server.c create mode 100755 comm/comm_status_broadcast_server.h create mode 100755 comm/comm_status_broadcast_server_dbus.c create mode 100644 comm/comm_status_broadcast_signal_marshaller.list create mode 100755 comm/error_report.h create mode 100644 comm/pkgmgr-installer-client.pc.in create mode 100644 comm/pkgmgr-installer-status-broadcast-server.pc.in create mode 100755 comm/pkgmgr-installer.pc.in create mode 100755 comm/pkgmgr_installer.c create mode 100755 comm/pkgmgr_installer.h create mode 100755 comm/pkgmgr_installer_config.h create mode 100755 comm/test/CMakeLists.txt create mode 100755 comm/test/test_comm_client.c create mode 100755 comm/test/test_comm_pkg_mgr_server.c create mode 100755 comm/test/test_comm_socket.c create mode 100755 comm/test/test_comm_status_broadcast_server.c create mode 100755 comm/test/test_pkgmgr_installer.c create mode 100755 debian/changelog create mode 100644 debian/compat create mode 100755 debian/control create mode 100644 debian/docs create mode 100755 debian/libpkgmgr-client-0.install.in create mode 100755 debian/libpkgmgr-client-0.postinst create mode 100644 debian/libpkgmgr-client-dev.install.in create mode 100755 debian/libpkgmgr-installer-dev.install.in create mode 100755 debian/libpkgmgr-installer.install.in create mode 100755 debian/libpkgmgr-types-dev.install.in create mode 100755 debian/pkgmgr-server.install.in create mode 100755 debian/pkgmgr-server.postinst create mode 100755 debian/rules create mode 100755 include/SLP_package_manager_PG.h create mode 120000 include/package-manager-plugin.h create mode 120000 include/package-manager-types.h create mode 120000 include/package-manager.h create mode 100755 installers/CMakeLists.txt create mode 100755 installers/sample/CMakeLists.txt create mode 100755 installers/sample/sample_backend.c create mode 100755 installers/sample/sample_backendlib.c create mode 100644 org.tizen.slp.pkgmgr.service.in create mode 100644 packaging/pkgmgr.spec create mode 100644 pkg_path.conf.in create mode 100644 pkgmgr.pc.in create mode 100644 po/CMakeLists.txt create mode 100644 po/POTFILES.in create mode 100644 po/en_GB.po create mode 100644 po/en_US.po create mode 100644 po/ja_JP.po create mode 100644 po/ko_KR.po create mode 100644 po/package-manager.pot create mode 100755 po/update-po.sh create mode 100644 po/zh_CN.po create mode 100644 queue_status create mode 100755 server/include/pkgmgr-server.h create mode 100755 server/include/pm-queue.h create mode 100755 server/src/pkgmgr-server.c create mode 100755 server/src/pm-queue.c create mode 100755 test.sh create mode 100755 tool/CMakeLists.txt create mode 100644 tool/mime.wac.xml create mode 100755 tool/org.tizen.pkgmgr-install.desktop.in create mode 100755 tool/pkg_cmd.c create mode 100755 tool/pkgmgr-install.c create mode 100755 tool/stress_test.py create mode 100755 types/CMakeLists.txt create mode 100755 types/include/package-manager-plugin.h create mode 100755 types/include/package-manager-types.h create mode 100755 types/pkgmgr-types.pc.in diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..d908bc1 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,4 @@ +Jayoun Lee +Sewook Park +Jaeho Lee +Shobhit Srivastava diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..853ea9a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,102 @@ +# +# Copyright (c) 2008 ~ 2010 Samsung Electronics Co., Ltd. +# All rights reserved +# + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + +PROJECT(package-manager C) + +SET(VERSION 0.1.68) +SET(VERSION_MAJOR 0) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") + + +set(CMAKE_SKIP_BUILD_RPATH true) + +#Verbose +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/comm) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED security-server dlog elementary evas ecore appcore-efl ecore-x ail ecore-file) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +pkg_check_modules(libpkgs REQUIRED dbus-glib-1 dlog aul ail) + +FOREACH(flag ${libpkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(pm_dir "${CMAKE_SOURCE_DIR}") +SET(pm_inc_dir "${pm_dir}/include") +SET(pm_c_src_dir "${pm_dir}/client/src") +SET(pm_c_inc_dir "${pm_dir}/client/include") +SET(pm_s_src_dir "${pm_dir}/server/src") +SET(pm_s_inc_dir "${pm_dir}/server/include") +SET(pm_t_inc_dir "${pm_dir}/types/include") + +## About debug +SET(debug_type "-DPM_CONSOLE_USE") # for debug - use console window + +## Additional flag +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -Wall") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +################## +## build comm libraries +add_subdirectory(comm) +add_subdirectory(tool) +add_subdirectory(types) + +################################################################################################### +## for libpkgmgr-client.so (library) +SET(PKGMGR_CLIENT "pkgmgr-client") +SET(libpkgmgr-client_SOURCES ${pm_c_src_dir}/pkgmgr-info.c ${pm_c_src_dir}/pkgmgr-internal.c ${pm_c_src_dir}/pkgmgr.c) +SET(libpkgmgr-client_LDFLAGS " -module -avoid-version ") +SET(libpkgmgr-client_CFLAGS " ${CFLAGS} -fPIC -I${pm_c_inc_dir} -I${pm_inc_dir} -I${pm_t_inc_dir} ${debug_type}") + +ADD_LIBRARY(${PKGMGR_CLIENT} SHARED ${libpkgmgr-client_SOURCES}) +SET_TARGET_PROPERTIES(${PKGMGR_CLIENT} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${PKGMGR_CLIENT} PROPERTIES VERSION ${VERSION}) +SET_TARGET_PROPERTIES(${PKGMGR_CLIENT} PROPERTIES COMPILE_FLAGS "${libpkgmgr-client_CFLAGS}") +TARGET_LINK_LIBRARIES(${PKGMGR_CLIENT} pkgmgr_installer_client pkgmgr_installer_status_broadcast_server ${libpkgs_LDFLAGS}) +################################################################################################### + +################################################################################################### +## for pkgmgr-server (binary) +SET(pkgmgr-server_SOURCES ${pm_s_src_dir}/pkgmgr-server.c ${pm_s_src_dir}/pm-queue.c) +SET(pkgmgr-server_CFLAGS " -I. -I${pm_inc_dir} -I${pm_s_inc_dir} -I${pm_dir}/comm ${debug_type} -D_GNU_SOURCE ") +SET(pkgmgr-server_LDFLAGS ${pkgs_LDFLAGS}) + +ADD_EXECUTABLE(pkgmgr-server ${pkgmgr-server_SOURCES}) +TARGET_LINK_LIBRARIES(pkgmgr-server pkgmgr_installer pkgmgr_installer_pkg_mgr_server) +TARGET_LINK_LIBRARIES(pkgmgr-server ${pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(pkgmgr-server PROPERTIES COMPILE_FLAGS "${pkgmgr-server_CFLAGS}") +#################################################################################################### + +CONFIGURE_FILE(pkgmgr.pc.in pkgmgr.pc @ONLY) +configure_file(org.tizen.slp.pkgmgr.service.in org.tizen.slp.pkgmgr.service @ONLY) +configure_file(pkg_path.conf.in pkg_path.conf @ONLY) + +#INSTALL(FILES ${CMAKE_BINARY_DIR}/libpkgmgr-client.so DESTINATION lib) +INSTALL(TARGETS ${PKGMGR_CLIENT} DESTINATION lib COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_BINARY_DIR}/pkgmgr-server DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr.pc DESTINATION lib/pkgconfig) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/client/include/package-manager.h DESTINATION include) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.tizen.slp.pkgmgr.service DESTINATION ${PREFIX}/share/dbus-1/services/) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkg_path.conf DESTINATION ${PREFIX}/etc/package-manager/) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/queue_status DESTINATION etc/package-manager/server/) + +#################################################################################################### +add_subdirectory(installers) +# i18n +add_subdirectory(po) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a06208b --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + 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/client/include/package-manager.h b/client/include/package-manager.h new file mode 100755 index 0000000..82899f2 --- /dev/null +++ b/client/include/package-manager.h @@ -0,0 +1,384 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + + + + + + + + + +/** + * @file package-manager.h + * @author Sewook Park + * @version 0.1 + * @brief This file declares API of slp-pkgmgr library + * + * @addtogroup APPLICATION_FRAMEWORK + * @{ + * + * @defgroup PackageManager + * @section Header to use them: + * @code + * #include "package-manager.h" + * @endcode + * + * @addtogroup PackageManager + * @{ + */ + +#ifndef __PKG_MANAGER_H__ +#define __PKG_MANAGER_H__ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef DEPRECATED +#define DEPRECATED __attribute__ ((__deprecated__)) +#endif + +/** + * @mainpage + * + * This is package manager + * + * Packaeg manager is used to install/uninstall the packages.\n + * package includes dpkg, java, widget, etc. and it can be added\n + * Security is considered on current package manager\n + * + */ + +/** + * @file package-manager.h + * @brief Package Manager header + * + * Generated by Sewook Park + */ + + + +/** + * @addtogroup PackageManager + * @{ + */ + +/** + * @brief pkgmgr info types. + */ +#define PKGMGR_INFO_STR_PKGTYPE "pkg_type" +#define PKGMGR_INFO_STR_PKGNAME "pkg_name" +#define PKGMGR_INFO_STR_VERSION "version" +#define PKGMGR_INFO_STR_INSTALLED_SIZE "installed_size" +#define PKGMGR_INFO_STR_DATA_SIZE "data_size" +#define PKGMGR_INFO_STR_APP_SIZE "app_size" +#define PKGMGR_INFO_STR_INSTALLED_TIME "installed_time" +/** @} */ + + +/** + * @brief Return values in pkgmgr. + */ +typedef enum _pkgmgr_return_val { + PKGMGR_R_ETIMEOUT = -4, /**< Timeout */ + PKGMGR_R_EINVAL = -3, /**< Invalid argument */ + PKGMGR_R_ECOMM = -2, /**< Comunication Error */ + PKGMGR_R_ERROR = -1, /**< General error */ + PKGMGR_R_OK = 0 /**< General success */ +} pkgmgr_return_val; +/** @} */ + +/** + * @defgroup pkg_operate APIs to install /uninstall / activate application + * @ingroup pkgmgr + * @brief + * APIs to install /uninstall / activate application + * - Install application using application package filepath + * - Uninstall application using application package name + * - Activate application using application package name + * + */ + + +/** + * @addtogroup pkg_operate + * @{ + */ +typedef int (*pkgmgr_iter_fn)(const char* pkg_type, const char* pkg_name, + const char* version, void *data); + +typedef int (*pkgmgr_handler)(int req_id, const char *pkg_type, + const char *pkg_name, const char *key, + const char *val, const void *pmsg, void *data); + + +typedef void pkgmgr_client; + +typedef enum { + PC_REQUEST = 0, + PC_LISTENING, + PC_BROADCAST, +}client_type; + +typedef enum { + PM_DEFAULT, + PM_QUIET +}pkgmgr_mode; + +/** + * @brief This API creates pkgmgr client. + * + * This API is for package-manager client application.\n + * + * @param[in] ctype client type - PC_REQUEST, PC_LISTENING, PC_BROADCAST + * @return pkgmgr_client object + * @retval NULL on failure creating an object +*/ +pkgmgr_client *pkgmgr_client_new(client_type ctype); + +/** + * @brief This API deletes pkgmgr client. + * + * This API is for package-manager client application.\n + * + * @param[in] pc pkgmgr_client + * @return Operation result; + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_ERROR internal error +*/ +int pkgmgr_client_free(pkgmgr_client *pc); + +/** + * @brief This API installs package. + * + * This API is for package-manager client application.\n + * + * @param[in] pc pkgmgr_client + * @param[in] pkg_type package type + * @param[in] descriptor_path full path that descriptor is located + * @param[in] pkg_path full path that package file is located + * @param[in] optional_file optional file which is used for installation + * @param[in] mode installation mode - PM_DEFAULT, PM_QUIET + * @param[in] event_cb user callback + * @param[in] data user data + * @return request_id (>0) if success, error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_ECOMM communication error +*/ +int pkgmgr_client_install(pkgmgr_client *pc, const char *pkg_type, + const char *descriptor_path, const char *pkg_path, + const char *optional_file, pkgmgr_mode mode, + pkgmgr_handler event_cb, void *data); + +/** + * @brief This API uninstalls package. + * + * This API is for package-manager client application.\n + * + * @param[in] pc pkgmgr_client + * @param[in] pkg_type package type + * @param[in] pkg_name package name + * @param[in] mode installation mode - PM_DEFAULT, PM_QUIET + * @param[in] event_cb user callback + * @param[in] data user data + * @return request_id (>0), error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_ECOMM communication error +*/ +int pkgmgr_client_uninstall(pkgmgr_client *pc, const char *pkg_type, + const char *pkg_name, pkgmgr_mode mode, + pkgmgr_handler event_cb, void *data); + +/** + * @brief This API activates package. + * + * This API is for package-manager client application.\n + * + * @param[in] pc pkgmgr_client + * @param[in] pkg_type package type + * @param[in] pkg_name package name + * @return request_id (>0) if success, error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_ECOMM communication error +*/ +int pkgmgr_client_activate(pkgmgr_client *pc, const char *pkg_type, + const char *pkg_name); + +/** + * @brief This API deactivates package. + * + * This API is for package-manager client application.\n + * + * @param[in] pc pkgmgr_client + * @param[in] pkg_type package type + * @param[in] pkg_name package name + * @return request_id (>0) if success, error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_ECOMM communication error +*/ +int pkgmgr_client_deactivate(pkgmgr_client *pc, const char *pkg_type, + const char *pkg_name); + +/** + * @brief This API deletes application's private data. + * + * This API is for package-manager client application.\n + * + * @param[in] pc pkgmgr_client + * @param[in] pkg_type package type + * @param[in] pkg_name package name + * @param[in] mode installation mode - PM_DEFAULT, PM_QUIET + * @return request_id (>0) if success, error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_ECOMM communication error +*/ +int pkgmgr_client_clear_user_data(pkgmgr_client *pc, const char *pkg_type, + const char *pkg_name, pkgmgr_mode mode); + +/** + * @brief This API request to listen the pkgmgr's broadcasting + * + * This API is for package-manager client application.\n + * + * @param[in] pc pkgmgr_client + * @param[in] event_cb user callback + * @param[in] data user data + * @return request_id (>0) if success, error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument +*/ +int pkgmgr_client_listen_status(pkgmgr_client *pc, pkgmgr_handler event_cb, + void *data); + +/** + * @brief This API broadcasts pkgmgr's status + * + * This API is for package-manager client application.\n + * + * @param[in] pc pkgmgr_client + * @param[in] pkg_type package type + * @param[in] pkg_name package name + * @param[in] key key to broadcast + * @param[in] val value to broadcast + * @return 0 if success, error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument +*/ +int pkgmgr_client_broadcast_status(pkgmgr_client *pc, const char *pkg_type, + const char *pkg_name, const char *key, + const char *val); + +/** + * @brief This API provides package list + * + * This API is for package-manager client application.\n + * + * @param[in] iter_fn iteration function for list + * @param[in] data user data + * @return 0 if success, error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_ERROR internal error +*/ +int pkgmgr_get_pkg_list(pkgmgr_iter_fn iter_fn, void *data); +/** @} */ + +/** + * @defgroup pkg_list APIs to get package information + * @ingroup pkgmgr + * @brief + * API to get package information +*/ + +/** + * @addtogroup pkg_list + * @{ + */ + +typedef void pkgmgr_info; + +/** + * @brief This API gets the package's information. + * + * This API is for package-manager client application.\n + * + * @param[in] pkg_type package type for the package to get infomation + * @param[in] pkg_name package name for the package to get infomation + * @return package entry pointer if success, NULL if fail\n +*/ +pkgmgr_info * pkgmgr_info_new(const char *pkg_type, const char *pkg_name); + +/** + * @brief This API gets the package's information. + * + * This API is for package-manager client application.\n + * + * @param[in] pkg_type package type for the package to get infomation + * @param[in] pkg_path package file path to get infomation + * @return package entry pointer if success, NULL if fail\n +*/ +pkgmgr_info * pkgmgr_info_new_from_file(const char *pkg_type, + const char *pkg_path); + +/** + * @brief This API get package information value + * + * This API is for package-manager client application.\n + * + * @param[in] pkg_info pointer for package info entry + * @param[in] key key for package info field + * @return string value if success, NULL if fail\n +*/ +char * pkgmgr_info_get_string(pkgmgr_info * pkg_info, const char *key); + +/** + * @brief This API get package information value + * + * This API is for package-manager client application.\n + * + * @param[in] pkg_info pointer for package info entry + * @return 0 if success, error code(<0) if fail\n +*/ +int pkgmgr_info_free(pkgmgr_info * pkg_info); +/** @} */ + + + +#ifdef __cplusplus +} +#endif +#endif /* __PKG_MANAGER_H__ */ +/** + * @} + * @} + */ + diff --git a/client/include/pkgmgr-api.h b/client/include/pkgmgr-api.h new file mode 100755 index 0000000..adacf2a --- /dev/null +++ b/client/include/pkgmgr-api.h @@ -0,0 +1,29 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 API +#define API __attribute__ ((visibility("default"))) +#endif diff --git a/client/include/pkgmgr-info.h b/client/include/pkgmgr-info.h new file mode 100755 index 0000000..6760fa0 --- /dev/null +++ b/client/include/pkgmgr-info.h @@ -0,0 +1,58 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __PKG_MANAGER_INFO_H__ +#define __PKG_MANAGER_INFO_H__ + +//#include "package-manager.h" +#include "package-manager-plugin.h" + +typedef package_manager_pkg_info_t package_manager_app_info_t; + + +char *_get_pkg_type_from_desktop_file(const char *pkg_name); + +package_manager_pkg_info_t *_pkg_malloc_appinfo(int num); + +pkg_plugin_set *_pkg_plugin_load_library(const char *pkg_type, + const char *library_path); + +int _pkg_plugin_get_library_path(const char *pkg_type, char *library_path); + +pkg_plugin_set *_package_manager_load_library(const char *pkg_type); + +char *_get_info_string(const char *key, + const package_manager_pkg_detail_info_t * + pkg_detail_info); + +int _get_info_int(const char *key, + const package_manager_pkg_detail_info_t *pkg_detail_info); + +time_t _get_info_time(const char *key, + const package_manager_pkg_detail_info_t * + pkg_detail_info); + +#endif /* __PKG_MANAGER_INFO_H__ */ diff --git a/client/include/pkgmgr-internal.h b/client/include/pkgmgr-internal.h new file mode 100755 index 0000000..5779015 --- /dev/null +++ b/client/include/pkgmgr-internal.h @@ -0,0 +1,72 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __PKG_MANAGER_INTERNAL_H__ +#define __PKG_MANAGER_INTERNAL_H__ + +#include +#include +#include + +#undef LOG_TAG +#ifndef LOG_TAG +#define LOG_TAG "PKGMGR" +#endif /* LOG_TAG */ + +#define PKG_FRONTEND "frontend:" +#define PKG_BACKEND "backend:" +#define PKG_BACKENDLIB "backendlib:" +#define PKG_CONF_PATH "/usr/etc/package-manager/pkg_path.conf" + +#define PKG_STATUS "STATUS" + +#define PKG_STRING_LEN_MAX 1024 +#define PKG_EXT_LEN_MAX 20 +#define PKG_ARGC_MAX 16 + +#define _LOGE(fmt, arg...) LOGE("[%s,%d] "fmt, __FUNCTION__, __LINE__, ##arg) +#define _LOGD(fmt, arg...) LOGD("[%s,%d] "fmt, __FUNCTION__, __LINE__, ##arg) + +#define retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + _LOGE(fmt, ##arg); \ + _LOGE("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ +} while (0) + +#define retv_if(expr, val) do { \ + if (expr) { \ + _LOGE("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ +} while (0) + +void _app_str_trim(char *input); +char *_get_backend_path(const char *input_path); +char *_get_backend_path_with_type(const char *type); + +#endif /* __PKG_MANAGER_INTERNAL_H__ */ diff --git a/client/src/pkgmgr-info.c b/client/src/pkgmgr-info.c new file mode 100755 index 0000000..83532bc --- /dev/null +++ b/client/src/pkgmgr-info.c @@ -0,0 +1,373 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 +#include +#include + +#include "package-manager.h" +#include "pkgmgr-internal.h" +#include "pkgmgr-info.h" + +char *_get_pkg_type_from_desktop_file(const char *pkg_name) +{ + static char pkg_type[PKG_EXT_LEN_MAX]; + + ail_appinfo_h handle; + ail_error_e ret; + char *str; + + ret = ail_package_get_appinfo(pkg_name, &handle); + if (ret != AIL_ERROR_OK) { + return NULL; + } + + ret = ail_appinfo_get_str(handle, AIL_PROP_X_SLP_PACKAGETYPE_STR, &str); + if (ret != AIL_ERROR_OK) { + ail_package_destroy_appinfo(handle); + return NULL; + } + snprintf(pkg_type, sizeof(pkg_type) - 1, str); + + ret = ail_package_destroy_appinfo(handle); + if (ret != AIL_ERROR_OK) { + return NULL; + } + + return pkg_type; +} + +package_manager_pkg_info_t *_pkg_malloc_appinfo(int num) +{ + package_manager_app_info_t *app_info = NULL; + package_manager_app_info_t *first = NULL; + package_manager_app_info_t *last = NULL; + int i = 0; + + for (i = 0; i < num; i++) { + app_info = (package_manager_app_info_t *) + malloc(sizeof(package_manager_app_info_t)); + if (app_info == NULL) { + package_manager_app_info_t *temp_info; + package_manager_app_info_t *next; + + for (temp_info = first; temp_info != NULL; + temp_info = next) { + next = temp_info->next; + free(temp_info); + temp_info = NULL; + } + + return NULL; + } + + memset(app_info, 0x00, sizeof(package_manager_app_info_t)); + + if (first == NULL) + first = app_info; + + if (last == NULL) + last = app_info; + else { + last->next = app_info; + last = app_info; + } + } + + return first; + +} + +static pkg_plugin_set *plugin_set_list[24] = { 0, }; + +pkg_plugin_set *_pkg_plugin_load_library(const char *pkg_type, + const char *library_path) +{ + void *library_handle = NULL; + int i = 0; + + /* _pkg_plugin_on_load onload = NULL; */ + bool(*on_load) (pkg_plugin_set *plugin); + + if (library_path == NULL) { + _LOGE("pkg library path = [%s] \n", library_path); + return NULL; + } + + if ((library_handle = dlopen(library_path, RTLD_LAZY)) == NULL) { + _LOGE("dlopen is failed library_path[%s]\n", library_path); + return NULL; + } + + if ((on_load = dlsym(library_handle, "pkg_plugin_on_load")) == NULL || + dlerror() != NULL) { + _LOGE("can not find symbol \n"); + dlclose(library_handle); + return NULL; + } + + for (i = 0; plugin_set_list[i]; i++) { + if (strcmp(plugin_set_list[i]->pkg_type, pkg_type) == 0) { + _LOGD("already loaded [%s] is done well \n", + library_path); + goto END; + } + } + + plugin_set_list[i] = (pkg_plugin_set *) malloc(sizeof(pkg_plugin_set)); + if (plugin_set_list[i] == NULL) { + _LOGE("malloc of the plugin_set_list element is failed \n"); + dlclose(library_handle); + return NULL; + } + + memset(plugin_set_list[i], 0x0, sizeof(pkg_plugin_set)); + + if (on_load(plugin_set_list[i]) != 0) { + _LOGE("on_load is failed \n"); + + dlclose(library_handle); + + free(plugin_set_list[i]); + plugin_set_list[i] = NULL; + + return NULL; + } + + plugin_set_list[i]->plugin_handle = library_handle; + strncpy(plugin_set_list[i]->pkg_type, pkg_type, + PKG_TYPE_STRING_LEN_MAX - 1); + + _LOGD("load library [%s] is done well \n", library_path); + + END: + return plugin_set_list[i]; + +} + +int _pkg_plugin_get_library_path(const char *pkg_type, char *library_path) +{ + FILE *fp = NULL; + char buffer[1024] = { 0 }; + + if (pkg_type == NULL || library_path == NULL) { + _LOGE("invalid argument\n"); + return -1; + } + + fp = fopen(PKG_CONF_PATH, "r"); + if (fp == NULL) { + _LOGE("no matching backendlib\n"); + return PKGMGR_R_ERROR; + } + + char *path = NULL; + while (fgets(buffer, 1024, fp) != NULL) { + if (buffer[0] == '#') + continue; + + _app_str_trim(buffer); + + if ((path = strstr(buffer, PKG_BACKENDLIB)) != NULL) { + _LOGD("[%s]\n", buffer); + _LOGD("[%s]\n", path); + path = path + strlen(PKG_BACKENDLIB); + _LOGD("[%s]\n", path); + + break; + } + + memset(buffer, 0x00, 1024); + } + + if (fp != NULL) + fclose(fp); + + if (path == NULL) { + _LOGE("no matching backendlib\n"); + return PKGMGR_R_ERROR; + } + + snprintf(library_path, 1024, "%slib%s.so", path, pkg_type); + + return PKGMGR_R_OK; + +} + +pkg_plugin_set *_package_manager_load_library(const char *pkg_type) +{ + char package_path[1024] = { 0 }; + pkg_plugin_set *plugin_set = NULL; + + if (pkg_type == NULL) { + _LOGE("can not load library - pkg_type is null\n"); + return NULL; + } + + if (_pkg_plugin_get_library_path(pkg_type, package_path) == + PKGMGR_R_OK) { + plugin_set = _pkg_plugin_load_library(pkg_type, package_path); + if (plugin_set == NULL) { + _LOGE("can not load library \n"); + return NULL; + } + } else { + _LOGE("can not find path \n"); + return NULL; + } + + return plugin_set; +} + +typedef struct _detail_info_map_t { + char *name; + void *field; + char *type; +} detail_info_map_t; + +/* + typedef struct _package_manager_pkg_detail_info_t { + char pkg_type[PKG_TYPE_STRING_LEN_MAX]; + char pkg_name[PKG_NAME_STRING_LEN_MAX]; + char version[PKG_VERSION_STRING_LEN_MAX]; + char pkg_description[PKG_VALUE_STRING_LEN_MAX]; + char min_platform_version[PKG_VERSION_STRING_LEN_MAX]; + time_t installed_time; + int installed_size; + int app_size; + int data_size; + char optional_id[PKG_NAME_STRING_LEN_MAX]; + void *pkg_optional_info; + } package_manager_pkg_detail_info_t; +*/ + +static package_manager_pkg_detail_info_t tmp_pkg_detail_info; + +static detail_info_map_t info_map[] = { + {"pkg_type", tmp_pkg_detail_info.pkg_type, "string"}, + {"pkg_name", tmp_pkg_detail_info.pkg_name, "string"}, + {"version", tmp_pkg_detail_info.version, "string"}, + {"pkg_description", tmp_pkg_detail_info.pkg_description, "string"}, + {"min_platform_version", tmp_pkg_detail_info.min_platform_version, + "string"}, + {"installed_time", &tmp_pkg_detail_info.installed_time, "time_t"}, + {"installed_size", &tmp_pkg_detail_info.installed_size, "int"}, + {"app_size", &tmp_pkg_detail_info.app_size, "int"}, + {"data_size", &tmp_pkg_detail_info.data_size, "int"}, + {"optional_id", tmp_pkg_detail_info.optional_id, "string"} +}; + +char *_get_info_string(const char *key, + const package_manager_pkg_detail_info_t * + pkg_detail_info) +{ + detail_info_map_t *tmp; + int i = 0; + + if (pkg_detail_info == NULL) + return NULL; + + memcpy(&tmp_pkg_detail_info, pkg_detail_info, + sizeof(package_manager_pkg_detail_info_t)); + + for (i = 0; i < sizeof(info_map) / sizeof(detail_info_map_t); i++) { + tmp = &info_map[i]; + if (strcmp(key, tmp->name) == 0) { + if (strcmp(tmp->type, "string") == 0) { + return strdup((char *)(tmp->field)); + } else if (strcmp(tmp->type, "bool") == 0) { + char temp[PKG_VALUE_STRING_LEN_MAX]; + snprintf(temp, PKG_VALUE_STRING_LEN_MAX - 1, + "%d", (int)*(bool *) (tmp->field)); + return strdup(temp); + } else if (strcmp(tmp->type, "int") == 0) { + char temp[PKG_VALUE_STRING_LEN_MAX]; + snprintf(temp, PKG_VALUE_STRING_LEN_MAX - 1, + "%d", (int)*(int *)(tmp->field)); + return strdup(temp); + } else if (strcmp(tmp->type, "time_t") == 0) { + char temp[PKG_VALUE_STRING_LEN_MAX]; + snprintf(temp, PKG_VALUE_STRING_LEN_MAX - 1, + "%d", (int)*(time_t *) (tmp->field)); + return strdup(temp); + } else + return NULL; + } + } + return NULL; +} + +int _get_info_int(const char *key, + const package_manager_pkg_detail_info_t *pkg_detail_info) +{ + detail_info_map_t *tmp; + int i = 0; + + if (pkg_detail_info == NULL) + return -1; + + memcpy(&tmp_pkg_detail_info, pkg_detail_info, + sizeof(package_manager_pkg_detail_info_t)); + for (i = 0; i < sizeof(info_map) / sizeof(detail_info_map_t); i++) { + tmp = &info_map[i]; + if (strcmp(key, tmp->name) == 0) { + if (strcmp(tmp->type, "int") == 0) { + return (int)*(int *)(tmp->field); + } else + return -1; + } + } + return -1; +} + +time_t _get_info_time(const char *key, + const package_manager_pkg_detail_info_t *pkg_detail_info) +{ + detail_info_map_t *tmp; + int i = 0; + + if (pkg_detail_info == NULL) + return -1; + + memcpy(&tmp_pkg_detail_info, pkg_detail_info, + sizeof(package_manager_pkg_detail_info_t)); + for (i = 0; i < sizeof(info_map) / sizeof(detail_info_map_t); i++) { + tmp = &info_map[i]; + if (strcmp(key, tmp->name) == 0) { + if (strcmp(tmp->type, "time_t") == 0) { + return (time_t) *(time_t *) (tmp->field); + } else + return (time_t) -1; + } + } + return (time_t) -1; +} + diff --git a/client/src/pkgmgr-internal.c b/client/src/pkgmgr-internal.c new file mode 100755 index 0000000..8c67e4b --- /dev/null +++ b/client/src/pkgmgr-internal.c @@ -0,0 +1,196 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "pkgmgr-internal.h" + +#define IS_WHITESPACE(CHAR) \ + ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? \ + true : false) + +void _app_str_trim(char *input) +{ + char *trim_str = input; + + if (input == NULL) + return; + + while (*input != 0) { + if (!IS_WHITESPACE(*input)) { + *trim_str = *input; + trim_str++; + } + input++; + } + + *trim_str = 0; + return; +} + +char *_get_backend_path(const char *input_path) +{ + FILE *fp = NULL; + char buffer[1024] = { '\0', }; + char *type = NULL; + char installer_path[PKG_STRING_LEN_MAX] = { '\0', }; + char pkg_path[PKG_STRING_LEN_MAX] = { '\0', }; + char backend_path[PKG_STRING_LEN_MAX] = { '\0', }; + + if (strrchr(input_path, '/')) { + strncpy(pkg_path, strrchr(input_path, '/') + 1, + PKG_STRING_LEN_MAX - 1); + } else { + strncpy(pkg_path, input_path, PKG_STRING_LEN_MAX - 1); + } + + _LOGD("pkg_path[%s]\n", pkg_path); + + fp = fopen(PKG_CONF_PATH, "r"); + if (fp == NULL) { + return NULL; + } + + char *path = NULL; + while (fgets(buffer, 1024, fp) != NULL) { + if (buffer[0] == '#') + continue; + + _app_str_trim(buffer); + + if ((path = strstr(buffer, PKG_BACKEND)) != NULL) { + _LOGD("[%s]\n", buffer); + _LOGD("[%s]\n", path); + path = path + strlen(PKG_BACKEND); + _LOGD("[%s]\n", path); + + break; + } + + memset(buffer, 0x00, 1024); + } + + if (fp != NULL) + fclose(fp); + + if (path == NULL) + return NULL; + +/* if(path[strlen(path)] == '/') */ + snprintf(backend_path, PKG_STRING_LEN_MAX - 1, "%s", path); +/* else + sprintf(backend_path, "%s/", path); */ + + type = strrchr(pkg_path, '.'); + if (type == NULL) + type = pkg_path; + else + type++; + + snprintf(installer_path, PKG_STRING_LEN_MAX - 1, + "%s%s", backend_path, type); + + _LOGD("installer_path[%s]\n", installer_path); + + if (access(installer_path, F_OK) != 0) + return NULL; + + return strdup(installer_path); +} + +char *_get_backend_path_with_type(const char *type) +{ + FILE *fp = NULL; + char buffer[1024] = { '\0', }; + char installer_path[PKG_STRING_LEN_MAX] = { '\0', }; + char backend_path[PKG_STRING_LEN_MAX] = { '\0', }; + + _LOGD("type[%s]\n", type); + + fp = fopen(PKG_CONF_PATH, "r"); + if (fp == NULL) { + return NULL; + } + + char *path = NULL; + while (fgets(buffer, 1024, fp) != NULL) { + if (buffer[0] == '#') + continue; + + _app_str_trim(buffer); + + if ((path = strstr(buffer, PKG_BACKEND)) != NULL) { + _LOGD("[%s]\n", buffer); + _LOGD("[%s]\n", path); + path = path + strlen(PKG_BACKEND); + _LOGD("[%s]\n", path); + + break; + } + + memset(buffer, 0x00, 1024); + } + + if (fp != NULL) + fclose(fp); + + if(path == NULL) + return NULL; + +/* if(path[strlen(path)] == '/') */ + snprintf(backend_path, PKG_STRING_LEN_MAX - 1, "%s", path); +/* else + sprintf(backend_path, "%s/", path); */ + + snprintf(installer_path, PKG_STRING_LEN_MAX - 1, + "%s%s", backend_path, type); + _LOGD("installer_path[%s]\n", installer_path); + + if (access(installer_path, F_OK) != 0) { + char extlist[256] = { '\0', }; + aul_get_mime_extension(type, extlist, sizeof(extlist)); + _LOGD("extlist[%s]\n", extlist); + + if (strlen(extlist) == 0) + return NULL; + + if (strchr(extlist, ',')) { + extlist[strlen(extlist) - + strlen(strchr(extlist, ','))] = '\0'; + } + type = strchr(extlist, '.') + 1; + + snprintf(installer_path, PKG_STRING_LEN_MAX - 1, + "%s%s", backend_path, type); + } + + return strdup(installer_path); +} + diff --git a/client/src/pkgmgr.c b/client/src/pkgmgr.c new file mode 100755 index 0000000..17337a0 --- /dev/null +++ b/client/src/pkgmgr.c @@ -0,0 +1,1220 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 +#include +#include +#include +#include +#include + +#include "package-manager.h" +#include "pkgmgr-internal.h" +#include "pkgmgr-info.h" +#include "pkgmgr-api.h" +#include "comm_client.h" +#include "comm_status_broadcast_server.h" + +static int _get_request_id() +{ + static int internal_req_id = 1; + + return internal_req_id++; +} + +typedef struct _req_cb_info { + int request_id; + char *req_key; + pkgmgr_handler event_cb; + void *data; + struct _req_cb_info *next; +} req_cb_info; + +typedef struct _listen_cb_info { + int request_id; + pkgmgr_handler event_cb; + void *data; + struct _listen_cb_info *next; +} listen_cb_info; + +typedef struct _pkgmgr_client_t { + client_type ctype; + union { + struct _request { + comm_client *cc; + req_cb_info *rhead; + } request; + struct _listening { + comm_client *cc; + listen_cb_info *lhead; + } listening; + struct _broadcast { + DBusConnection *bc; + } broadcast; + } info; +} pkgmgr_client_t; + +typedef struct _iter_data { + pkgmgr_iter_fn iter_fn; + void *data; +} iter_data; + +static void __add_op_cbinfo(pkgmgr_client_t * pc, int request_id, + const char *req_key, pkgmgr_handler event_cb, + void *data) +{ + req_cb_info *cb_info; + req_cb_info *current; + req_cb_info *prev; + + cb_info = (req_cb_info *) calloc(1, sizeof(req_cb_info)); + if (cb_info == NULL) { + _LOGD("calloc failed"); + return; + } + cb_info->request_id = request_id; + cb_info->req_key = strdup(req_key); + cb_info->event_cb = event_cb; + cb_info->data = data; + cb_info->next = NULL; + + if (pc->info.request.rhead == NULL) + pc->info.request.rhead = cb_info; + else { + current = prev = pc->info.request.rhead; + while (current) { + prev = current; + current = current->next; + } + + prev->next = cb_info; + } +} + +static req_cb_info *__find_op_cbinfo(pkgmgr_client_t *pc, const char *req_key) +{ + req_cb_info *tmp; + + tmp = pc->info.request.rhead; + + if (tmp == NULL) { + _LOGE("tmp is NULL"); + return NULL; + } + + _LOGD("tmp->req_key %s, req_key %s", tmp->req_key, req_key); + + while (tmp) { + if (strncmp(tmp->req_key, req_key, strlen(tmp->req_key)) == 0) + return tmp; + tmp = tmp->next; + } + return NULL; +} + +static void __remove_op_cbinfo(pkgmgr_client_t *pc, req_cb_info *info) +{ + req_cb_info *tmp; + + if (pc == NULL || pc->info.request.rhead == NULL || info == NULL) + return; + + tmp = pc->info.request.rhead; + while (tmp) { + if (tmp->next == info) { + tmp->next = info->next; + free(info); + return; + } + tmp = tmp->next; + } +} + + +static void __add_stat_cbinfo(pkgmgr_client_t *pc, int request_id, + pkgmgr_handler event_cb, void *data) +{ + listen_cb_info *cb_info; + listen_cb_info *current; + listen_cb_info *prev; + + cb_info = (listen_cb_info *) calloc(1, sizeof(listen_cb_info)); + if (cb_info == NULL) { + _LOGD("calloc failed"); + return; + } + cb_info->request_id = request_id; + cb_info->event_cb = event_cb; + cb_info->data = data; + cb_info->next = NULL; + + /* TODO - check the order of callback - FIFO or LIFO => Should be changed to LIFO */ + if (pc->info.listening.lhead == NULL) + pc->info.listening.lhead = cb_info; + else { + current = prev = pc->info.listening.lhead; + while (current) { + prev = current; + current = current->next; + } + + prev->next = cb_info; + } +} + +static listen_cb_info *__find_stat_cbinfo(pkgmgr_client_t *pc, int request_id) +{ + listen_cb_info *tmp; + + tmp = pc->info.listening.lhead; + + _LOGD("tmp->request_id %d, request_id %d", tmp->request_id, request_id); + + while (tmp) { + if (tmp->request_id == request_id) + return tmp; + tmp = tmp->next; + } + return NULL; +} + +static void __remove_stat_cbinfo(pkgmgr_client_t *pc, listen_cb_info *info) +{ + listen_cb_info *tmp; + + if (pc == NULL || pc->info.listening.lhead == NULL || info == NULL) + return; + + tmp = pc->info.listening.lhead; + while (tmp) { + if (tmp->next == info) { + tmp->next = info->next; + free(info); + return; + } + tmp = tmp->next; + } +} + +static void __operation_callback(void *cb_data, const char *req_id, + const char *pkg_type, const char *pkg_name, + const char *key, const char *val) +{ + pkgmgr_client_t *pc; + req_cb_info *cb_info; + + _LOGD("__operation_callback() req_id[%s] pkg_type[%s] pkg_name[%s]" + "key[%s] val[%s]\n", req_id, pkg_type, pkg_name, key, val); + + pc = (pkgmgr_client_t *) cb_data; + + /* find callback info */ + cb_info = __find_op_cbinfo(pc, req_id); + if (cb_info == NULL) + return; + + _LOGD("__find_op_cbinfo"); + + /* call callback */ + if (cb_info->event_cb) { + cb_info->event_cb(cb_info->request_id, pkg_type, pkg_name, key, + val, NULL, cb_info->data); + _LOGD("event_cb is called"); + } + + /*remove callback for last call + if (strcmp(key, "end") == 0) { + __remove_op_cbinfo(pc, cb_info); + _LOGD("__remove_op_cbinfo"); + } + */ + + return; +} + +static void __status_callback(void *cb_data, const char *req_id, + const char *pkg_type, const char *pkg_name, + const char *key, const char *val) +{ + pkgmgr_client_t *pc; + listen_cb_info *tmp; + + _LOGD("__status_callback() req_id[%s] pkg_type[%s] pkg_name[%s]" + "key[%s] val[%s]\n", req_id, pkg_type, pkg_name, key, val); + + pc = (pkgmgr_client_t *) cb_data; + + tmp = pc->info.listening.lhead; + while (tmp) { + if (tmp->event_cb(tmp->request_id, pkg_type, pkg_name, key, val, + NULL, tmp->data) != 0) + break; + tmp = tmp->next; + } + + return; +} + +API pkgmgr_client *pkgmgr_client_new(client_type ctype) +{ + pkgmgr_client_t *pc = NULL; + int ret = -1; + + if (ctype != PC_REQUEST && ctype != PC_LISTENING + && ctype != PC_BROADCAST) + return NULL; + + /* Allocate memory for ADT:pkgmgr_client */ + pc = calloc(1, sizeof(pkgmgr_client_t)); + if (pc == NULL) { + _LOGE("No memory"); + return NULL; + } + + /* Manage pc */ + pc->ctype = ctype; + + if (pc->ctype == PC_REQUEST) { + pc->info.request.cc = comm_client_new(); + if (pc->info.request.cc == NULL) { + _LOGE("client creation failed"); + goto err; + } + ret = comm_client_set_status_callback(pc->info.request.cc, + __operation_callback, pc); + if (ret < 0) { + _LOGE("comm_client_set_status_callback() failed - %d", + ret); + goto err; + } + } else if (pc->ctype == PC_LISTENING) { + pc->info.listening.cc = comm_client_new(); + if (pc->info.listening.cc == NULL) { + _LOGE("client creation failed"); + goto err; + } + ret = comm_client_set_status_callback(pc->info.request.cc, + __status_callback, pc); + if (ret < 0) { + _LOGE("comm_client_set_status_callback() failed - %d", + ret); + goto err; + } + } else if (pc->ctype == PC_BROADCAST) { + pc->info.broadcast.bc = comm_status_broadcast_server_connect(); + if (pc->info.broadcast.bc == NULL) { + _LOGE("client creation failed"); + goto err; + } + ret = 0; + } + + return (pkgmgr_client *) pc; + + err: + if (pc) + free(pc); + return NULL; +} + +API int pkgmgr_client_free(pkgmgr_client *pc) +{ + int ret = -1; + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + + if (mpc == NULL) { + _LOGE("Invalid argument"); + return PKGMGR_R_EINVAL; + } + + if (mpc->ctype == PC_REQUEST) { + req_cb_info *tmp; + req_cb_info *prev; + for (tmp = mpc->info.request.rhead; tmp;) { + prev = tmp; + tmp = tmp->next; + free(prev); + } + + ret = comm_client_free(mpc->info.request.cc); + if (ret < 0) { + _LOGE("comm_client_free() failed - %d", ret); + goto err; + } + } else if (mpc->ctype == PC_LISTENING) { + listen_cb_info *tmp; + listen_cb_info *prev; + for (tmp = mpc->info.listening.lhead; tmp;) { + prev = tmp; + tmp = tmp->next; + free(prev); + } + + ret = comm_client_free(mpc->info.listening.cc); + if (ret < 0) { + _LOGE("comm_client_free() failed - %d", ret); + goto err; + } + } else if (mpc->ctype == PC_BROADCAST) { + comm_status_broadcast_server_disconnect(mpc->info.broadcast.bc); + ret = 0; + } else { + _LOGE("Invalid client type\n"); + return PKGMGR_R_EINVAL; + } + + free(mpc); + mpc = NULL; + return PKGMGR_R_OK; + + err: + if (mpc) { + free(mpc); + mpc = NULL; + } + return PKGMGR_R_ERROR; +} + +static char *__get_req_key(const char *pkg_path) +{ + struct timeval tv; + long curtime; + char timestr[PKG_STRING_LEN_MAX]; + char *str_req_key; + int size; + + gettimeofday(&tv, NULL); + curtime = tv.tv_sec * 1000000 + tv.tv_usec; + snprintf(timestr, sizeof(timestr), "%ld", curtime); + + size = strlen(pkg_path) + strlen(timestr) + 2; + str_req_key = (char *)calloc(size, sizeof(char)); + if (str_req_key == NULL) { + _LOGD("calloc failed"); + return NULL; + } + snprintf(str_req_key, size, "%s_%s", pkg_path, timestr); + + return str_req_key; +} + +static char *__get_type_from_path(const char *pkg_path) +{ + int ret; + char mimetype[255] = { '\0', }; + char extlist[256] = { '\0', }; + char *pkg_type; + + ret = aul_get_mime_from_file(pkg_path, mimetype, sizeof(mimetype)); + if (ret) { + _LOGE("aul_get_mime_from_file() failed - error code[%d]\n", + ret); + return NULL; + } + + ret = aul_get_mime_extension(mimetype, extlist, sizeof(extlist)); + if (ret) { + _LOGE("aul_get_mime_extension() failed - error code[%d]\n", + ret); + return NULL; + } + + if (strlen(extlist) == 0) + return NULL; + + if (strchr(extlist, ',')) { + extlist[strlen(extlist) - strlen(strchr(extlist, ','))] = '\0'; + } + pkg_type = strchr(extlist, '.') + 1; + return strdup(pkg_type); +} + +API int pkgmgr_client_install(pkgmgr_client * pc, const char *pkg_type, + const char *descriptor_path, const char *pkg_path, + const char *optional_file, pkgmgr_mode mode, + pkgmgr_handler event_cb, void *data) +{ + char *pkgtype; + char *installer_path; + char *req_key; + int req_id; + int i = 0; + char *argv[PKG_ARGC_MAX] = { NULL, }; + char *args = NULL; + int argcnt = 0; + int len = 0; + char *temp = NULL; + int ret; + char *cookie = NULL; + + /* Check for NULL value of pc */ + if (pc == NULL) { + _LOGD("package manager client handle is NULL\n"); + return PKGMGR_R_EINVAL; + } + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + + /* 0. check the pc type */ + if (mpc->ctype != PC_REQUEST) + return PKGMGR_R_EINVAL; + + /* 1. check argument */ + if (descriptor_path) { + if (strlen(descriptor_path) >= PKG_STRING_LEN_MAX) + return PKGMGR_R_EINVAL; + + if (access(descriptor_path, F_OK) != 0) + return PKGMGR_R_EINVAL; + } + + if (pkg_path == NULL) + return PKGMGR_R_EINVAL; + else { + if (strlen(pkg_path) >= PKG_STRING_LEN_MAX) + return PKGMGR_R_EINVAL; + + if (access(pkg_path, F_OK) != 0) + return PKGMGR_R_EINVAL; + } + + if (optional_file) { + if (strlen(optional_file) >= PKG_STRING_LEN_MAX) + return PKGMGR_R_EINVAL; + + if (access(optional_file, F_OK) != 0) + return PKGMGR_R_EINVAL; + } + + /* 2. get installer path using pkg_path */ + if (pkg_type) { + installer_path = _get_backend_path_with_type(pkg_type); + pkgtype = strdup(pkg_type); + } else { + installer_path = _get_backend_path(pkg_path); + pkgtype = __get_type_from_path(pkg_path); + } + + if (installer_path == NULL) { + free(pkgtype); + return PKGMGR_R_EINVAL; + } + + /* 3. generate req_key */ + req_key = __get_req_key(pkg_path); + + /* 4. add callback info - add callback info to pkgmgr_client */ + req_id = _get_request_id(); + __add_op_cbinfo(mpc, req_id, req_key, event_cb, data); + + /* 5. generate argv */ + + /* argv[0] installer path */ + argv[argcnt++] = installer_path; + /* argv[1] */ + argv[argcnt++] = strdup("-k"); + /* argv[2] */ + argv[argcnt++] = req_key; + /* argv[3] */ + argv[argcnt++] = strdup("-i"); + /* argv[(4)] if exists */ + if (descriptor_path) + argv[argcnt++] = strdup(descriptor_path); + /* argv[4] */ + argv[argcnt++] = strdup(pkg_path); + /* argv[5] -q option should be located at the end of command !! */ + if (mode == PM_QUIET) + argv[argcnt++] = strdup("-q"); + + /*** add quote in all string for special charactor like '\n'*** FIX */ + for (i = 0; i < argcnt; i++) { + temp = g_shell_quote(argv[i]); + len += (strlen(temp) + 1); + g_free(temp); + } + + args = (char *)calloc(len, sizeof(char)); + if (args == NULL) { + _LOGD("calloc failed"); + + for (i = 0; i < argcnt; i++) + free(argv[i]); + + free(pkgtype); + return PKGMGR_R_ERROR; + } + strncpy(args, argv[0], len - 1); + + for (i = 1; i < argcnt; i++) { + strncat(args, " ", strlen(" ")); + temp = g_shell_quote(argv[i]); + strncat(args, temp, strlen(temp)); + g_free(temp); + } + _LOGD("[args] %s [len] %d\n", args, len); + /******************* end of quote ************************/ + + /* 6. request install */ + ret = comm_client_request(mpc->info.request.cc, req_key, + COMM_REQ_TO_INSTALLER, pkgtype, pkg_path, + args, cookie, 0); + if (ret < 0) { + _LOGE("request failed, ret=%d\n", ret); + + for (i = 0; i < argcnt; i++) + free(argv[i]); + free(args); + free(pkgtype); + return PKGMGR_R_ECOMM; + } + + for (i = 0; i < argcnt; i++) + free(argv[i]); + + free(args); + free(pkgtype); + + return req_id; +} + +int __iterfunc(const aul_app_info *info, void *data) +{ + char pkgname[PKG_STRING_LEN_MAX]; + const char *pkg_name; + + pkg_name = (const char *)data; + + aul_app_get_pkgname_bypid(info->pid, pkgname, sizeof(pkgname)); + + if (strncmp(pkg_name, pkgname, strlen(pkg_name)) == 0) { + if (aul_terminate_pid(info->pid) < 0) + kill(info->pid, SIGKILL); + } + + return 0; +} + +API int pkgmgr_client_uninstall(pkgmgr_client *pc, const char *pkg_type, + const char *pkg_name, pkgmgr_mode mode, + pkgmgr_handler event_cb, void *data) +{ + const char *pkgtype; + char *installer_path; + char *req_key; + int req_id; + int i = 0; + char *argv[PKG_ARGC_MAX] = { NULL, }; + char *args = NULL; + int argcnt = 0; + int len = 0; + char *temp = NULL; + int ret; + char *cookie = NULL; + + /* Check for NULL value of pc */ + if (pc == NULL) { + _LOGD("package manager client handle is NULL\n"); + return PKGMGR_R_EINVAL; + } + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + + /* 0. check the pc type */ + if (mpc->ctype != PC_REQUEST) + return PKGMGR_R_EINVAL; + + /* 1. check argument */ + if (pkg_name == NULL) + return PKGMGR_R_EINVAL; + + if (aul_app_is_running(pkg_name)) { + ret = + aul_app_get_running_app_info(__iterfunc, (void *)pkg_name); + if (ret < 0) + return PKGMGR_R_ERROR; + } + + if (pkg_type == NULL) { + pkgtype = _get_pkg_type_from_desktop_file(pkg_name); + if (pkgtype == NULL) + return PKGMGR_R_EINVAL; + } else + pkgtype = pkg_type; + + if (strlen(pkg_name) >= PKG_STRING_LEN_MAX) + return PKGMGR_R_EINVAL; + + /* 2. get installer path using pkg_path */ + installer_path = _get_backend_path_with_type(pkgtype); + if (installer_path == NULL) + return PKGMGR_R_EINVAL; + + /* 3. generate req_key */ + req_key = __get_req_key(pkg_name); + + /* 4. add callback info - add callback info to pkgmgr_client */ + req_id = _get_request_id(); + __add_op_cbinfo(mpc, req_id, req_key, event_cb, data); + + /* 5. generate argv */ + + /* argv[0] installer path */ + argv[argcnt++] = installer_path; + /* argv[1] */ + argv[argcnt++] = strdup("-k"); + /* argv[2] */ + argv[argcnt++] = req_key; + /* argv[3] */ + argv[argcnt++] = strdup("-d"); + /* argv[4] */ + argv[argcnt++] = strdup(pkg_name); + /* argv[5] -q option should be located at the end of command !! */ + if (mode == PM_QUIET) + argv[argcnt++] = strdup("-q"); + + /*** add quote in all string for special charactor like '\n'*** FIX */ + for (i = 0; i < argcnt; i++) { + temp = g_shell_quote(argv[i]); + len += (strlen(temp) + 1); + g_free(temp); + } + + args = (char *)calloc(len, sizeof(char)); + if (args == NULL) { + _LOGD("calloc failed"); + + for (i = 0; i < argcnt; i++) + free(argv[i]); + + return PKGMGR_R_ERROR; + } + strncpy(args, argv[0], len - 1); + + for (i = 1; i < argcnt; i++) { + strncat(args, " ", strlen(" ")); + temp = g_shell_quote(argv[i]); + strncat(args, temp, strlen(temp)); + g_free(temp); + } + _LOGD("[args] %s [len] %d\n", args, len); + /******************* end of quote ************************/ + + /* 6. request install */ + ret = comm_client_request(mpc->info.request.cc, req_key, + COMM_REQ_TO_INSTALLER, pkgtype, pkg_name, + args, cookie, 0); + if (ret < 0) { + _LOGE("request failed, ret=%d\n", ret); + + for (i = 0; i < argcnt; i++) + free(argv[i]); + + free(args); + return PKGMGR_R_ECOMM; + } + + for (i = 0; i < argcnt; i++) + free(argv[i]); + + free(args); + + return req_id; +} + +API int pkgmgr_client_activate(pkgmgr_client * pc, const char *pkg_type, + const char *pkg_name) +{ + const char *pkgtype; + char *req_key; + char *cookie = NULL; + int ret; + /* Check for NULL value of pc */ + if (pc == NULL) { + _LOGD("package manager client handle is NULL\n"); + return PKGMGR_R_EINVAL; + } + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + + /* 0. check the pc type */ + if (mpc->ctype != PC_REQUEST) + return PKGMGR_R_EINVAL; + + /* 1. check argument */ + if (pkg_name == NULL) + return PKGMGR_R_EINVAL; + + if (pkg_type == NULL) { + pkgtype = _get_pkg_type_from_desktop_file(pkg_name); + if (pkgtype == NULL) + return PKGMGR_R_EINVAL; + } else + pkgtype = pkg_type; + + if (strlen(pkg_name) >= PKG_STRING_LEN_MAX) + return PKGMGR_R_EINVAL; + + /* 2. generate req_key */ + req_key = __get_req_key(pkg_name); + + /* 3. request activate */ + ret = comm_client_request(mpc->info.request.cc, req_key, + COMM_REQ_TO_ACTIVATOR, pkgtype, + pkg_name, "1", cookie, 1); + if (ret < 0) { + _LOGE("request failed, ret=%d\n", ret); + free(req_key); + return PKGMGR_R_ECOMM; + } + + free(req_key); + + return PKGMGR_R_OK; +} + +API int pkgmgr_client_deactivate(pkgmgr_client *pc, const char *pkg_type, + const char *pkg_name) +{ + const char *pkgtype; + char *req_key; + char *cookie = NULL; + int ret; + /* Check for NULL value of pc */ + if (pc == NULL) { + _LOGD("package manager client handle is NULL\n"); + return PKGMGR_R_EINVAL; + } + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + + /* 0. check the pc type */ + if (mpc->ctype != PC_REQUEST) + return PKGMGR_R_EINVAL; + + /* 1. check argument */ + if (pkg_name == NULL) + return PKGMGR_R_EINVAL; + + if (pkg_type == NULL) { + pkgtype = _get_pkg_type_from_desktop_file(pkg_name); + if (pkgtype == NULL) + return PKGMGR_R_EINVAL; + } else + pkgtype = pkg_type; + + if (strlen(pkg_name) >= PKG_STRING_LEN_MAX) + return PKGMGR_R_EINVAL; + + /* 2. generate req_key */ + req_key = __get_req_key(pkg_name); + + /* 3. request activate */ + ret = comm_client_request(mpc->info.request.cc, req_key, + COMM_REQ_TO_ACTIVATOR, pkgtype, + pkg_name, "0", cookie, 1); + if (ret < 0) { + _LOGE("request failed, ret=%d\n", ret); + free(req_key); + return PKGMGR_R_ECOMM; + } + + free(req_key); + + return PKGMGR_R_OK; +} + +API int pkgmgr_client_clear_user_data(pkgmgr_client *pc, const char *pkg_type, + const char *pkg_name, pkgmgr_mode mode) +{ + const char *pkgtype; + char *installer_path; + char *req_key; + int req_id; + int i = 0; + char *argv[PKG_ARGC_MAX] = { NULL, }; + char *args = NULL; + int argcnt = 0; + int len = 0; + char *temp = NULL; + int ret; + char *cookie = NULL; + + /* Check for NULL value of pc */ + if (pc == NULL) { + _LOGD("package manager client handle is NULL\n"); + return PKGMGR_R_EINVAL; + } + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + + /* 0. check the pc type */ + if (mpc->ctype != PC_REQUEST) + return PKGMGR_R_EINVAL; + + /* 1. check argument */ + if (pkg_name == NULL) + return PKGMGR_R_EINVAL; + +/* + if( aul_app_is_running(pkg_name) ) { + ret = aul_app_get_running_app_info(__iterfunc, (void *) pkg_name); + if(ret < 0) + return PKGMGR_R_ERROR; + } +*/ + + if (pkg_type == NULL) { + pkgtype = _get_pkg_type_from_desktop_file(pkg_name); + if (pkgtype == NULL) + return PKGMGR_R_EINVAL; + } else + pkgtype = pkg_type; + + if (strlen(pkg_name) >= PKG_STRING_LEN_MAX) + return PKGMGR_R_EINVAL; + + /* 2. get installer path using pkg_path */ + installer_path = _get_backend_path_with_type(pkgtype); + if (installer_path == NULL) + return PKGMGR_R_EINVAL; + + /* 3. generate req_key */ + req_key = __get_req_key(pkg_name); + + /* 4. generate argv */ + + /* argv[0] installer path */ + argv[argcnt++] = installer_path; + /* argv[1] */ + argv[argcnt++] = strdup("-k"); + /* argv[2] */ + argv[argcnt++] = req_key; + /* argv[3] */ + argv[argcnt++] = strdup("-c"); + /* argv[4] */ + argv[argcnt++] = strdup(pkg_name); + /* argv[5] -q option should be located at the end of command !! */ + if (mode == PM_QUIET) + argv[argcnt++] = strdup("-q"); + + /*** add quote in all string for special charactor like '\n'*** FIX */ + for (i = 0; i < argcnt; i++) { + temp = g_shell_quote(argv[i]); + len += (strlen(temp) + 1); + g_free(temp); + } + + args = (char *)calloc(len, sizeof(char)); + if (args == NULL) { + _LOGD("calloc failed"); + + for (i = 0; i < argcnt; i++) + free(argv[i]); + + return PKGMGR_R_ERROR; + } + strncpy(args, argv[0], len - 1); + + for (i = 1; i < argcnt; i++) { + strncat(args, " ", strlen(" ")); + temp = g_shell_quote(argv[i]); + strncat(args, temp, strlen(temp)); + g_free(temp); + } + _LOGD("[args] %s [len] %d\n", args, len); + /******************* end of quote ************************/ + + /* 6. request clear */ + ret = comm_client_request(mpc->info.request.cc, req_key, + COMM_REQ_TO_CLEARER, pkgtype, pkg_name, + args, cookie, 1); + if (ret < 0) { + _LOGE("request failed, ret=%d\n", ret); + + for (i = 0; i < argcnt; i++) + free(argv[i]); + + free(args); + return PKGMGR_R_ECOMM; + } + + for (i = 0; i < argcnt; i++) + free(argv[i]); + + free(args); + + return PKGMGR_R_OK; +} + +API int pkgmgr_client_listen_status(pkgmgr_client *pc, pkgmgr_handler event_cb, + void *data) +{ + int req_id; + /* Check for NULL value of pc */ + if (pc == NULL) { + _LOGD("package manager client handle is NULL\n"); + return PKGMGR_R_EINVAL; + } + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + + /* 0. check the pc type */ + if (mpc->ctype != PC_LISTENING) + return PKGMGR_R_EINVAL; + + /* 1. check argument */ + if (event_cb == NULL) + return PKGMGR_R_EINVAL; + + /* 2. add callback info to pkgmgr_client */ + req_id = _get_request_id(); + __add_stat_cbinfo(mpc, req_id, event_cb, data); + + return req_id; +} + +API int pkgmgr_client_broadcast_status(pkgmgr_client *pc, const char *pkg_type, + const char *pkg_name, const char *key, + const char *val) +{ + /* Check for NULL value of pc */ + if (pc == NULL) { + _LOGD("package manager client handle is NULL\n"); + return PKGMGR_R_EINVAL; + } + /* Check for valid arguments. NULL parameter causes DBUS to abort */ + if (pkg_name == NULL || pkg_type == NULL || key == NULL || val == NULL) { + _LOGD("Argument supplied is NULL\n"); + return PKGMGR_R_EINVAL; + } + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + + /* 0. check the pc type */ + if (mpc->ctype != PC_BROADCAST) + return PKGMGR_R_EINVAL; + + comm_status_broadcast_server_send_signal(mpc->info.broadcast.bc, + PKG_STATUS, pkg_type, + pkg_name, key, val); + + return PKGMGR_R_OK; +} + +ail_cb_ret_e __appinfo_func(const ail_appinfo_h appinfo, void *user_data) +{ + char *type; + char *package; + char *version; + + iter_data *udata = (iter_data *) user_data; + + ail_appinfo_get_str(appinfo, AIL_PROP_X_SLP_PACKAGETYPE_STR, &type); + if (type == NULL) + type = ""; + ail_appinfo_get_str(appinfo, AIL_PROP_PACKAGE_STR, &package); + if (package == NULL) + package = ""; + ail_appinfo_get_str(appinfo, AIL_PROP_VERSION_STR, &version); + if (version == NULL) + version = ""; + + if (udata->iter_fn(type, package, version, udata->data) != 0) + return AIL_CB_RET_CANCEL; + + return AIL_CB_RET_CONTINUE; +} + +API int pkgmgr_get_pkg_list(pkgmgr_iter_fn iter_fn, void *data) +{ + int cnt = -1; + ail_filter_h filter; + ail_error_e ret; + + if (iter_fn == NULL) + return PKGMGR_R_EINVAL; + + ret = ail_filter_new(&filter); + if (ret != AIL_ERROR_OK) { + return PKGMGR_R_ERROR; + } + + ret = ail_filter_add_str(filter, AIL_PROP_TYPE_STR, "Application"); + if (ret != AIL_ERROR_OK) { + ail_filter_destroy(filter); + return PKGMGR_R_ERROR; + } + + ret = ail_filter_add_bool(filter, AIL_PROP_X_SLP_REMOVABLE_BOOL, true); + if (ret != AIL_ERROR_OK) { + ail_filter_destroy(filter); + return PKGMGR_R_ERROR; + } + + ret = ail_filter_count_appinfo(filter, &cnt); + if (ret != AIL_ERROR_OK) { + ail_filter_destroy(filter); + return PKGMGR_R_ERROR; + } + + iter_data *udata = calloc(1, sizeof(iter_data)); + if (udata == NULL) { + _LOGE("calloc failed"); + ail_filter_destroy(filter); + + return PKGMGR_R_ERROR; + } + udata->iter_fn = iter_fn; + udata->data = data; + + ail_filter_list_appinfo_foreach(filter, __appinfo_func, udata); + + free(udata); + + ret = ail_filter_destroy(filter); + if (ret != AIL_ERROR_OK) { + return PKGMGR_R_ERROR; + } + + return PKGMGR_R_OK; +} + +API pkgmgr_info *pkgmgr_info_new(const char *pkg_type, const char *pkg_name) +{ + const char *pkgtype; + pkg_plugin_set *plugin_set = NULL; + package_manager_pkg_detail_info_t *pkg_detail_info = NULL; + + /* 1. check argument */ + if (pkg_name == NULL) + return NULL; + + if (pkg_type == NULL) { + pkgtype = _get_pkg_type_from_desktop_file(pkg_name); + if (pkgtype == NULL) + return NULL; + } else + pkgtype = pkg_type; + + if (strlen(pkg_name) >= PKG_STRING_LEN_MAX) + return NULL; + + pkg_detail_info = calloc(1, sizeof(package_manager_pkg_detail_info_t)); + if (pkg_detail_info == NULL) { + _LOGE("*** Failed to alloc package_handler_info.\n"); + return NULL; + } + + plugin_set = _package_manager_load_library(pkgtype); + if (plugin_set == NULL) { + free(pkg_detail_info); + return NULL; + } + + if (plugin_set->pkg_is_installed) { + if (plugin_set->pkg_is_installed(pkg_name) != 0) { + free(pkg_detail_info); + return NULL; + } + + if (plugin_set->get_pkg_detail_info) { + if (plugin_set->get_pkg_detail_info(pkg_name, + pkg_detail_info) != 0) { + free(pkg_detail_info); + return NULL; + } + } + } + + return (pkgmgr_info *) pkg_detail_info; +} + +API char * pkgmgr_info_get_string(pkgmgr_info * pkg_info, const char *key) +{ + package_manager_pkg_detail_info_t *pkg_detail_info; + + if (pkg_info == NULL) + return NULL; + if (key == NULL) + return NULL; + + pkg_detail_info = (package_manager_pkg_detail_info_t *) pkg_info; + + return _get_info_string(key, pkg_detail_info); +} + +API pkgmgr_info *pkgmgr_info_new_from_file(const char *pkg_type, + const char *pkg_path) +{ + pkg_plugin_set *plugin_set = NULL; + package_manager_pkg_detail_info_t *pkg_detail_info = NULL; + char *pkgtype; + if (pkg_path == NULL) { + _LOGE("pkg_path is NULL\n"); + return NULL; + } + + if (strlen(pkg_path) > PKG_URL_STRING_LEN_MAX) { + _LOGE("length of pkg_path is too long - %d.\n", + strlen(pkg_path)); + return NULL; + } + + pkg_detail_info = calloc(1, sizeof(package_manager_pkg_detail_info_t)); + if (pkg_detail_info == NULL) { + _LOGE("*** Failed to alloc package_handler_info.\n"); + return NULL; + } + + if (pkg_type == NULL) + pkgtype = __get_type_from_path(pkg_path); + else + pkgtype = strdup(pkg_type); + + plugin_set = _package_manager_load_library(pkgtype); + if (plugin_set == NULL) { + free(pkg_detail_info); + free(pkgtype); + return NULL; + } + + if (plugin_set->get_pkg_detail_info_from_package) { + if (plugin_set->get_pkg_detail_info_from_package(pkg_path, + pkg_detail_info) != 0) { + free(pkg_detail_info); + free(pkgtype); + return NULL; + } + } + + free(pkgtype); + return (pkgmgr_info *) pkg_detail_info; +} + +API int pkgmgr_info_free(pkgmgr_info * pkg_info) +{ + if (pkg_info == NULL) + return PKGMGR_R_EINVAL; + + free(pkg_info); + pkg_info = NULL; + + return 0; +} diff --git a/comm/CMakeLists.txt b/comm/CMakeLists.txt new file mode 100755 index 0000000..245d264 --- /dev/null +++ b/comm/CMakeLists.txt @@ -0,0 +1,161 @@ +### Description +# Communication modules for pkg-mgr client lib and server process +# By Youmin Ha + +cmake_minimum_required(VERSION 2.6) +#set(CMAKE_SKIP_BUILD_RPATH true) +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + + +### Versioning +if(DEFINED ${VERSION}) + message("VERSION: ${VERSION}") +else() + message("VERSION is not defined. set it as 0.1.0") + set(VERSION 0.1.0) +endif() +if(DEFINED ${VERSION_MAJOR}) + message("VERSION_MAJOR: ${VERSION_MAJOR}") +else() + message( "VERSION_MAJOR is not defined. set it as 0") + set(VERSION_MAJOR 0) +endif() +message(STATUS "version/major : ${VERSION} / ${VERSION_MAJOR}") + +### Get required CFLAGS, LDFLAGS from pkg-config + +include(FindPkgConfig) +pkg_check_modules(comm_pkgs REQUIRED dbus-1 dbus-glib-1 dlog) + +foreach(flag ${comm_pkgs_CFLAGS}) + set(comm_pkgs_CFLAGS_str "${comm_pkgs_CFLAGS_str} ${flag}") +endforeach() + + +### Set current binary dir to be included (for generated *.h files) +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +### Create dbus-glib bindings headers (client/server) from xml by dbus-binding-tool + +# comm_pkg_mgr : package manger interface (client - package manager process) +add_custom_target(comm_pkg_mgr_client_dbus_bindings.h + COMMAND dbus-binding-tool --prefix=pkgmgr --mode=glib-client + ${CMAKE_CURRENT_SOURCE_DIR}/comm_pkg_mgr.xml + --output=${CMAKE_CURRENT_BINARY_DIR}/comm_pkg_mgr_client_dbus_bindings.h + ) +add_custom_target(comm_pkg_mgr_server_dbus_bindings.h + COMMAND dbus-binding-tool --prefix=pkgmgr --mode=glib-server + ${CMAKE_CURRENT_SOURCE_DIR}/comm_pkg_mgr.xml + --output=${CMAKE_CURRENT_BINARY_DIR}/comm_pkg_mgr_server_dbus_bindings.h + ) + +# comm_status_broadcast : status broadcast interface (client - backend process) +add_custom_target(comm_status_broadcast_client_dbus_bindings.h + COMMAND dbus-binding-tool --prefix=status_broadcast --mode=glib-client + ${CMAKE_CURRENT_SOURCE_DIR}/comm_status_broadcast.xml + --output=${CMAKE_CURRENT_BINARY_DIR}/comm_status_broadcast_client_dbus_bindings.h + ) +add_custom_target(comm_status_broadcast_server_dbus_bindings.h + COMMAND dbus-binding-tool --prefix=status_broadcast --mode=glib-server + ${CMAKE_CURRENT_SOURCE_DIR}/comm_status_broadcast.xml + --output=${CMAKE_CURRENT_BINARY_DIR}/comm_status_broadcast_server_dbus_bindings.h + ) + +### Create marshaller header/source for signal (client must use this) +add_custom_target(comm_status_broadcast_signal_marshaller.h + COMMAND glib-genmarshal --header ${CMAKE_CURRENT_SOURCE_DIR}/comm_status_broadcast_signal_marshaller.list > ${CMAKE_CURRENT_BINARY_DIR}/comm_status_broadcast_signal_marshaller.h + ) +add_custom_target(comm_status_broadcast_signal_marshaller.c + COMMAND glib-genmarshal --body ${CMAKE_CURRENT_SOURCE_DIR}/comm_status_broadcast_signal_marshaller.list > ${CMAKE_CURRENT_BINARY_DIR}/comm_status_broadcast_signal_marshaller.c + ) +set_source_files_properties(comm_status_broadcast_signal_marshaller.c PROPERTIES GENERATED true) # This source is generated during build time, so this property must be set + + + + + +### Build modules + +## client for apps +# Send request, get status signal +add_library(pkgmgr_installer_client SHARED + comm_client_dbus.c + #${CMAKE_CURRENT_BINARY_DIR}/comm_status_broadcast_signal_marshaller.c + ) +set_target_properties(pkgmgr_installer_client PROPERTIES SOVERSION ${VERSION_MAJOR}) +set_target_properties(pkgmgr_installer_client PROPERTIES VERSION ${VERSION}) +set_target_properties(pkgmgr_installer_client PROPERTIES COMPILE_FLAGS "${comm_pkgs_CFLAGS_str}") +target_link_libraries(pkgmgr_installer_client ${comm_pkgs_LDFLAGS}) +add_dependencies(pkgmgr_installer_client comm_pkg_mgr_client_dbus_bindings.h comm_status_broadcast_client_dbus_bindings.h comm_status_broadcast_signal_marshaller.h comm_status_broadcast_signal_marshaller.c) + +## pkg-mgr server for PMS +# Get request +add_library(pkgmgr_installer_pkg_mgr_server STATIC + comm_pkg_mgr_server.c) +set_target_properties(pkgmgr_installer_pkg_mgr_server PROPERTIES SOVERSION ${VERSION_MAJOR}) +set_target_properties(pkgmgr_installer_pkg_mgr_server PROPERTIES VERSION ${VERSION}) +set_target_properties(pkgmgr_installer_pkg_mgr_server PROPERTIES COMPILE_FLAGS "${comm_pkgs_CFLAGS_str}") +target_link_libraries(pkgmgr_installer_pkg_mgr_server ${comm_pkgs_LDFLAGS}) +add_dependencies(pkgmgr_installer_pkg_mgr_server comm_pkg_mgr_server_dbus_bindings.h) + +## status-broadcast server for backend/downloader +# Send signal +add_library(pkgmgr_installer_status_broadcast_server SHARED + comm_status_broadcast_server_dbus.c + ) +set_target_properties(pkgmgr_installer_status_broadcast_server PROPERTIES SOVERSION ${VERSION_MAJOR}) +set_target_properties(pkgmgr_installer_status_broadcast_server PROPERTIES VERSION ${VERSION}) +set_target_properties(pkgmgr_installer_status_broadcast_server PROPERTIES COMPILE_FLAGS "${comm_pkgs_CFLAGS_str}") +target_link_libraries(pkgmgr_installer_status_broadcast_server ${comm_pkgs_LDFLAGS}) +add_dependencies(pkgmgr_installer_status_broadcast_server comm_status_broadcast_server_dbus_bindings.h) + + +## comm_socket +# Internal lib +add_library(comm_socket STATIC comm_socket.c) +set_target_properties(comm_socket PROPERTIES COMPILE_FLAGS "${comm_pkgs_CFLAGS_str}") +#target_link_libraries(comm_socket) + +## pkgmgr_installer object (by youmin.ha) +# This library is for installer backend +add_library(pkgmgr_installer SHARED pkgmgr_installer.c) +set_target_properties(pkgmgr_installer PROPERTIES SOVERSION ${VERSION_MAJOR}) +set_target_properties(pkgmgr_installer PROPERTIES VERSION ${VERSION}) +set_target_properties(pkgmgr_installer PROPERTIES COMPILE_FLAGS "${comm_pkgs_CFLAGS_str}") +target_link_libraries(pkgmgr_installer pkgmgr_installer_status_broadcast_server ${comm_pkgs_LDFLAGS}) + + +### Create pc file +configure_file(pkgmgr-installer-client.pc.in ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-installer-client.pc @ONLY) +configure_file(pkgmgr-installer-status-broadcast-server.pc.in ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-installer-status-broadcast-server.pc @ONLY) +configure_file(pkgmgr-installer.pc.in ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-installer.pc @ONLY) + + +## Install +INSTALL(TARGETS + pkgmgr_installer_client + pkgmgr_installer_status_broadcast_server + pkgmgr_installer + DESTINATION lib + COMPONENT RuntimeLibraries) +INSTALL(FILES + comm_client.h + comm_status_broadcast_server.h + comm_config.h + pkgmgr_installer.h + DESTINATION include/pkgmgr) + + +INSTALL(FILES + ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-installer-client.pc + ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-installer-status-broadcast-server.pc + ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-installer.pc + DESTINATION lib/pkgconfig) + + + + +## test +add_subdirectory(test) + + diff --git a/comm/SLP_package_manager_frontend_backend_PG.h b/comm/SLP_package_manager_frontend_backend_PG.h new file mode 100755 index 0000000..3fe0ff5 --- /dev/null +++ b/comm/SLP_package_manager_frontend_backend_PG.h @@ -0,0 +1,470 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + + + + + +/** + * @ingroup SLP_PG + * @defgroup pacakge_manager_PG PackageManagerStructure + * @brief A programming guide for deelopers who want to make a frontend/backend pair for a package type. + * @{ + +

Introduction

+

Terms of use

+
    +
  • frontend an installer frontend process
  • +
  • backend an installer backend process
  • +
  • backendlib a library of backend plugin
  • +
  • PMS Package manager server
  • +
+ +

Structure overview

+ + When a command to install/update/delete a package to package-manager system, a frontend process receives request, and pass it to the package manager server. Package manager server will queue all requests, and runs backend one by one.
+For example,
+
SamsungApps --(install foo.deb)--> frontend --(install foo.deb)--> PMS --(Run dpkg backend to install foo.deb)--> backend

+ +When 'install' command is given, the package file to be installed is already downloaded by user's application (SamsungApps, ...), and these frontend/PMS/backend are only responsible for installing it.
+Requests between frontend and PMS, and signal broadcasting between backend and frontend/apps are implemented by dbus.
+


+ + To get the package information, backend plugin library is used. Each backend library provides the predefined functions, and package manager client library uses it.
+
SamsungApps ~~> package-manager client library ~~> backend end plugin library
+
(link and API call) (dynamic loading and symbol binding)

+ + +Detailed informations for each process are explained below. + +

Frontend

+ + A frontend is a program which shows UI to users(if needed), requests install/update/delete/recover to PMS, and shows installing status(if needed). frontend/backend programs must be exist per one package type. Again, each package type must have one frontend/backend pair.
+ + A frontend process runs with user provilege, executed by package-manager client API, in include/package-manager.h; +
    +
  • package_manager_install_application()
  • +
  • package_manager_uninstall_application()
  • +
+ + Frontend process does following things; +
    +
  • Gets arguments from argv, with one of following options; +
      +
    • -i : Install package
    • +
    • -u : Update package
    • +
    • -r : Recover package system
    • +
    • -d : Delete package
    • +
    +
  • +
  • Gets cookie from security server.
  • +
  • Sends request to PMS, with various arguments and cookie.
  • +
  • Waits backend's status signals.
  • +
  • Updates UI accroding to backend's status signal, if necessary.
  • +
  • Finishes process when 'end' signal from backend comes.
  • +
+ +A frontend has UI, so it runs in event-loop (usually ecore_loop, sometimes g_main_loop). We provide an object 'comm_client', which is integrated with g_main_loop. So, you have to program event-loop based code. Luckily the ecore_loop in SLP is integrated with g_main_loop, so you don't need to worry about using comm_client API in ecore_loop. + +

Rules

+A frontend must have following features; +
    +
  • Must be able to parse -i, -u, -r, -d, -q options.
  • +
  • Must be able to parse -k option. This string is passed to backend, as a request id. +
  • Must have UI(at least a OK/Cancel dialog), which can be ignored by -q option.
  • +
  • Must be able to use g_main_loop based functions.
  • +
+ + + +

Package manager server

+Package Manager Server(PMS) is a root privilege process, which queues all requests from lots of frontends, and runs backends accrding to each requests.
+PMS has a queue internally, which stores each request and runs one by one.
+When no PMS is running yet, first frontend's request will execute PMS. + + PMS process does following things; +
    +
  • Receives requests from a frontend via dbus.
  • +
  • If the request has a wrong cookie, discard it.
  • +
  • Puts the request into the queue.
  • +
  • Pops a request from the queue, and sends it to corresponding backend.
  • +
  • When the backend finishes, run next request in the queue.
  • +
+ +PMS is already made and installed in your system. + +

Backend

+ +for a certain package type, a backend is a root privilege process invoked by PMS, which is doing following things; +
    +
  • Parses input values
  • +
  • Checks signing of the package file, and verifies its validity (if necessary) +
  • Does install/update/delete a pacakge, or recovers package system, or
  • +
  • activate/deactivate a package
  • +
  • Broadcasts current status
  • +
+ +

Rules

+A backend must have following features; +
    +
  • Must parse args string from frontend.
  • +
  • Must install/update/delete a package.
  • +
  • Must be able to recover package system, when it is corrupted.
  • +
  • Must broadcast current install/status
  • +
+ +

Backend library

+ +for a certain package type, a backend library is just a library client process uses this library. +Backend library does following things; +
    +
  • Checks whether package is installed or not
  • +
  • Gets the list of installed package
  • +
  • Gets the information of installed package
  • +
  • Gets the information from package file
  • +
+ +

Rules

+A backend must have following features; +
    +
  • Must check whether package is installed or not.
  • +
  • Must get the list of installed package.
  • +
  • Must get the information of installed package.
  • +
  • Must gets the information from package file
  • +
+ + +

Programming guide

+ +

Requied dev package

+libpkgmgr-installer-dev package is provided to develop installer frontend/backend.
+@code +$ apt-get install libpkgmgr-installer-dev +@endcode + +libpkgmgr-types-dev package is provided to develop installer backendlib.
+@code +$ apt-get install libpkgmgr-types-dev +@endcode + +Three package-config files are installed; pkgmgr-installer-client.pc and pkgmgr-installer-status-broadcast-server.pc and pkgmgr-types.pc +The first one is for frontend, the second one is for backend, and last one if for backendlib
+ + +

Installer frontend's programming guide

+ +comm_client module is provided for frontend programming, which can do comminucations with PMS and backend process.
+ +Example code is in packages/test/frontend.c.
+ +NOTE: This example code uses g_main_loop. If you use ecore_loop, you don't need to run g_main_loop_*() functions.
+ +Every installer frontend's command arguments are like this;
+@code +$ [] -k +@endcode +
    +
  • frontend : An installer frontend executable file.
  • +
  • cmd_opt : One of -i(install package), -u(update package), -d(delete package), -r(recover package system), -a(activate package)
  • +
  • opt_val : Means package file path (with -i/-u), package name (with -d, -a). When cmd_opt is -r, no opt_val is required.
  • +
  • req_id : A request id, which is passed from frontend (with -k option) to backend.
  • +
+ + + +

Get a cookie from security-server

+To authenticate this frontend process, firstly you have to get a cookie from security server.
+security-server.h from security-server package has cookie APIs. For more information, see security-server.h file.
+@code + +#include + +/* ...... */ + +char *cookie; +int cookie_size; +int cookie_ret; + +cookie_size = security_server_get_cookie_size(); +/* If security server is down or some other error occured, raise failure */ +if(0 >= cookie_size) { + /* TODO: raise error */ +} else { + cookie = calloc(cookie_size, sizeof(char)); + cookie_ret = security_server_request_cookie(cookie, cookie_size); + /* TODO: Check cookie_ret... (See security-server.h to check return code) */ +} + +@endcode +This cookie string will be passed to PMS later. + +

Parse argv options

+All frontends must support at least 5 options; -i, -u, -d, -r, -k, and -q. Parse each options, and do requested job.
+Only one of following options must be taken.
+
    +
  • -i : Install package
  • +
  • -u : Update package
  • +
  • -r : Recover package system
  • +
  • -d : Delete package
  • +
+Following options must be able to taken.
+
    +
  • -k : An unique string to identify this request. This key will be included in status broadcast signals from backend.
  • +
  • -q : Quiet option. Do now show UI.
  • +
+ + +The sample code uses getopt() function in unistd.h to parse argv options.
+ +@code +#include +#define BUFSIZE 256 + +/* ...... */ + +const char *opts_str = "i:u:d:rqk:"; +int s = 0; +int quite = 0; +int mode = 0; +char buf[BUFSIZE]; +char req_id[BUFSIZE]; + + +while(-1 != (s = getopt(argc, argv, opts_str))) { + switch(s) { + case 'i': + if(mode) break; + mode = MODE_INSTALL; + strncpy(buf, optarg, BUFSIZE); + break; + case 'u': + if(mode) break; + mode = MODE_UPDATE; + strncpy(buf, optarg, BUFSIZE); + break; + case 'd': + if(mode) break; + mode = MODE_DELETE; + strncpy(buf, optarg, BUFSIZE); + break; + case 'r': + if(mode) break; + mode = MODE_RECOVER; + break; + case 'q': + quite = 1; + break; + case 'k': + strncpy(req_id, optarg, BUFSIZE); + + default: + usage(); /* Show usage, and exit */ + } +} + +@endcode + +

Do send a request to install,update,delete or recover

+After parsing argv options, now your frontend knows what command will be request to your backend. For this work, we provide APIs. + +

+

+

+ +

Installer backend's programming guide

+ +Example code is in packages/test/backend.c.
+ +

Parse command args

+Every installer backend's command arguments are like this;
+@code +$ [ ...] +@endcode +
    +
  • backend : An installer backend executable file.
  • +
  • req_id : A request id, which is passed from frontend (with -k option). This is broadcasted with all signals from this backend.
  • +
  • pkg_name : package name
  • +
  • arg1, arg2, ... : Separated arguments from frontend. You can use anything. This is a rule just between frontend and backend.
  • +
+ +Those options must be parsed and processed properly.
+ +

Broadcast installing status

+Backend must broadcast its installing status. You can broadcast your status by using following API. +@code +#include "comm_status_broadcast_server.h" + +/* ... */ + +DBusConnection *conn; +conn = comm_status_broadcast_server_connect(); + +comm_status_broadcast_server_send_signal(conn, req_id, pkg_type, pkg_name, "start", "0"); +/* ... */ +comm_status_broadcast_server_send_signal(conn, req_id, pkg_type, pkg_name, "install_percent", "60"); +/* ... */ +comm_status_broadcast_server_send_signal(conn, req_id, pkg_type, pkg_name, "end", "0"); + +/* ... */ +@endcode + +Last two values are key/value pair. Following values are mandatory; + + + + + + + + + + + + + + + + + + + + + + + + + + +
keyvalueComment
startdownload|install|uninstall|update|recoverStart backend process.
NOTE: 'download' is used only by downloader.
install_percent[number between 0~100]Install progress
error[string]Error message
endok|failEnd backend (Process termination)
+ +Following values are required also. If you need any of them in downloader or installer backend, send it.
+ + + + + + + + + + + + + + + +
keyvalueComment
icon_pathpath of icon fileBefore icon and *.desktop files are installed, menu-screen must have temporary icon file. This option indicates temporary icon file's path.
If no icon_path is provided, menu-screen will use general temporary icon.
download_percent[number between 0~100]Download progress
NOTE: This key is used by downloader only. Installer backends don't use this.
+ +You can send any other key/val pair by this API, to send any information to your frontend or donwloader app. Any keys except above will be ignored by PMS.
+ + + +

Installer backendlib's programming guide

+Example code is in packages/installers/sample/sample_backendlib.c.
+ +

Plugin implementation

+Backendlib should implemented according to following Rule. +
    +
  • Exported API : pkg_plugin_onload() is a exported symbol. This symbol is found when after loading the library.
  • +
  • function pointer : _pkg_plugin_set defines the structor of function pointer. Each functions are implemented.
  • +
  • function mapping : defined each functions are connected to function pointer when pkg_plugin_onload() is called.
  • +
+ +@code +#include "package-manager-plugin.h" + + +static void pkg_native_plugin_unload (void) +{ + //ToDo +} + +static int pkg_plugin_app_is_installed(const char *pkg_name) +{ + //ToDo + + return 0; +} + +static int pkg_plugin_get_installed_apps_list(package_manager_pkg_info_t **list, int *count) +{ + //ToDo + + return 0; +} + +static int pkg_plugin_get_app_detail_info(const char *pkg_name, package_manager_pkg_detail_info_t* pkg_detail_info) +{ + //ToDo + + return 0; +} + +static int pkg_plugin_get_app_detail_info_from_package(const char *pkg_path, package_manager_pkg_detail_info_t* pkg_detail_info) +{ + //ToDo + + return 0; +} + + +int pkg_plugin_onload (pkg_plugin_set * set) +{ + if(set == NULL) + { + return -1; + } + + memset(set, 0x00, sizeof(pkg_plugin_set)); + + set->plugin_unload = pkg_native_plugin_unload; + set->pkg_is_installed = pkg_plugin_app_is_installed; + set->get_installed_pkg_list = pkg_plugin_get_installed_apps_list; + set->get_pkg_detail_info = pkg_plugin_get_app_detail_info; + set->get_pkg_detail_info_from_package = pkg_plugin_get_app_detail_info_from_package; + + return 0; +} +@endcode + + + +

Install frontend/backend

+Your frontend/backend binary executables have to be installed. Usually they are installed into @PREFIX@/bin/.
+ +One thing you must do is that your backend binary's owner must be root, permission must be 700. +In case of backendlib, it's permission is 644. + + +

Create symlinks for your frontend/backend binaries and backendlib library

+After installing your frontend/backend, You have to create symlinks pointing your frontend/backend binaries.
+Those symlinks must be installed as following paths; +
    +
  • frontend : @PREFIX@/etc/package-manager/frontend/
  • +
  • backend : @PREFIX@/etc/package-manager/backend/
  • +
  • backendlib : @PREFIX@/etc/package-manager/backendlib/lib[].so
  • +
+For example, the debian package (*.deb) must have symlink @PREFIX@/etc/package-manager/frontend/deb, which is pointing actual frontend binary.
+Client API and PMS will find actual frontend/backend binaries from those paths.
+ + * @} + */ diff --git a/comm/build.sh b/comm/build.sh new file mode 100755 index 0000000..c425ead --- /dev/null +++ b/comm/build.sh @@ -0,0 +1,30 @@ + +#export CFLAGS="" +#export LDFLAGS="" + +cd `dirname $0` + +PREFIX=/usr + +rm -rf cmake_tmp +mkdir -p cmake_tmp +cd cmake_tmp + +CFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" cmake .. -DCMAKE_INSTALL_PREFIX=${PREFIX} && +make && + +# test +{ + export LD_LIBRARY_PATH=`pwd` + cd test +# ./test_comm_client & +# ./test_comm_status_broadcast_server +# ./test_comm_socket && + ./test_pkgmgr_installer +} +if [ "$?" == "0" ]; then + echo "Test done." +else + echo "Test failed!" +fi + diff --git a/comm/comm_client.c b/comm/comm_client.c new file mode 100755 index 0000000..c7cbb53 --- /dev/null +++ b/comm/comm_client.c @@ -0,0 +1,216 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_config.h" +#include "comm_client.h" +#include "comm_pkg_mgr_client_dbus_bindings.h" +#include "comm_status_broadcast_client_dbus_bindings.h" +#include "comm_status_broadcast_signal_marshaller.h" +#include +#include + +struct comm_client { + /* Resources to be freed */ + DBusGConnection *conn; + GError *err; + DBusGProxy *request_proxy; + DBusGProxy *signal_proxy; + char *pkg_name; + + status_cb signal_cb; + void *signal_cb_data; +}; + +comm_client *comm_client_new(void) +{ + comm_client *cc = NULL; + + cc = calloc(1, sizeof(comm_client)); + if (NULL == cc) + return NULL; + + cc->conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &(cc->err)); + if (NULL == cc->conn) { + g_printerr("Failed to open connection to dbus: %s\n", + cc->err->message); + g_error_free(cc->err); + cc->err = NULL; + comm_client_free(cc); + return NULL; + } + + cc->request_proxy = dbus_g_proxy_new_for_name(cc->conn, + COMM_PKG_MGR_DBUS_SERVICE, + /* name : written in service file */ + COMM_PKG_MGR_DBUS_PATH, + /* path : written as a node in xml */ + COMM_PKG_MGR_DBUS_INTERFACE + /* interface : written as an interface in xml */ + ); + + return cc; +} + +int comm_client_free(comm_client *cc) +{ + if (NULL == cc) + return -1; + + if (cc->err) + g_error_free(cc->err); + if (cc->conn) + dbus_g_connection_unref(cc->conn); + if (cc->request_proxy) + g_object_unref(cc->request_proxy); + if (cc->signal_proxy) + g_object_unref(cc->signal_proxy); + if (cc->pkg_name) + free(cc->pkg_name); + + free(cc); + + return 0; +} + +static void +status_signal_handler(DBusGProxy *proxy, + const char *req_id, + const char *pkg_type, + const char *pkg_name, + const char *key, const char *val, gpointer data) +{ + comm_client *cc = (comm_client *) data; + + dbg("Got signal: %s/%s/%s/%s/%s", req_id, pkg_type, + pkg_name, key, val); + if (cc->signal_cb) { + if (cc->pkg_name && pkg_name && + 0 == strncmp(cc->pkg_name, pkg_name, + strlen(cc->pkg_name))) { + dbg("Run signal handler"); + cc->signal_cb(cc->signal_cb_data, req_id, pkg_type, + pkg_name, key, val); + } else { + dbg("pkg_name is different. (My pkg_name:%s)" + " Though pass signal to user callback.", cc->pkg_name); + cc->signal_cb(cc->signal_cb_data, req_id, pkg_type, + pkg_name, key, val); + } + } else { + dbg("No signal handler is set. Do nothing."); + } +} + +int +comm_client_request(comm_client *cc, const char *req_id, const int req_type, + const char *pkg_type, const char *pkg_name, + const char *args, const char *cookie) +{ + gboolean r; + gint ret = COMM_RET_ERROR; + + dbg("got request:%s/%d/%s/%s/%s/%s\n", req_id, req_type, pkg_type, + pkg_name, args, cookie); + + if (!pkg_name) + pkg_name = ""; /* NULL check */ + + r = org_tizen_slp_pkgmgr_request(cc->request_proxy, req_id, req_type, + pkg_type, pkg_name, args, cookie, + &ret, &(cc->err)); + if (TRUE == r) { + ret = COMM_RET_OK; + } else { + g_printerr("Failed to send request via dbus: %s\n", + cc->err->message); + if (cc->err) { + g_error_free(cc->err); + cc->err = NULL; + } + return ret; + } + dbg("request sent"); + + if (cc->pkg_name) { + dbg("freeing pkg_name"); + free(cc->pkg_name); + dbg("freed pkg_name"); + } + cc->pkg_name = strdup(pkg_name); + + dbg("ret:%d", ret); + + return ret; +} + +int +comm_client_set_status_callback(comm_client *cc, status_cb cb, void *cb_data) +{ + /* set callback */ + if (!cc->signal_proxy) { + dbg("signal_proxy is NULL. Try to create a proxy for signal."); + cc->signal_proxy = dbus_g_proxy_new_for_name(cc->conn, + COMM_STATUS_BROADCAST_DBUS_SERVICE_PREFIX, + COMM_STATUS_BROADCAST_DBUS_PATH, + COMM_STATUS_BROADCAST_DBUS_INTERFACE); + if (NULL == cc->signal_proxy) { + g_printerr("Failed to create proxy for signal\n", NULL); + return COMM_RET_ERROR; + } else { + } + } else { + /* Proxy is existing. Do nothing. */ + } + + cc->signal_cb = cb; + cc->signal_cb_data = cb_data; + + dbg("Register signal-type marshaller."); + dbus_g_object_register_marshaller( + g_cclosure_user_marshal_VOID__STRING_STRING_STRING_STRING_STRING, + /* marshaller */ + G_TYPE_NONE, /* return type */ + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); /* termination flag */ + + dbg("Add signal to proxy."); + dbus_g_proxy_add_signal(cc->signal_proxy, + COMM_STATUS_BROADCAST_SIGNAL_STATUS, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); + + dbg("Connect signal to proxy."); + + dbus_g_proxy_connect_signal(cc->signal_proxy, + COMM_STATUS_BROADCAST_SIGNAL_STATUS, + G_CALLBACK(status_signal_handler), + cc, NULL); + + return 0; +} + diff --git a/comm/comm_client.h b/comm/comm_client.h new file mode 100755 index 0000000..7c5cbcd --- /dev/null +++ b/comm/comm_client.h @@ -0,0 +1,55 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __COMM_CLIENT_H__ +#define __COMM_CLIENT_H__ + +#include "comm_config.h" +#include +#include +#include + +enum { + COMM_CLIENT_STATUS_CALLBACK_FLAG_NONE = 0, +}; + +typedef struct comm_client comm_client; +typedef void (*status_cb) (void *cb_data, const char *req_id, + const char *pkg_type, const char *pkg_name, + const char *key, const char *val); + +API comm_client *comm_client_new(void); +API int comm_client_free(comm_client *cc); + +API int comm_client_request(comm_client *cc, const char *req_id, + const int req_type, const char *pkg_type, + const char *pkg_name, const char *args, + const char *cookie, int is_block); + +API int comm_client_set_status_callback(comm_client *cc, status_cb cb, + void *cb_data); + +#endif /* __COMM_CLIENT_H__ */ diff --git a/comm/comm_client_dbus.c b/comm/comm_client_dbus.c new file mode 100755 index 0000000..2bb65d6 --- /dev/null +++ b/comm/comm_client_dbus.c @@ -0,0 +1,355 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + + + + + +/* + * comm_client_dbus.c + * comm_client library using pure dbus + * (dbus-glib is used only to register into g_main_loop) + */ + +#include "comm_config.h" +#include "comm_client.h" +#include +#include +#include +#include + +/******************* + * ADT description + */ + +/* Storing status_cb */ +struct signal_callback_data { + status_cb cb; + void *cb_data; +}; + +/* comm_client ADT */ +struct comm_client { + DBusConnection *conn; + struct signal_callback_data *sig_cb_data; +}; + +/********************************* + * Internal function description + */ + +/** + * signal handler filter + * Filter signal, and run user callback + */ +DBusHandlerResult +_on_signal_handle_filter(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + DBusError err; + + dbg("start function"); + + dbus_error_init(&err); + + /* Values to be received by signal */ + char *req_id = NULL; + char *pkg_type = NULL; + char *pkg_name = NULL; + char *key = NULL; + char *val = NULL; + + /* User's signal handler */ + struct signal_callback_data *sig_cb_data; + sig_cb_data = (struct signal_callback_data *)user_data; + + /* Signal check */ + if (dbus_message_is_signal(msg, + COMM_STATUS_BROADCAST_DBUS_INTERFACE, + COMM_STATUS_BROADCAST_SIGNAL_STATUS)) { + + /* Signal type check */ + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_STRING, &req_id, + DBUS_TYPE_STRING, &pkg_type, + DBUS_TYPE_STRING, &pkg_name, + DBUS_TYPE_STRING, &key, + DBUS_TYPE_STRING, &val, + DBUS_TYPE_INVALID)) { + /* Got signal! */ + dbg("Got signal: %s / %s / %s / %s / %s", req_id, + pkg_type, pkg_name, key, val); + + /* Run signal callback if exist */ + if (sig_cb_data && sig_cb_data->cb) { + sig_cb_data->cb(sig_cb_data->cb_data, req_id, + pkg_type, pkg_name, key, val); + + dbg("callback function is end"); + } + + dbg("handled signal. exit function"); + return DBUS_HANDLER_RESULT_HANDLED; + } + } + dbg("Didn't handled signal. anyway exit function"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +/** + * signal_callback_data free function + * Just free it! + */ +void _free_sig_cb_data(void *memory) +{ + struct signal_callback_data *sig_cb_data; + sig_cb_data = (struct signal_callback_data *)memory; + if (!sig_cb_data) + return; + free(sig_cb_data); +} + +/******************* + * API description + */ + +/** + * Create a new comm_client object + */ +comm_client *comm_client_new(void) +{ + DBusError err; + comm_client *cc = NULL; + + /* Allocate memory for ADT:comm_client */ + cc = calloc(1, sizeof(comm_client)); + if (NULL == cc) { + ERR("No memory"); + goto ERROR_CLEANUP; + } + + /* Connect to dbus */ + dbus_error_init(&err); + cc->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + ERR("dbus connection error (%s)", err.message); + dbus_error_free(&err); + goto ERROR_CLEANUP; + } + if (NULL == cc->conn) { + ERR("dbus connection is not set, even dbus error isn't raised"); + goto ERROR_CLEANUP; + } + + /* TODO: requesting name for dbus is needed? */ + + /* Register my connection to g_main_loop (with default context) */ + dbus_connection_setup_with_g_main(cc->conn, NULL); + + return cc; + + ERROR_CLEANUP: + if (cc) + free(cc); + return NULL; +} + +/** + * Free comm_client object + */ +int comm_client_free(comm_client *cc) +{ + if (!cc) + return -1; + if (!(cc->conn) || !dbus_connection_get_is_connected(cc->conn)) { + ERR("Invalid dbus connection"); + return -2; + } + + /* Cleanup ADT */ + /* flush remaining buffer: blocking mode */ + dbus_connection_flush(cc->conn); + + /* Free signal filter if signal callback is exist */ + if (cc->sig_cb_data) { + dbus_connection_remove_filter(cc->conn, + _on_signal_handle_filter, + cc->sig_cb_data); + /* TODO: Is it needed to free cc->sig_cb_data here? */ + /* _free_sig_cb_data(cc->sig_cb_data); */ + } + + dbus_connection_unref(cc->conn); + + free(cc); + + return 0; +} + +/** + * Request a message + */ +int +comm_client_request( + comm_client *cc, + const char *req_id, + const int req_type, + const char *pkg_type, + const char *pkg_name, + const char *args, + const char *cookie, + int is_block) +{ + DBusMessage *msg = NULL; + int r = COMM_RET_ERROR; /* Default return */ + + if (!cc) + return COMM_RET_ERROR; + + /* Create a dbus message */ + msg = dbus_message_new_method_call(COMM_PKG_MGR_DBUS_SERVICE, + COMM_PKG_MGR_DBUS_PATH, + COMM_PKG_MGR_DBUS_INTERFACE, + COMM_PKG_MGR_METHOD_REQUEST); + if (NULL == msg) { + r = COMM_RET_NOMEM; + goto ERROR_CLEANUP; + } + + /* Assign default values if NULL (NULL is not allowed) */ + if (NULL == req_id) + req_id = "tmp_reqid"; + if (NULL == pkg_type) + pkg_type = "none"; + if (NULL == pkg_name) + pkg_name = ""; + if (NULL == args) + args = ""; + if (NULL == cookie) + cookie = ""; + + /* Append arguments */ + if (!dbus_message_append_args(msg, + DBUS_TYPE_STRING, &req_id, + DBUS_TYPE_INT32, &req_type, + DBUS_TYPE_STRING, &pkg_type, + DBUS_TYPE_STRING, &pkg_name, + DBUS_TYPE_STRING, &args, + DBUS_TYPE_STRING, &cookie, + DBUS_TYPE_INVALID)) { + r = COMM_RET_NOMEM; + goto ERROR_CLEANUP; + } + + /* Send message */ + if (is_block == 1){ + if(!dbus_connection_send_with_reply_and_block(cc->conn, msg, + 1200, NULL)) { + r = COMM_RET_NOMEM; + goto ERROR_CLEANUP; + } + } else { + if (!dbus_connection_send(cc->conn, msg, NULL)) { + r = COMM_RET_NOMEM; + goto ERROR_CLEANUP; + } + } + dbus_connection_flush(cc->conn); + + /* Cleanup and return */ + dbus_message_unref(msg); + /* NOTE: It is not needed to free DBusMessageIter. */ + + return 0; + + ERROR_CLEANUP: + if (COMM_RET_NOMEM == r) + ERR("No memory!"); + else + ERR("General error!"); + + if (msg) + dbus_message_unref(msg); + + return r; +} + +/** + * Set a callback for status signal + */ +int +comm_client_set_status_callback(comm_client *cc, status_cb cb, void *cb_data) +{ + DBusError err; + char buf[256] = { 0, }; + int r = COMM_RET_ERROR; + + dbus_error_init(&err); + + if (NULL == cc) + goto ERROR_CLEANUP; + + /* Add a rule for signal */ + snprintf(buf, 255, "type='signal',interface='%s'", + COMM_STATUS_BROADCAST_DBUS_INTERFACE); + dbus_bus_add_match(cc->conn, buf, &err); + if (dbus_error_is_set(&err)) { + ERR("dbus error:%s", err.message); + r = COMM_RET_ERROR; + goto ERROR_CLEANUP; + } + + /* If previous signal handler is set already, remove filter first */ + if (cc->sig_cb_data) { + dbus_connection_remove_filter(cc->conn, + _on_signal_handle_filter, + cc->sig_cb_data); + /* TODO: Is it needed to free cc->sig_cb_data here? */ + } + + /* Create new sig_cb_data */ + cc->sig_cb_data = calloc(1, sizeof(struct signal_callback_data)); + (cc->sig_cb_data)->cb = cb; + (cc->sig_cb_data)->cb_data = cb_data; + + /* Add signal filter */ + if (!dbus_connection_add_filter(cc->conn, + _on_signal_handle_filter, + cc->sig_cb_data, _free_sig_cb_data)) { + r = COMM_RET_NOMEM; + goto ERROR_CLEANUP; + } + + /* Cleanup and return */ + dbus_error_free(&err); + return COMM_RET_OK; + + ERROR_CLEANUP: + if (COMM_RET_NOMEM == r) + ERR("No memory"); + else + ERR("General error"); + + dbus_error_free(&err); + return r; +} + diff --git a/comm/comm_config.h b/comm/comm_config.h new file mode 100755 index 0000000..704bc46 --- /dev/null +++ b/comm/comm_config.h @@ -0,0 +1,124 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __COMM_CONFIG_H__ +#define __COMM_CONFIG_H__ + +#include /* for NULL */ +#include + +/* API export macro */ +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +/* Debug message macro */ +#define USE_DLOG 1 /* Use dlog! */ + +#ifndef NDEBUG +#ifdef USE_DLOG +#define LOG_TAG "PKGMGR" +#include +#define dbg(fmtstr, args...) \ + do { SLOGI("[comm]%s:%d:%s(): " \ + fmtstr "\n", basename(__FILE__), __LINE__, __func__, ##args); } \ + while (0) +#define ERR(fmtstr, args...) \ + do { SLOGE("[comm]%s:%d:%s(): " \ + fmtstr "\n", basename(__FILE__), __LINE__, __func__, ##args); } \ + while (0) +#else +#include +#include +#include +#define dbg(fmtstr, args...) \ + do { + fprintf(stdout, "[%d:comm]%s:%d:%s(): " \ + fmtstr "\n", getpid(),\ + basename(__FILE__), __LINE__, __func__, ##args);\ + } while (0) + +#define ERR(fmtstr, args...) \ + do { + fprintf(stderr, "[%d:comm]%s:%d:%s(): " \ + fmtstr "\n", getpid(),\ + basename(__FILE__), __LINE__, __func__, ##args);\ + } while (0) +#endif /* USE_DLOG */ +#else +#define dbg(fmtstr, args...) +#endif + +/* from comm_pkg_mgr.xml + */ +#define COMM_PKG_MGR_DBUS_SERVICE "org.tizen.slp.pkgmgr" +#define COMM_PKG_MGR_DBUS_PATH "/org/tizen/slp/pkgmgr" +#define COMM_PKG_MGR_DBUS_INTERFACE "org.tizen.slp.pkgmgr" +#define COMM_PKG_MGR_METHOD_REQUEST "Request" +#define COMM_PKG_MGR_METHOD_ECHO_STRING "EchoString" + +/* from comm_status_broadcast + */ +#define COMM_STATUS_BROADCAST_DBUS_SERVICE_PREFIX \ + "org.tizen.slp.pkgmgr_status" +#define COMM_STATUS_BROADCAST_DBUS_PATH \ + "/org/tizen/slp/pkgmgr_status" +#define COMM_STATUS_BROADCAST_DBUS_INTERFACE \ + "org.tizen.slp.pkgmgr_status" +#define COMM_STATUS_BROADCAST_SIGNAL_STATUS "status" + +/******** + * enums + ********/ + +/* req_type */ +enum { + /* to installer */ + COMM_REQ_TO_INSTALLER = 1, + + /* to activator */ + COMM_REQ_TO_ACTIVATOR, + + /* to clearer */ + COMM_REQ_TO_CLEARER, + + /* cancel job */ + COMM_REQ_CANCEL, + + COMM_REQ_MAX_SENTINEL +}; + +/* return value */ +enum { + COMM_RET_NOMEM = -2, + COMM_RET_ERROR = -1, + COMM_RET_OK = 0, + COMM_RET_QUEUED, + + COMM_RET_MAX_SENTINEL +}; + +#endif /* __COMM_CONFIG_H__ */ diff --git a/comm/comm_pkg_mgr.xml b/comm/comm_pkg_mgr.xml new file mode 100644 index 0000000..915cb76 --- /dev/null +++ b/comm/comm_pkg_mgr.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/comm/comm_pkg_mgr_server.c b/comm/comm_pkg_mgr_server.c new file mode 100755 index 0000000..6ad55d5 --- /dev/null +++ b/comm/comm_pkg_mgr_server.c @@ -0,0 +1,203 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_config.h" +#include +#include +#include +#include + +#include "comm_pkg_mgr_server.h" + +/* object class def: do nothing on this */ +struct PkgMgrObjectClass { + GObjectClass parent_class; +}; + +/* object def: has connection */ +struct PkgMgrObject { + GObject parent; + + DBusGConnection *bus; + + request_callback req_cb; + void *req_cb_data; +}; + +#define PKG_MGR_OBJECT(object) \ +(G_TYPE_CHECK_INSTANCE_CAST((object), \ + PKG_MGR_TYPE_OBJECT, PkgMgrObject)) +#define PKG_MGR_OBJECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + PKG_MGR_TYPE_OBJECT, PkgMgrObjectClass)) +#define PKG_MGR_IS_OBJECT(object) \ + (G_TYPE_CHECK_INSTANCE_TYPE((object), \ + PKG_MGR_TYPE_OBJECT)) +#define PKG_MGR_IS_OBJECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), \ + PKG_MGR_TYPE_OBJECT)) +#define PKG_MGR_OBJECT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + PKG_MGR_TYPE_OBJECT, PkgMgrObjectClass)) + +/* Macro that creates follwoing functions automatically; + * - pkgmgr_object_get_type() + * - pkgmgr_object_parent_class + */ +G_DEFINE_TYPE(PkgMgrObject, pkg_mgr_object, G_TYPE_OBJECT); + +/* Method declarations + * Used for binding stub. + */ +GCallback pkgmgr_request(PkgMgrObject *obj, const gchar *req_id, + const gint req_type, const gchar *pkg_type, + const gchar *pkg_name, const gchar *args, + const gchar *cookie, gint *ret, GError *err); + +/* Include stub header */ +#include "comm_pkg_mgr_server_dbus_bindings.h" + +static void pkg_mgr_object_finalize(GObject *self); +static void pkg_mgr_object_init(PkgMgrObject *obj); +static void pkg_mgr_object_class_init(PkgMgrObjectClass *klass); +static void pkg_mgr_object_init(PkgMgrObject *obj) +{ + dbg("called"); + g_assert(NULL != obj); + + GError *err = NULL; + + /* Establish dbus session */ + obj->bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err); + if (NULL == obj->bus) { + dbg("Failed to open connection to dbus: %s", err->message); + return; + } + + /* Create a proxy to resgister, connecting dbus daemon */ + DBusGProxy *proxy = NULL; + proxy = dbus_g_proxy_new_for_name(obj->bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); + if (NULL == proxy) { + dbg("Failed to get a proxy"); + return; + } + /* Register service name + * NOTE: refer to + http://dbus.freedesktop.org/doc/dbus-specification.html + */ + guint result; + if (!dbus_g_proxy_call(proxy, "RequestName", &err, + /* input vars */ + G_TYPE_STRING, COMM_PKG_MGR_DBUS_SERVICE, + /* service name */ + G_TYPE_UINT, 0, /* default flag */ + G_TYPE_INVALID, + /* output vars */ + G_TYPE_UINT, &result, G_TYPE_INVALID)) { + g_printerr("dbus RequestName RPC failed %s %d", err->message, TRUE); + return; + } + dbg("RequestName returns: %d", result); + + dbus_g_connection_register_g_object(obj->bus, + COMM_PKG_MGR_DBUS_PATH, + G_OBJECT(obj)); + dbg("Ready to serve requests"); + + g_object_unref(proxy); + + dbg("done"); +} + +static void pkg_mgr_object_class_init(PkgMgrObjectClass *klass) +{ + dbg("called"); + + g_assert(NULL != klass); + + dbus_g_object_type_install_info(PKG_MGR_TYPE_OBJECT, + &dbus_glib_pkgmgr_object_info); + + dbg("done"); +} + +static void pkg_mgr_object_finalize(GObject *self) +{ + /* PkgMgrObjectClass *klass = (PkgMgrObjectClass *) G_OBJECT_CLASS(self); */ + + /* Call parent's finalize function + * 'server_object_parent_class' comes from G_DEFINE_TYPE() macro. + */ + G_OBJECT_CLASS(pkg_mgr_object_parent_class)->finalize(self); +} + +/* dbus-glib methods */ + +GCallback +pkgmgr_request(PkgMgrObject *obj, + const gchar *req_id, + const gint req_type, + const gchar *pkg_type, + const gchar *pkg_name, + const gchar *args, + const gchar *cookie, gint *ret, GError *err) +{ + dbg("Called"); + *ret = COMM_RET_OK; /* TODO: fix this! */ + + /* TODO: Add business logic + * - add to queue, or remove from queue + * */ + + if (obj->req_cb) { + dbg("Call request callback(obj, %s, %d, %s, %s, %s, *ret)", + req_id, req_type, pkg_type, pkg_name, args); + obj->req_cb(obj->req_cb_data, req_id, req_type, pkg_type, + pkg_name, args, cookie, ret); + } else { + dbg("Attempt to call request callback," + " but request callback is not set. Do nothing.\n" + "Use pkg_mgr_set_request_callback()" + " to register your callback."); + } + + return (GCallback) TRUE; +} + +/* Other APIs + */ + +/** + * Set request callback function + */ +void pkg_mgr_set_request_callback(PkgMgrObject *obj, request_callback req_cb, + void *cb_data) +{ + obj->req_cb = req_cb; + obj->req_cb_data = cb_data; +} diff --git a/comm/comm_pkg_mgr_server.h b/comm/comm_pkg_mgr_server.h new file mode 100755 index 0000000..9bb961c --- /dev/null +++ b/comm/comm_pkg_mgr_server.h @@ -0,0 +1,49 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __COMM_PKG_MGR_SERVER_H__ +#define __COMM_PKG_MGR_SERVER_H__ + +#include "comm_config.h" +#include + +typedef struct PkgMgrObjectClass PkgMgrObjectClass; +typedef struct PkgMgrObject PkgMgrObject; + +/* For returning server object's GType. + * I don't use this. Just forward declaration for G_DEFINE_TYPE() macro. */ +API GType pkg_mgr_object_get_type(void); +#define PKG_MGR_TYPE_OBJECT (pkg_mgr_object_get_type()) + +typedef void (*request_callback) (void *cb_data, const char *req_id, + const int req_type, const char *pkg_type, + const char *pkg_name, const char *args, + const char *cookie, int *ret); + +API void pkg_mgr_set_request_callback(PkgMgrObject *obj, + request_callback req_cb, void *cb_data); + +#endif /* __COMM_PKG_MGR_SERVER_H__ */ diff --git a/comm/comm_socket.c b/comm/comm_socket.c new file mode 100755 index 0000000..f10f460 --- /dev/null +++ b/comm/comm_socket.c @@ -0,0 +1,215 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_socket.h" + +#include + +#include +#include +#include +#include +#include +#include +#define __USE_GNU +#include +#include /* for sockaddr_un */ + +#define COMM_SOCKET_SERVER_SOCK_PATH_PREFIX "/tmp/comm_socket_" + +#define CHK_CS_RET(r) \ + do { if (NULL == cs) return (r); } while (0) + +struct comm_socket { + int sockfd; +}; + +static int _get_new_socket(void) +{ + int fd = -1; + fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + if (EINVAL == errno) { + /* Try again, without SOCK_CLOEXEC option */ + fd = socket(AF_LOCAL, SOCK_STREAM, 0); + if (fd < 0) { + return -EINVAL; + } + } else { + return -errno; + } + } + + return fd; +} + +static void _set_sockaddr_un(struct sockaddr_un *saddr, const char *sock_path) +{ + saddr->sun_family = AF_UNIX; + snprintf(saddr->sun_path, UNIX_PATH_MAX, sock_path); +} + +static const char *_create_server_sock_path(void) +{ + static char sock_path[UNIX_PATH_MAX]; + + snprintf(sock_path, UNIX_PATH_MAX, "%s_%d", + COMM_SOCKET_SERVER_SOCK_PATH_PREFIX, getpid()); + unlink(sock_path); + return sock_path; +} + +comm_socket *_comm_socket_new(void) +{ + comm_socket *cs; + + cs = (comm_socket *) calloc(1, sizeof(struct comm_socket)); + + return cs; +} + +int _comm_socket_free(comm_socket *cs) +{ + CHK_CS_RET(-EINVAL); + free(cs); + return 0; +} + +int _comm_socket_create_server(comm_socket *cs, const char *sock_path) +{ + CHK_CS_RET(-EINVAL); + if (cs->sockfd) + return -EISCONN; + + + int fd = -1; + fd = _get_new_socket(); + if (fd < 0) + return fd; + + struct sockaddr_un saddr; + _set_sockaddr_un(&saddr, _create_server_sock_path()); + + /* bind */ + if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr))) { + return -errno; + } + + /* chmod */ + if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + return -errno; + } + + /* listen */ + if (-1 == listen(fd, 10)) { + return -errno; + } + + cs->sockfd = fd; + + return 0; +} + +static gboolean _read_socket(GIOChannel *source, GIOCondition io) +{ + return FALSE; +} + +int comm_socket_server_add_wait_to_thread(comm_socket *cs, void *cb, + void *cb_data, GMainContext *context) +{ + CHK_CS_RET(-EINVAL); + if (!cs->sockfd) + return -ENOTCONN; + + GIOChannel *channel; + GSource *src; + + channel = g_io_channel_unix_new(cs->sockfd); + src = g_io_create_watch(channel, G_IO_IN); + g_source_set_callback(src, (GSourceFunc) _read_socket, NULL, NULL); + g_source_attach(src, context); + g_source_unref(src); + + return 0; +} + +int comm_socket_connect_to_server(comm_socket *cs, + const char *server_sock_path) +{ + CHK_CS_RET(-EINVAL); + if (cs->sockfd) + return -EISCONN; + + int r; + + int fd = -1; + fd = _get_new_socket(); + if (fd < 0) + return fd; + + /* Try to connect to server_sock_path */ + struct sockaddr_un saddr; + _set_sockaddr_un(&saddr, server_sock_path); + + r = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); + if (0 != r) { + close(fd); + return -r; + } + + /* remember sockfd */ + cs->sockfd = fd; + + return 0; +} + +int _comm_socket_disconnect(comm_socket *cs) +{ + CHK_CS_RET(-EINVAL); + if (!cs->sockfd) + return -EBADFD; + + if (close(cs->sockfd)) + return -errno; + + cs->sockfd = 0; + + return 0; +} + +int _comm_socket_send(comm_socket *cs, void **data, int *datasize) +{ + CHK_CS_RET(-EINVAL); + return 0; +} + +int _comm_socket_recv(comm_socket *cs, void *data, int datasize) +{ + CHK_CS_RET(-EINVAL); + return 0; +} + diff --git a/comm/comm_socket.h b/comm/comm_socket.h new file mode 100755 index 0000000..0d9e840 --- /dev/null +++ b/comm/comm_socket.h @@ -0,0 +1,35 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + + + + + +typedef struct comm_socket comm_socket; + +comm_socket *_comm_socket_new(void); +int _comm_socket_free(comm_socket *csc); +int _comm_socket_connect(comm_socket *csc, const char *server_sock_path); +int _comm_socket_disconnect(comm_socket *csc); +int _comm_socket_create_server(comm_socket *cs, const char *sock_path); +int _comm_socket_send(comm_socket *csc, void **data, int *datasize); +int _comm_socket_recv(comm_socket *csc, void *data, int datasize); diff --git a/comm/comm_socket_client.c b/comm/comm_socket_client.c new file mode 100755 index 0000000..9423dbf --- /dev/null +++ b/comm/comm_socket_client.c @@ -0,0 +1,66 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_socket_client.h" + +#include +#include + +#define CHK_CSC_RET(r) \ + do { if (NULL == csc) return (r); } while (0) + +struct comm_socket_client { + int sockfd; +}; + +comm_socket_client *_comm_socket_client_new(const char *server_sock_path) +{ + int fd = -1; + fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + if (EINVAL == errno) { + /* Try again, without SOCK_CLOEXEC option */ + fd = socket(AF_LOCAL, SOCK_STREAM, 0); + if (fd < 0) { + return NULL; + } + } else { + return NULL; + } + } + + /* Try to connect to server_sock_path */ + struct sockaddr_un saddr = { 0, }; + +} + +int _comm_socket_client_free(comm_socket_client *csc) +{ + CHK_CSC_RET(-EINVAL); + free(csc); + return 0; +} + diff --git a/comm/comm_socket_client.h b/comm/comm_socket_client.h new file mode 100755 index 0000000..f996672 --- /dev/null +++ b/comm/comm_socket_client.h @@ -0,0 +1,30 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + + + + + +typedef struct comm_socket_client comm_socket_client; + +comm_socket_client *_comm_socket_client_new(const char *server_sock_path); +int _comm_socket_client_free(comm_socket_client *csc); diff --git a/comm/comm_status_broadcast.xml b/comm/comm_status_broadcast.xml new file mode 100644 index 0000000..2dbae94 --- /dev/null +++ b/comm/comm_status_broadcast.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/comm/comm_status_broadcast_server.c b/comm/comm_status_broadcast_server.c new file mode 100755 index 0000000..22aa7d2 --- /dev/null +++ b/comm/comm_status_broadcast_server.c @@ -0,0 +1,190 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_config.h" +#include +#include +#include + +#include "comm_status_broadcast_server.h" + +/*************************** + * dbus-glib API for server + ***************************/ +#include +#include + +/* object class def: do nothing on this */ +struct StatusBroadcastObjectClass { + GObjectClass parent_class; + + guint signal; +}; + +/* object def: has connection */ +struct StatusBroadcastObject { + GObject parent; + + DBusGConnection *bus; + char *dbus_service_name; +}; + +#define STATUS_BROADCAST_OBJECT(object) \ +(G_TYPE_CHECK_INSTANCE_CAST((object), \ + STATUS_BROADCAST_TYPE_OBJECT, StatusBroadcastObject)) +#define STATUS_BROADCAST_OBJECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + STATUS_BROADCAST_TYPE_OBJECT, StatusBroadcastObjectClass)) +#define STATUS_BROADCAST_IS_OBJECT(object) \ + (G_TYPE_CHECK_INSTANCE_TYPE((object), \ + STATUS_BROADCAST_TYPE_OBJECT)) +#define STATUS_BROADCAST_IS_OBJECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), \ + STATUS_BROADCAST_TYPE_OBJECT)) +#define STATUS_BROADCAST_OBJECT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + STATUS_BROADCAST_TYPE_OBJECT, StatusBroadcastObjectClass)) + +/* Macro that creates follwoing functions automatically; + * - status_broadcast_object_get_type() + * - status_broadcast_object_parent_class + */ +G_DEFINE_TYPE(StatusBroadcastObject, status_broadcast_object, G_TYPE_OBJECT); + +/* method/signal declarations + * Used for binding stub. + */ + +/* Include stub header */ +#include "comm_status_broadcast_server_dbus_bindings.h" + +static void +__status_broadcast_object_class_init(StatusBroadcastObjectClass *klass); +static void __status_broadcast_object_init(StatusBroadcastObject *obj); +static void __status_broadcast_object_finalize(GObject *self); + +static void +__status_broadcast_object_class_init(StatusBroadcastObjectClass *klass) +{ + dbg("called"); + + g_assert(NULL != klass); + + klass->signal = g_signal_new(COMM_STATUS_BROADCAST_SIGNAL_STATUS, + G_OBJECT_CLASS_TYPE(klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 3, + G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING); + + dbus_g_object_type_install_info(STATUS_BROADCAST_TYPE_OBJECT, + &dbus_glib_status_broadcast_object_info); + + dbg("done"); +} + +static void __status_broadcast_object_init(StatusBroadcastObject *obj) +{ + dbg("called"); + g_assert(NULL != obj); + + GError *err = NULL; + + /* Establish dbus session */ + obj->bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err); + if (NULL == obj->bus) { + dbg("Failed to open connection to dbus: %s", err->message); + return; + } + + /* Create a proxy to resgister, connecting dbus daemon */ + DBusGProxy *proxy = NULL; + proxy = dbus_g_proxy_new_for_name(obj->bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); + if (NULL == proxy) { + dbg("Failed to get a proxy"); + return; + } + /* Register service name + * NOTE: refer to + http://dbus.freedesktop.org/doc/dbus-specification.html + */ + + guint result; + if (!dbus_g_proxy_call(proxy, "RequestName", &err, + /* input vars */ + G_TYPE_STRING, COMM_STATUS_BROADCAST_DBUS_SERVICE_PREFIX, + /* service name */ + G_TYPE_UINT, 0, /* default flag */ + G_TYPE_INVALID, + /* output vars */ + G_TYPE_UINT, &result, G_TYPE_INVALID)) { + g_printerr("dbus RequestName RPC failed", err->message, TRUE); + return; + } + dbg("RequestName returns: %d", result); + + dbus_g_connection_register_g_object(obj->bus, + COMM_STATUS_BROADCAST_DBUS_PATH, + G_OBJECT(obj)); + dbg("Ready to serve requests"); + + g_object_unref(proxy); + + dbg("done"); +} + +static void __status_broadcast_object_finalize(GObject *self) +{ + StatusBroadcastObjectClass *klass = + (StatusBroadcastObjectClass *) G_OBJECT_CLASS(self); + + /* Call parent's finalize function + * 'server_object_parent_class' comes from G_DEFINE_TYPE() macro. + */ + G_OBJECT_CLASS(status_broadcast_object_parent_class)->finalize(self); +} + +/* dbus-glib methods/signals */ + +void +status_broadcast_emit_status(StatusBroadcastObject *obj, + const char *pkg, const char *key, const char *val) +{ + StatusBroadcastObjectClass *klass; + klass = STATUS_BROADCAST_OBJECT_GET_CLASS(obj); + + dbg("Send signal: %s/%s/%s", pkg, key, val); + g_signal_emit(obj, klass->signal, 0, pkg, key, val); + +} + diff --git a/comm/comm_status_broadcast_server.h b/comm/comm_status_broadcast_server.h new file mode 100755 index 0000000..2c747d0 --- /dev/null +++ b/comm/comm_status_broadcast_server.h @@ -0,0 +1,42 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __COMM_STATUS_BROADCAST_SERVER_H__ +#define __COMM_STATUS_BROADCAST_SERVER_H__ + +#include "comm_config.h" +#include + +/* pure dbus api */ +API DBusConnection *comm_status_broadcast_server_connect(void); +API void comm_status_broadcast_server_send_signal(DBusConnection *conn, + const char *req_id, + const char *pkg_type, + const char *pkg_name, + const char *key, + const char *val); +API void comm_status_broadcast_server_disconnect(DBusConnection *conn); +#endif /* __COMM_STATUS_BROADCAST_SERVER_H__ */ diff --git a/comm/comm_status_broadcast_server_dbus.c b/comm/comm_status_broadcast_server_dbus.c new file mode 100755 index 0000000..04d7f89 --- /dev/null +++ b/comm/comm_status_broadcast_server_dbus.c @@ -0,0 +1,114 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_config.h" +#include "comm_status_broadcast_server.h" +#include + +/******************************************** + * pure dbus signal service for internal use + ********************************************/ + +API DBusConnection *comm_status_broadcast_server_connect(void) +{ + DBusError err; + DBusConnection *conn; + + dbus_error_init(&err); + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + dbg("Connection error: %s", err.message); + dbus_error_free(&err); + } + dbus_error_free(&err); + if (NULL == conn) + exit(1); + dbus_bus_request_name(conn, + COMM_STATUS_BROADCAST_DBUS_SERVICE_PREFIX, + DBUS_NAME_FLAG_ALLOW_REPLACEMENT, &err); + if (dbus_error_is_set(&err)) { + dbg("Failed to request name: %s", err.message); + dbus_error_free(&err); + exit(1); + } + + return conn; +} + +API void +comm_status_broadcast_server_send_signal(DBusConnection *conn, + const char *req_id, + const char *pkg_type, + const char *pkg_name, const char *key, + const char *val) +{ + dbus_uint32_t serial = 0; + DBusMessage *msg; + DBusMessageIter args; + + const char *values[] = { + req_id, + pkg_type, + pkg_name, + key, + val + }; + int i; + + msg = dbus_message_new_signal(COMM_STATUS_BROADCAST_DBUS_PATH, + COMM_STATUS_BROADCAST_DBUS_INTERFACE, + COMM_STATUS_BROADCAST_SIGNAL_STATUS); + if (NULL == msg) { + dbg("msg NULL"); + exit(1); + } + + dbus_message_iter_init_append(msg, &args); + + for (i = 0; i < 5; i++) { + if (!dbus_message_iter_append_basic + (&args, DBUS_TYPE_STRING, &(values[i]))) { + dbg("dbus_message_iter_append_basic failed:" + " Out of memory"); + exit(1); + } + } + if (!dbus_connection_send(conn, msg, &serial)) { + dbg("dbus_connection_send failed: Out of memory"); + exit(1); + } + dbus_connection_flush(conn); + dbus_message_unref(msg); +} + +API void comm_status_broadcast_server_disconnect(DBusConnection *conn) +{ + if (!conn) + return; + dbus_connection_unref(conn); +} + diff --git a/comm/comm_status_broadcast_signal_marshaller.list b/comm/comm_status_broadcast_signal_marshaller.list new file mode 100644 index 0000000..1c50753 --- /dev/null +++ b/comm/comm_status_broadcast_signal_marshaller.list @@ -0,0 +1,2 @@ +VOID:STRING,STRING,STRING,STRING,STRING + diff --git a/comm/error_report.h b/comm/error_report.h new file mode 100755 index 0000000..c136e42 --- /dev/null +++ b/comm/error_report.h @@ -0,0 +1,45 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __ERROR_REPORT_H__ +#define __ERROR_REPORT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error reporting: kernel style */ +#include +#define MAX_ERRNO 4095 +#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) +static inline void *ERR_PTR(long error) +{ + return (void *)error; +} +#ifdef __cplusplus +} +#endif +#endif /* __ERROR_REPORT_H__ */ diff --git a/comm/pkgmgr-installer-client.pc.in b/comm/pkgmgr-installer-client.pc.in new file mode 100644 index 0000000..287a398 --- /dev/null +++ b/comm/pkgmgr-installer-client.pc.in @@ -0,0 +1,16 @@ +# +# Copyright (c) 2008 ~ 2010 Samsung Electronics Co., Ltd. +# All rights reserved. +# + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: package manager installer +Description: SLP package manager's installer library +Version: @VERSION@ +Requires: dbus-1 dbus-glib-1 +Libs: -L${libdir} -lpkgmgr_installer_client +Cflags: -I${includedir}/pkgmgr diff --git a/comm/pkgmgr-installer-status-broadcast-server.pc.in b/comm/pkgmgr-installer-status-broadcast-server.pc.in new file mode 100644 index 0000000..bfb2360 --- /dev/null +++ b/comm/pkgmgr-installer-status-broadcast-server.pc.in @@ -0,0 +1,16 @@ +# +# Copyright (c) 2008 ~ 2010 Samsung Electronics Co., Ltd. +# All rights reserved. +# + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: package manager installer +Description: SLP package manager's installer library +Version: @VERSION@ +Requires: dbus-1 dbus-glib-1 +Libs: -L${libdir} -lpkgmgr_installer_status_broadcast_server +Cflags: -I${includedir}/pkgmgr diff --git a/comm/pkgmgr-installer.pc.in b/comm/pkgmgr-installer.pc.in new file mode 100755 index 0000000..88a6200 --- /dev/null +++ b/comm/pkgmgr-installer.pc.in @@ -0,0 +1,16 @@ +# +# Copyright (c) 2008 ~ 2010 Samsung Electronics Co., Ltd. +# All rights reserved. +# + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: package manager installer library +Description: SLP package manager's installer lib for each backends +Version: @VERSION@ +Requires: pkgmgr-installer-status-broadcast-server +Libs: -L${libdir} -lpkgmgr_installer +Cflags: -I${includedir}/pkgmgr diff --git a/comm/pkgmgr_installer.c b/comm/pkgmgr_installer.c new file mode 100755 index 0000000..c1fc6ec --- /dev/null +++ b/comm/pkgmgr_installer.c @@ -0,0 +1,277 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "pkgmgr_installer.h" +#include "pkgmgr_installer_config.h" + +#include "comm_config.h" +#include "comm_socket.h" +#include "comm_status_broadcast_server.h" +#include "error_report.h" + +#include +#include +#include + +#define MAX_STRLEN 512 +#define CHK_PI_RET(r) \ + do { if (NULL == pi) return (r); } while (0) + +/* ADT */ +struct pkgmgr_installer { + int request_type; + int quiet; + char *pkgmgr_info; + char *session_id; + char *license_path; + char *quiet_socket_path; + + DBusConnection *conn; +}; +static int __pkgmgr_installer_receive_request_by_socket(pkgmgr_installer *pi); + +/* Internal func */ + +static int __pkgmgr_installer_receive_request_by_socket(pkgmgr_installer *pi) +{ + CHK_PI_RET(-EINVAL); + int r = 0; + +#ifdef USE_SOCKET + /* TODO: implement this */ + + /* Try to connect to socket */ + comm_socket_client *csc = + comm_socket_client_new(pi->quiet_socket_path); + if (!csc) + return -EINVAL; + + /* Receive request */ + char *req = NULL, *pkg_info = NULL; + if (0 != comm_socket_client_receive_request(csc, &req, &pkg_info)) { + r = -EINVAL; + goto CLEANUP_RET; + } + + /* Verify requester */ + + /* Set request value */ + + /* Cleanup */ + CLEANUP_RET: + if (csc) + comm_socket_client_free(csc); +#endif + + return r; +} + +/* API */ + +API pkgmgr_installer *pkgmgr_installer_new(void) +{ + pkgmgr_installer *pi = NULL; + pi = calloc(1, sizeof(struct pkgmgr_installer)); + if (NULL == pi) + return ERR_PTR(-ENOMEM); + + pi->request_type = PKGMGR_REQ_INVALID; + + return pi; +} + +API int pkgmgr_installer_free(pkgmgr_installer *pi) +{ + CHK_PI_RET(-EINVAL); + + /* free members */ + if (pi->pkgmgr_info) + free(pi->pkgmgr_info); + if (pi->session_id) + free(pi->session_id); + + if (pi->conn) + comm_status_broadcast_server_disconnect(pi->conn); + + free(pi); + + return 0; +} + +API int +pkgmgr_installer_receive_request(pkgmgr_installer *pi, + const int argc, char **argv) +{ + CHK_PI_RET(-EINVAL); + + int r = 0; + + /* Parse argv */ + optind = 1; /* Initialize optind to clear prev. index */ + int opt_idx = 0; + int c; + int mode = 0; + while (1) { + c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx); + /* printf("c=%d %c\n", c, c); //debug */ + if (-1 == c) + break; /* Parse is end */ + switch (c) { + case 'k': /* session id */ + if (pi->session_id) + free(pi->session_id); + pi->session_id = strndup(optarg, MAX_STRLEN); + break; + + case 'l': /* license path */ + if (pi->license_path) + free(pi->license_path); + pi->license_path = strndup(optarg, MAX_STRLEN); + break; + + case 'i': /* install */ + if (mode) { + r = -EINVAL; + goto RET; + } + mode = 'i'; + pi->request_type = PKGMGR_REQ_INSTALL; + if (pi->pkgmgr_info) + free(pi->pkgmgr_info); + pi->pkgmgr_info = strndup(optarg, MAX_STRLEN); + break; + + case 'd': /* uninstall */ + if (mode) { + r = -EINVAL; + goto RET; + } + mode = 'd'; + pi->request_type = PKGMGR_REQ_UNINSTALL; + if (pi->pkgmgr_info) + free(pi->pkgmgr_info); + pi->pkgmgr_info = strndup(optarg, MAX_STRLEN); + break; + + + case 'c': /* clear */ + if (mode) { + r = -EINVAL; + goto RET; + } + mode = 'c'; + pi->request_type = PKGMGR_REQ_CLEAR; + if (pi->pkgmgr_info) + free(pi->pkgmgr_info); + pi->pkgmgr_info = strndup(optarg, MAX_STRLEN); + break; + + case 'r': /* recover */ + if (mode) { + r = -EINVAL; + goto RET; + } + mode = 'r'; + break; + + case 'q': /* quiet mode */ + /* if(mode) { r = -EINVAL; goto RET; } + mode = 'q'; */ + pi->quiet = 1; + /* pi->quiet_socket_path = strndup(optarg, MAX_STRLEN); + maximum 255 bytes + return + __pkgmgr_installer_receive_request_by_socket(pi); */ + + break; + + /* Otherwise */ + case '?': /* Not an option */ + break; + + case ':': /* */ + break; + + } + } + + /* quiet mode : get options from socket (to be impelemented) */ + + /* normal mode : get options from argv */ + + RET: + return r; +} + +API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi) +{ + CHK_PI_RET(PKGMGR_REQ_INVALID); + return pi->request_type; +} + +API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi) +{ + CHK_PI_RET(PKGMGR_REQ_INVALID); + return pi->pkgmgr_info; +} + +API const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi) +{ + CHK_PI_RET(PKGMGR_REQ_INVALID); + return pi->session_id; +} + +API const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi) +{ + CHK_PI_RET(PKGMGR_REQ_INVALID); + return pi->license_path; +} + +API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi) +{ + CHK_PI_RET(PKGMGR_REQ_INVALID); + return pi->quiet; +} + +API int +pkgmgr_installer_send_signal(pkgmgr_installer *pi, + const char *pkg_type, + const char *pkg_name, + const char *key, const char *val) +{ + int r = 0; + + if (!pi->conn) + pi->conn = comm_status_broadcast_server_connect(); + + char *sid = pi->session_id; + if (!sid) + sid = ""; + comm_status_broadcast_server_send_signal(pi->conn, sid, pkg_type, + pkg_name, key, val); + + return r; +} diff --git a/comm/pkgmgr_installer.h b/comm/pkgmgr_installer.h new file mode 100755 index 0000000..4579f47 --- /dev/null +++ b/comm/pkgmgr_installer.h @@ -0,0 +1,362 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __PKGMGR_INSTALLER_H__ +#define __PKGMGR_INSTALLER_H__ + +/** + * @file pkgmgr_installer.h + * @author Youmin Ha + * @version 0.1 + * @brief This file declares API of pkgmgr_installer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * pkgmgr_installer is an opaque type for an object + */ +typedef struct pkgmgr_installer pkgmgr_installer; + +/** + * Request type. + */ +enum { + PKGMGR_REQ_PERM = -1, + PKGMGR_REQ_INVALID = 0, + PKGMGR_REQ_INSTALL = 1, + PKGMGR_REQ_UNINSTALL = 2, + PKGMGR_REQ_CLEAR = 3, + PKGMGR_REQ_RECOVER = 4 +}; + +/** + * @brief Create a pkgmgr_installer object. + * @pre None + * @post pkgmgr_installer object must be freed. + * @see pkgmgr_installer_free + * @return pkgmgr_installer object + * @retval NULL on failure creating an object + * @remark None +@code +#include +pkgmgr_installer *pi = pkgmgr_installer_new(); +pkgmgr_installer_free(pi); +@endcode + */ +pkgmgr_installer *pkgmgr_installer_new(void); + +/** + @brief Free a pkgmgr_installer object + @pre pi must be a valid object. + @post None + @see pkgmgr_installer_new + @param[in] pi A pkgmgr_installer object + @return Operation result + @retval 0 on success + @retval -errno on error + @remark None + @code +#include +pkgmgr_installer *pi = pkgmgr_installer_new(); +pkgmgr_installer_free(pi); + @endcode + */ +int pkgmgr_installer_free(pkgmgr_installer *pi); + +/** + @brief Receive a request from argv + @pre None + @post pkgmgr_installer_get_*(), pkgmgr_installer_is_quiet() can be called. + @see pkgmgr_installer_get_request_type, pkgmgr_installer_get_request_info, pkgmgr_installer_get_session_id, pkgmgr_installer_is_quiet + @param[in] pi a pkgmgr_installer object + @param[in] argc argc from system + @param[in] argv argv from system + @return Operation result + @retval 0 on success + @retval -errno on failure + @remark None + @code +#include +int main(int argc, char **argv) +{ + pkgmgr_installer *pi; + int r; + + pi = pkgmgr_installer_new(); + int r = pkgmgr_installer_receive_request(pi, argc, argv); + pkgmgr_installer_free(pi); + + return 0; +} + @endcode + */ +int pkgmgr_installer_receive_request(pkgmgr_installer *pi, + const int argc, char **argv); + +/** + @brief Get request type + @pre pkgmgr_installer_receive_request() must be called. + @post None + @see pkgmgr_installer_receive_request + @param[in] pi pkgmgr_installer object + @return Request type (One of PKGMGR_REQ_* enum values) + @remark None + @code +int main(int argc, char **argv) +{ + pkgmgr_installer *pi; + int r = 0; + + pi = pkgmgr_installer_new(); + if(!pi) return -1; + if(pkgmgr_installer_receive_request(pi, argc, argv)) { + r = -1; + goto CLEANUP_RET; + } + + switch(pkgmgr_installer_get_request_type(pi)) { + case PKGMGR_REQ_PERM: + // Do error processing + break; + case PKGMGR_REQ_INVALID: + // Do error processing + r = -1; + break; + case PKGMGR_REQ_INSTALL: + // Do install processing + break; + case PKGMGR_REQ_UNINSTALL: + // Do uninstall processing + break; + case PKGMGR_REQ_RECOVER: + // Do recovere processing + break; + default: + goto CLEANUP_END; + } +CLEANUP_END: + pkgmgr_installer_free(pi); + + return r; +} + @endcode + */ +int pkgmgr_installer_get_request_type(pkgmgr_installer *pi); + +/** + @brief Get request info + @pre pkgmgr_installer_receive_request() must be called. + @post None + @see pkgmgr_installer_receive_request + @param[in] pi pkgmgr_installer object + @return Request info. When PKGMGR_REQ_INSTALL, this is a package file path to be installed. When PKGMGR_REQ_UNINSTALL, this is a package name to be uninstalled. + @retval NULL on function failure + @remark Returned string must not be modified. + @code +#include +int main(int argc, char **argv) +{ + pkgmgr_installer *pi; + int r = 0; + char *req_info = NULL; + + pi = pkgmgr_installer_new(); + if(!pi) return -1; + if(pkgmgr_installer_receive_request(pi, argc, argv)) { + r = -1; + goto CLEANUP_RET; + } + req_info = (char *) pkgmgr_installer_get_request_info(pi); + + // Do something... + + pkgmgr_installer_free(pi); + return r; +} + @endcode + */ +const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi); + +/** + @brief Get session ID for a certain session + @pre pkgmgr_installer_receive_request() must be called. + @post None + @see pkgmgr_installer_receive_request + @param[in] pi pkgmgr_installer object + @return A session ID + @retval NULL on function failure + @remark Returned string must not be modified. + @code +#include +int main(int argc, char **argv) +{ + pkgmgr_installer *pi; + int r = 0; + char *session_id = NULL; + + pi = pkgmgr_installer_new(); + if(!pi) return -1; + if(pkgmgr_installer_receive_request(pi, argc, argv)) { + r = -1; + goto CLEANUP_RET; + } + session_id = (char *) pkgmgr_installer_get_session_id(pi); + + // Do something... + + pkgmgr_installer_free(pi); + return r; +} +@endcode + */ +const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi); + +/** + @brief Get a license path + @pre pkgmgr_installer_receive_request() must be called. + @post None + @see pkgmgr_installer_receive_request + @param[in] pi pkgmgr_installer object + @return license path + @retval NULL on function failure + @remark Returned string must not be modified. + @code +#include +int main(int argc, char **argv) +{ + pkgmgr_installer *pi; + int r = 0; + char *license_path = NULL; + + pi = pkgmgr_installer_new(); + if(!pi) return -1; + if(pkgmgr_installer_receive_request(pi, argc, argv)) { + r = -1; + goto CLEANUP_RET; + } + session_id = (char *) pkgmgr_installer_get_license_path(pi); + + // Do something... + + pkgmgr_installer_free(pi); + return r; +} +@endcode + */ +const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi); + +/** + @brief Get if a request is with quite mode or not + @pre pkgmgr_installer_receive_request() must be called. + @post None + @see pkgmgr_installer_receive_request + @param[in] pi pkgmgr_installer object + @return Operation result + @retval 0 if a request is not quiet mode + @retval 1 if a request is quiet mode + @remark None + @code +#include +int main(int argc, char **argv) +{ + pkgmgr_installer *pi; + int r = 0; + + pi = pkgmgr_installer_new(); + if(!pi) return -1; + if(pkgmgr_installer_receive_request(pi, argc, argv)) { + r = -1; + goto CLEANUP_RET; + } + if(pkgmgr_installer_is_quiet(pi)) { + // Do quiet mode work... + } else { + // Do normal mode work... + } + + pkgmgr_installer_free(pi); + return r; +} + @endcode + */ +int pkgmgr_installer_is_quiet(pkgmgr_installer *pi); + +/** + @brief Send a process status signal + @pre None + @post None + @see None + @param[in] pi pkgmgr_installer object + @param[in] pkg_type package type: "deb", "jar", "wgt", ... + @param[in] pkg_name package name + @param[in] key Signal key + @param[in] val Signal value + @return Operation result + @retval 0 on success + @retval -errno on failure + @remark If pkgmgr_installer_receive_request() is not called, the session ID will be null string (=="/0"). + @code +#include +int main(int argc, char **argv) +{ + pkgmgr_installer *pi; + int r = 0; + char *session_id = NULL; + + pi = pkgmgr_installer_new(); + if(!pi) return -1; + if(pkgmgr_installer_receive_request(pi, argc, argv)) { + r = -1; + goto CLEANUP_RET; + } + + // Do something... + pkgmgr_installer_send_signal(pi, + "deb", "deb.org.tizen.foo", "install_percent", "100"); + // A sample signal + + pkgmgr_installer_free(pi); + return r; +} + @endcode + */ +int pkgmgr_installer_send_signal(pkgmgr_installer *pi, + const char *pkg_type, + const char *pkg_name, const char *key, + const char *val); + +#ifdef __cplusplus +} +#endif + +#endif /* __PKGMGR_INSTALLER_H__ */ + diff --git a/comm/pkgmgr_installer_config.h b/comm/pkgmgr_installer_config.h new file mode 100755 index 0000000..bf5b323 --- /dev/null +++ b/comm/pkgmgr_installer_config.h @@ -0,0 +1,51 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __PACKAGE_INSTALLER_CONFIG_H__ +#define __PACKAGE_INSTALLER_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Supported options */ +const char *short_opts = "k:l:i:d:c:rq"; +const struct option long_opts[] = { + { "session-id", 1, NULL, 'k' }, + { "license-path", 1, NULL, 'l' }, + { "install", 1, NULL, 'i' }, + { "uninstall", 1, NULL, 'd' }, + { "clear", 1, NULL, 'c' }, + { "recover", 0, NULL, 'r' }, + { "quiet", 1, NULL, 'q' }, + { 0, 0, 0, 0 } /* sentinel */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __PACKAGE_INSTALLER_CONFIG_H__ */ diff --git a/comm/test/CMakeLists.txt b/comm/test/CMakeLists.txt new file mode 100755 index 0000000..016aca7 --- /dev/null +++ b/comm/test/CMakeLists.txt @@ -0,0 +1,33 @@ +include(FindPkgConfig) +pkg_check_modules(test_pkgs REQUIRED dbus-glib-1 glib-2.0 dlog) + +add_definitions(${test_pkgs_CFLAGS}) + + +add_executable(test_comm_pkg_mgr_server + test_comm_pkg_mgr_server.c) +target_link_libraries(test_comm_pkg_mgr_server pkgmgr_installer_pkg_mgr_server) +target_link_libraries(test_comm_pkg_mgr_server ${test_pkgs_LDFLAGS}) + +add_executable(test_comm_status_broadcast_server + test_comm_status_broadcast_server.c) +target_link_libraries(test_comm_status_broadcast_server pkgmgr_installer_status_broadcast_server) +target_link_libraries(test_comm_status_broadcast_server ${test_pkgs_LDFLAGS}) + +add_executable(test_comm_client + test_comm_client.c) +target_link_libraries(test_comm_client pkgmgr_installer_client) +target_link_libraries(test_comm_client ${test_pkgs_LDFLAGS}) + + +add_executable(test_comm_socket + test_comm_socket.c) +target_link_libraries(test_comm_socket comm_socket ${test_pkgs_LDFLAGS}) +set_target_properties(test_comm_socket PROPERTIES SKIP_BUILD_RPATH true) + + +add_executable(test_pkgmgr_installer + test_pkgmgr_installer.c) +target_link_libraries(test_pkgmgr_installer pkgmgr_installer pkgmgr_installer_client ${test_pkgs_LDFLAGS}) +set_target_properties(test_pkgmgr_installer PROPERTIES SKIP_BUILD_RPATH true) + diff --git a/comm/test/test_comm_client.c b/comm/test/test_comm_client.c new file mode 100755 index 0000000..b0a8744 --- /dev/null +++ b/comm/test/test_comm_client.c @@ -0,0 +1,61 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_client.h" +#include +#include + +static GMainLoop *mainloop; + +void +stat_cb(void *data, const char *req_id, const char *pkg_type, + const char *pkg_name, const char *key, const char *val) +{ + printf(">>user callback>> Got: %s %s %s %s %s\n", req_id, pkg_type, + pkg_name, key, val); + + g_main_loop_quit(mainloop); +} + +int main(int argc, char **argv) +{ + + g_type_init(); + mainloop = g_main_loop_new(NULL, FALSE); + + comm_client *cc = comm_client_new(); + + gint ret; + ret = comm_client_request(cc, "__test__req_key", COMM_REQ_TO_INSTALLER, + "dpkg", "test_pkg", "arg1 arg2 arg3", + "this_is_a_cookie", 0); + + printf("client: waiting signal...\n"); + comm_client_set_status_callback(cc, stat_cb, NULL); + + g_main_loop_run(mainloop); + + comm_client_free(cc); + + return 0; +} + diff --git a/comm/test/test_comm_pkg_mgr_server.c b/comm/test/test_comm_pkg_mgr_server.c new file mode 100755 index 0000000..1e130ad --- /dev/null +++ b/comm/test/test_comm_pkg_mgr_server.c @@ -0,0 +1,68 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_pkg_mgr_server.h" +#include +#include + +void +req_cb(void *cb_data, const char *req_id, const int req_type, + const char *pkg_type, const char *pkg_name, const char *args, + const char *cookie, int *ret) +{ + /* TODO: Do your job here */ + printf(">> in callback >> Got request: %s %d %s %s %s (cookie:%s)\n", + req_id, req_type, pkg_type, pkg_name, args, cookie); +} + +gboolean queue_job(void *data) +{ + /* .i.. + + if (no_need_more) { + g_main_loop_quit(mainloop); + return FALSE; + + */ + return TRUE; +} + +int main(int argc, char **argv) +{ + g_type_init(); + + GMainLoop *mainloop = g_main_loop_new(NULL, FALSE); + + PkgMgrObject *pkg_mgr; + pkg_mgr = g_object_new(PKG_MGR_TYPE_OBJECT, NULL); + + pkg_mgr_set_request_callback(pkg_mgr, req_cb, NULL); + + g_timeout_add_seconds(1, queue_job, NULL); + + g_main_loop_run(mainloop); + + /* TODO: add cleanup code */ + + return 0; +} + diff --git a/comm/test/test_comm_socket.c b/comm/test/test_comm_socket.c new file mode 100755 index 0000000..08bd27b --- /dev/null +++ b/comm/test/test_comm_socket.c @@ -0,0 +1,48 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_socket.h" + +#include +#include +#include +#include + +static void __test_comm_socket_create_server(void); +static void __test_comm_socket_create_server(void) +{ + comm_socket *cs; + cs = _comm_socket_new(); + + char *tmp_file_path = "/tmp/____asjdfjlsdjlfjxcvj"; + assert(0 == _comm_socket_create_server(cs, tmp_file_path)); + + _comm_socket_free(cs); +} + +int main(int argc, char **argv) +{ + __test_comm_socket_create_server(); + + return 0; +} + diff --git a/comm/test/test_comm_status_broadcast_server.c b/comm/test/test_comm_status_broadcast_server.c new file mode 100755 index 0000000..ee53e9f --- /dev/null +++ b/comm/test/test_comm_status_broadcast_server.c @@ -0,0 +1,50 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "comm_status_broadcast_server.h" +#include +#include +#include +#include +static int _main_dbus(int argc, char **argv); +static int _main_dbus(int argc, char **argv) +{ + DBusConnection *conn = comm_status_broadcast_server_connect(); + int i; + for (i = 0; i < 100; i++) { + comm_status_broadcast_server_send_signal(conn, "test_id", + "test", "test_pkgname", + "test_key", + "test_val"); + sleep(1); + printf(">>> sent signal: %d\n", i); + } + + return 0; +} + +int main(int argc, char **argv) +{ + return _main_dbus(argc, argv); + +} + diff --git a/comm/test/test_pkgmgr_installer.c b/comm/test/test_pkgmgr_installer.c new file mode 100755 index 0000000..c54929f --- /dev/null +++ b/comm/test/test_pkgmgr_installer.c @@ -0,0 +1,254 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "pkgmgr_installer.h" +#include +#include +#include +#include + +#include "comm_client.h" +static int _argc; +static char **_argv; +static GMainLoop *mainloop; + +static void __test_pi_new_free(void); +static void __test_pi_receive_request_standard_mode(); +static void __test_pi_send_signal(); +static void __test_pi_receive_request_quiet_mode(); + +static void __test_pi_new_free(void) +{ + pkgmgr_installer *pi = pkgmgr_installer_new(); + assert(NULL != pi); + + pkgmgr_installer_free(pi); +} + +static void __test_pi_receive_request_standard_mode(void) +{ + pkgmgr_installer *pi; + + struct test_data { + char *argv[1024]; + int size_argv; + int desired_ret_type; + char *desired_pkg_info; + char *desired_session_id; + }; + + /* Test data collection: Add more test here, except -q */ + struct test_data td[] = { + { {"a", "-i", "abc" }, 3, PKGMGR_REQ_INSTALL, "abc", NULL}, + { {"a", "-i", "ghi", "-k", "key1" }, 5, PKGMGR_REQ_INSTALL, + "ghi", "key1" }, + { {"a", "-i", "abc", "-k", "key1", "-k", "key2" }, 7, + PKGMGR_REQ_INSTALL, "abc", "key2" }, + { { NULL }, 0, 0, NULL, NULL } /* sentinel */ + }; + + /* Run test! */ + int i = 0; + struct test_data *p_td = td + i; + while (p_td && p_td->size_argv) { + + printf(">>> %s %d %d %s\n", p_td->argv[0], p_td->size_argv, + p_td->desired_ret_type, p_td->desired_pkg_info); + + pi = pkgmgr_installer_new(); + assert(NULL != pi); + + assert(0 == pkgmgr_installer_receive_request( + pi, p_td->size_argv, p_td->argv)); + assert(p_td->desired_ret_type == + pkgmgr_installer_get_request_type(pi)); + assert(pkgmgr_installer_get_request_info(pi)); /* NULL check */ + assert(!strcmp(p_td->desired_pkg_info, + pkgmgr_installer_get_request_info(pi))); + if (p_td->desired_session_id) { + assert(pkgmgr_installer_get_session_id(pi)); + assert(!strcmp(p_td->desired_session_id, + pkgmgr_installer_get_session_id(pi))); + } else { + assert(p_td->desired_session_id == + pkgmgr_installer_get_session_id(pi)); + } + pkgmgr_installer_free(pi); + + /* next */ + i++; + p_td = td + i; + } +} + +struct signal_counter { + int start; + int install_percent; + int end; +}; + +static gboolean timer_stop_mainloop(void *data) +{ + g_main_loop_quit(mainloop); + return FALSE; +} + +static void +get_signal_cb(void *cb_data, const char *req_id, const char *pkg_type, + const char *pkg_name, const char *key, const char *val) +{ + struct signal_counter *counter = (struct signal_counter *)cb_data; + + printf("get_signal_cb() called\n"); + if (!strcmp("start", key)) + counter->start += 1; + if (!strcmp("install_percent", key)) + counter->install_percent = atoi(val); + if (!strcmp("end", key)) + counter->end += 1; + + g_main_loop_quit(mainloop); +} + +static gboolean timer_send_signal(void *data) +{ + pkgmgr_installer *pi = (pkgmgr_installer *) data; + printf("try to send signal\n"); + assert(0 == pkgmgr_installer_send_signal(pi, "deb", "testpkg", "start", + "install")); + printf("sent signal\n"); + return FALSE; +} + +static void __test_pi_send_signal(void) +{ + pkgmgr_installer *pi; + pi = pkgmgr_installer_new(); + assert(NULL != pi); + + /* receiver */ + struct signal_counter counter = { 0, }; + comm_client *cc; + cc = comm_client_new(); + comm_client_set_status_callback(cc, get_signal_cb, &counter); + + /* sender */ + g_timeout_add_seconds(1, timer_send_signal, pi); + + /* Set timeout, and run main loop */ + g_timeout_add_seconds(5, timer_stop_mainloop, NULL); + + printf("start loop\n"); + g_main_loop_run(mainloop); + + /* find values */ + printf("exit loop\n"); + assert(1 == counter.start); + + comm_client_free(cc); + + pkgmgr_installer_free(pi); +} + +void __test_pi_receive_request_quiet_mode() +{ + pkgmgr_installer *pi; + + struct test_data { + char *argv[1024]; + int size_argv; + int desired_ret_type; + char *desired_pkg_info; + char *desired_session_id; + }; + + /* Test data collection: Add more test here, except -q */ + struct test_data td[] = { + { {"a", "-q", "-i", "abc" }, 4, PKGMGR_REQ_INSTALL, "abc", NULL}, + { {"a", "-i", "ghi", "-k", "key1", "-q" }, 6, + PKGMGR_REQ_INSTALL, "ghi", "key1"}, + { {NULL}, 0, 0, NULL, NULL } /* sentinel */ + }; + + /* Run test! */ + int i = 0; + int r; + struct test_data *p_td = td + i; + while (p_td && p_td->size_argv) { + + printf(">>> %s %d %d %s\n", p_td->argv[0], p_td->size_argv, + p_td->desired_ret_type, p_td->desired_pkg_info); + + pi = pkgmgr_installer_new(); + assert(NULL != pi); + r = pkgmgr_installer_receive_request(pi, p_td->size_argv, + p_td->argv); + printf("desired=0, r=%d\n", r); + assert(0 == r); + assert(p_td->desired_ret_type == + pkgmgr_installer_get_request_type(pi)); + assert(pkgmgr_installer_get_request_info(pi)); /* NULL check */ + assert(!strcmp + (p_td->desired_pkg_info, + pkgmgr_installer_get_request_info(pi))); + assert(pkgmgr_installer_is_quiet(pi)); + if (p_td->desired_session_id) { + assert(pkgmgr_installer_get_session_id(pi)); + assert(!strcmp + (p_td->desired_session_id, + pkgmgr_installer_get_session_id(pi))); + } else { + assert(p_td->desired_session_id == + pkgmgr_installer_get_session_id(pi)); + } + pkgmgr_installer_free(pi); + + /* next */ + i++; + p_td = td + i; + } +} + +/* Test collection */ +static void __test_pkgmgr_installer(void) +{ + __test_pi_new_free(); + __test_pi_receive_request_standard_mode(); + __test_pi_send_signal(); + __test_pi_receive_request_quiet_mode(); +} + +/* main function */ +int main(int argc, char **argv) +{ + _argc = argc; + _argv = argv; + + /* For event loop */ + g_type_init(); + mainloop = g_main_loop_new(NULL, FALSE); + + __test_pkgmgr_installer(); + + return 0; +} + diff --git a/debian/changelog b/debian/changelog new file mode 100755 index 0000000..efc3ff4 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,7 @@ +slp-pkgmgr (0.1.100-2) unstable; urgency=low + + * Initial Release. + * Git: pkgs/s/slp-pkgmgr + * Tag: slp-pkgmgr_0.1.100-2 + + -- Sewook Park Wed, 07 Dec 2011 12:55:49 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100755 index 0000000..d24df68 --- /dev/null +++ b/debian/control @@ -0,0 +1,48 @@ +Source: slp-pkgmgr +Priority: extra +Maintainer: Sewook Park , Youmin Ha +Build-Depends: debhelper (>= 5), autotools-dev, libsecurity-server-client-dev, libdbus-1-dev, libdbus-glib-1-dev, libecore-dev, dlog-dev, libaul-1-dev, libail-0-dev, libappcore-efl-dev +Standards-Version: 3.7.2 +Section: base + +Package: libpkgmgr-client-dev +Section: libdevel +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libpkgmgr-client-0 (= ${Source-Version}), libecore-dev, libsecurity-server-client-dev, libaul-1-dev, libail-0-dev, libpkgmgr-types-dev(>= ${Source-Version}), libpkgmgr-installer-dev (>= ${Source-Version}) +Description: Package Manager client library develpoment package + +Package: libpkgmgr-client-0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libpkgmgr-installer (>= ${Source-Version}), pkgmgr-server (>= ${Source-Version}) +Description: Packager Manager client library package + +Package: pkgmgr-server +Section: base +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libpkgmgr-installer (>= ${Source-Version}) +Description: Package Manager server + +Package: pkgmgr-server-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, pkgmgr-server +Description: debug package of Package Manager source package + +Package: libpkgmgr-installer +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Library for installer frontend/backend. + +Package: libpkgmgr-installer-dev +Section: libdevel +Architecture: any +Depends: libpkgmgr-installer (= ${Source-Version}), +Description: Dev package for libpkgmgr-installer + +Package: libpkgmgr-types-dev +Section: libdevel +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Package Manager client types develpoment package diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..e69de29 diff --git a/debian/libpkgmgr-client-0.install.in b/debian/libpkgmgr-client-0.install.in new file mode 100755 index 0000000..86624b8 --- /dev/null +++ b/debian/libpkgmgr-client-0.install.in @@ -0,0 +1,6 @@ +@PREFIX@/lib/libpkgmgr-client.so* +@PREFIX@/etc/package-manager/pkg_path.conf +@PREFIX@/bin/pkgcmd +@PREFIX@/bin/pkgmgr-install +/opt/share/applications/*.desktop +@PREFIX@/share/mime/packages/*.xml diff --git a/debian/libpkgmgr-client-0.postinst b/debian/libpkgmgr-client-0.postinst new file mode 100755 index 0000000..ce2df9a --- /dev/null +++ b/debian/libpkgmgr-client-0.postinst @@ -0,0 +1,15 @@ +#!/bin/sh + +#if [ ${USER} == "root" ] +#then +# chown root:root /usr/lib/libss-client.so +#fi + +mkdir -p /usr/etc/package-manager/frontend +mkdir -p /usr/etc/package-manager/backend + +# For pkgmgr-install: +# Update mime database to support package mime types +update-mime-database /usr/share/mime + +echo "Done." > /dev/null diff --git a/debian/libpkgmgr-client-dev.install.in b/debian/libpkgmgr-client-dev.install.in new file mode 100644 index 0000000..f4fa680 --- /dev/null +++ b/debian/libpkgmgr-client-dev.install.in @@ -0,0 +1,2 @@ +@PREFIX@/include/package-manager.h +@PREFIX@/lib/pkgconfig/pkgmgr.pc diff --git a/debian/libpkgmgr-installer-dev.install.in b/debian/libpkgmgr-installer-dev.install.in new file mode 100755 index 0000000..66cdf89 --- /dev/null +++ b/debian/libpkgmgr-installer-dev.install.in @@ -0,0 +1,4 @@ +@PREFIX@/include/pkgmgr/pkgmgr_installer.h +@PREFIX@/lib/pkgconfig/pkgmgr-installer-client.pc +@PREFIX@/lib/pkgconfig/pkgmgr-installer-status-broadcast-server.pc +@PREFIX@/lib/pkgconfig/pkgmgr-installer.pc diff --git a/debian/libpkgmgr-installer.install.in b/debian/libpkgmgr-installer.install.in new file mode 100755 index 0000000..6023b00 --- /dev/null +++ b/debian/libpkgmgr-installer.install.in @@ -0,0 +1,3 @@ +@PREFIX@/lib/libpkgmgr_installer_client.so* +@PREFIX@/lib/libpkgmgr_installer_status_broadcast_server.so* +@PREFIX@/lib/libpkgmgr_installer.so* diff --git a/debian/libpkgmgr-types-dev.install.in b/debian/libpkgmgr-types-dev.install.in new file mode 100755 index 0000000..b936405 --- /dev/null +++ b/debian/libpkgmgr-types-dev.install.in @@ -0,0 +1,3 @@ +@PREFIX@/include/package-manager-types.h +@PREFIX@/include/package-manager-plugin.h +@PREFIX@/lib/pkgconfig/pkgmgr-types.pc diff --git a/debian/pkgmgr-server.install.in b/debian/pkgmgr-server.install.in new file mode 100755 index 0000000..aec6073 --- /dev/null +++ b/debian/pkgmgr-server.install.in @@ -0,0 +1,3 @@ +@PREFIX@/bin/pkgmgr-server +@PREFIX@/share/dbus-1/services/org.tizen.slp.pkgmgr.service +@PREFIX@/share/locale/* diff --git a/debian/pkgmgr-server.postinst b/debian/pkgmgr-server.postinst new file mode 100755 index 0000000..aa57a4a --- /dev/null +++ b/debian/pkgmgr-server.postinst @@ -0,0 +1,13 @@ +#!/bin/sh + +#if [ ${USER} == "root" ] +#then +# chown root:root /usr/bin/ss-server +# chown root:root /etc/rc.d/init.d/ss-serverd +#fi + +#chmod 700 /usr/bin/ss-server +#chmod 755 /etc/rc.d/init.d/ss-serverd +mkdir -p /usr/etc/package-manager/server + +echo "Done." > /dev/null diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..add47c7 --- /dev/null +++ b/debian/rules @@ -0,0 +1,129 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +BUILDDIR = $(CURDIR)/cmake_tmp + +CFLAGS ?= -Wall -g +CXXFLAGS ?= -Wall -g +LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /opt + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 + CXXFLAGS += -O0 +else + CFLAGS += -O2 + CXXFLAGS += -O2 +endif + +LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + mkdir -p $(BUILDDIR) + cd $(BUILDDIR) && CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake .. -DCMAKE_INSTALL_PREFIX=$(PREFIX) + + touch configure-stamp + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir +# Add here commands to compile the package. + cd $(BUILDDIR) && $(MAKE) + + #docbook-to-man debian/wavplayer.sgml > wavplayer.1 + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + done + + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) clean + rm -rf CMakeCache.txt + rm -rf CMakeFiles + rm -rf cmake_install.cmake + rm -rf Makefile + rm -rf install_manifest.txt + rm -rf *.so + rm -rf *.pc + + rm -rf $(BUILDDIR) + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + rm -f $${f%.in}; \ + done + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/wavplayer. + cd $(BUILDDIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install +# mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/ +# ln -s ../init.d/ss-serverd $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S40ss-server + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_install --sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link +# dh_strip + dh_strip --dbg-package=pkgmgr-server-dbg + dh_compress + dh_fixperms +# dh_perl + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/include/SLP_package_manager_PG.h b/include/SLP_package_manager_PG.h new file mode 100755 index 0000000..96f1e1e --- /dev/null +++ b/include/SLP_package_manager_PG.h @@ -0,0 +1,276 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + + + + + +/** + + * + * @ingroup SLP_PG + * @defgroup PackageManagerClient + + +@par package manager Programming Guide + +

Introduction

+

Purpose of this document

+The purpose of this document is to describe how applications can usepackage manager APIs.\n +This document gives only programming guidelines to application engineers. + +

Scope

+The scope of this document is limited to Samsung platform package manager API usage. + +

Architecture

+

Architecture overview

+package manager is responsible for installing / uninstalling / activating application. It also support getting application list API \n + +Dbus is used for communication between frontend and package-server / package-server and client library..\n +Each type of packages have been implemented and these are used for each type of operation. + +@image html high-level.png "High-Level Architure" + +

SLP Features

+package manager has the following features:\n + + - Install /Uninstall /Activate Application (Primitive APIs) + - It can install/uninstall an application + - It can activate/deactivate application. + + - Application List + - It provides the list of applications that are installed. + - It provides the API to free the list. + + - Listen / Broadcast status + - It can listen the status broadcasted by other application. + - It can broadcast the status to other application. + +

package manager API descriptions

+ SEE API manual + +

package manager features with sample code

+

Install /Uninstall /Activate an application

+ +Client application +- Install request with return callback function + +@code +// the package path is "/opt/apps/org.tizen.hello.deb" +#include + +int static return_cb(pkg_request_id req_id, const char *pkg_type, const char *pkg_name, const char *key, const char *val, const void *pmsg, void *data) +{ + pkgmgr_client *pc = (pkgmgr_client *)data; + + if( strcmp(key, "end") == 0) { + pkgmgr_client_free(pc); + exit(0); + } +} + +void install_func() +{ + int result = 0; + pkgmgr_client *pc = NULL; + + pc = pkgmgr_client_new(PC_REQUEST); + if(pc == NULL) { + printf("pc is NULL\n"); + return -1; + } + + result = pkgmgr_client_install(pc, NULL, des, "/opt/apps/org.tizen.hello.deb", NULL, PM_DEFAULT, return_cb, pc); + if(result < 0) { + fprintf(stderr, "Install failed! %d\n", result); + return -1; + } + +} +@endcode + + +- Uninstall request with return callback function + +@code +// the package type is "deb", package name is "org.tizen.hello" +#include + +int static return_cb(pkg_request_id req_id, const char *pkg_type, const char *pkg_name, const char *key, const char *val, const void *pmsg, void *data) +{ + pkgmgr_client *pc = (pkgmgr_client *)data; + + if( strcmp(key, "end") == 0) { + pkgmgr_client_free(pc); + exit(0); + } +} + +void uninstall_func() +{ + int result = 0; + pkgmgr_client *pc = NULL; + + pc = pkgmgr_client_new(PC_REQUEST); + if(pc == NULL) { + printf("pc is NULL\n"); + return -1; + } + + result = pkgmgr_client_uninstall(pc, "deb", des, "org.tizen.hello", PM_DEFAULT, return_cb, pc); + if(result < 0) { + fprintf(stderr, "Uninstall failed! %d\n", result); + return -1; + } + +} +@endcode + + +- Activate request with return callback function + +@code +// the package type is "deb", package name is "org.tizen.hello" +#include + + +void activate_func() +{ + int result = 0; + pkgmgr_client *pc = NULL; + + pc = pkgmgr_client_new(PC_REQUEST); + if(pc == NULL) { + printf("pc is NULL\n"); + return -1; + } + + result = pkgmgr_client_activate(pc, "deb", "org.tizen.hello"); + if(result < 0) { + fprintf(stderr, "Activation failed! %d\n", result); + return -1; + } + + pkgmgr_client_free(pc); + +} +@endcode + + + +

Get Installed Application List

+ +- Get/free application list +- This package manager function is used to get the list of all installed applications which can be removed. + +@code +#include + +static int __iter_fn(const char* pkg_type, const char* pkg_name, const char* version, void *data) +{ + printf("pkg_type %s, pkg_name %s, version %s\n", pkg_type, pkg_name, version); + + return 0; +} + +void getlist_func() +{ + pkgmgr_get_pkg_list(__iter_fn, NULL); +} +@endcode + + + +

Listen and broadcast the status

+ +- Listen / broadcast the status +- This package manager function is used to listen the status broadcasted by other application. + +@code +#include + +int static return_cb(pkg_request_id req_id, const char *pkg_type, const char *pkg_name, const char *key, const char *val, const void *pmsg, void *data) +{ + pkgmgr_client *pc = (pkgmgr_client *)data; + + if( strcmp(key, "end") == 0) { + pkgmgr_client_free(pc); + exit(0); + } +} + +void listen_func() +{ + int result = 0; + pkgmgr_client *pc = NULL; + + pc = pkgmgr_client_new(PC_LISTENING); + if(pc == NULL) { + printf("pc is NULL\n"); + return -1; + } + + result = pkgmgr_client_listen_status(pc, return_cb, pc); + if(result < 0) + { + fprintf(stderr, "status listen failed!\n"); + return -1; + } +} +@endcode + + +- This package manager function is used to listen the status broadcasted by other application. + +@code +// the package type is "deb", package name is "org.tizen.hello", key is "key_string", val is "val_string" +#include + +void broadcast_func() +{ + int result = 0; + pkgmgr_client *pc = NULL; + + pc= pkgmgr_client_new(PC_BROADCAST); + if(pc == NULL) { + printf("pc is NULL\n"); + return -1; + } + + int result = pkgmgr_client_broadcast_status(pc, "deb", "org.tizen.hello", "key_string", "val_string"); + if(result < 0) { + fprintf(stderr, "status broadcast failed!\n"); + return -1; + } + + pkgmgr_client_free(pc); +} +@endcode + + +*/ + +/** +@} +*/ + + diff --git a/include/package-manager-plugin.h b/include/package-manager-plugin.h new file mode 120000 index 0000000..f50bb1f --- /dev/null +++ b/include/package-manager-plugin.h @@ -0,0 +1 @@ +../types/include/package-manager-plugin.h \ No newline at end of file diff --git a/include/package-manager-types.h b/include/package-manager-types.h new file mode 120000 index 0000000..6667546 --- /dev/null +++ b/include/package-manager-types.h @@ -0,0 +1 @@ +../types/include/package-manager-types.h \ No newline at end of file diff --git a/include/package-manager.h b/include/package-manager.h new file mode 120000 index 0000000..2318292 --- /dev/null +++ b/include/package-manager.h @@ -0,0 +1 @@ +../client/include/package-manager.h \ No newline at end of file diff --git a/installers/CMakeLists.txt b/installers/CMakeLists.txt new file mode 100755 index 0000000..71dd46f --- /dev/null +++ b/installers/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(sample) diff --git a/installers/sample/CMakeLists.txt b/installers/sample/CMakeLists.txt new file mode 100755 index 0000000..791a981 --- /dev/null +++ b/installers/sample/CMakeLists.txt @@ -0,0 +1,18 @@ +include(FindPkgConfig) +pkg_check_modules(security_pkgs security-server) + +add_executable(pkgmgr_backend_sample + sample_backend.c) +target_link_libraries(pkgmgr_backend_sample pkgmgr_installer) + +add_library(pkgmgr_backend_lib_sample SHARED + sample_backendlib.c) + +install(TARGETS pkgmgr_backend_sample + DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) + +install(TARGETS pkgmgr_backend_lib_sample + DESTINATION lib + COMPONENT RuntimeLibraries + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) diff --git a/installers/sample/sample_backend.c b/installers/sample/sample_backend.c new file mode 100755 index 0000000..1a03a7e --- /dev/null +++ b/installers/sample/sample_backend.c @@ -0,0 +1,123 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + + + + + +/* sample_backend.c + * test package + */ + + +/* Pkgmgr installer headers */ +#include "pkgmgr_installer.h" + +/* GUI headers */ + +/* glibc headers */ +#include +#include +#include +#include +#include + +static int __confirm_ui(void *data, char *msg); +static int __install_package(const char *pkg_file_path); +static int __uninstall_package(const char *pkg_name); +static int __recover_package_system(void); + +static pkgmgr_installer *_pi; + +static int __confirm_ui(void *data, char *msg) +{ + /* Show confirm ui */ + + return 1; +} + +static int __install_package(const char *pkg_file_path) +{ + if (__confirm_ui(NULL, "Install?")) { + /* Install package, and send signal */ + + } + + int ret = 0; + ret = pkgmgr_installer_send_signal(_pi, "sample", "abc", "end", "ok"); + if (ret == 0) { + system("touch /opt/etc/install_complete"); + } + + return 0; +} + +static int __uninstall_package(const char *pkg_name) +{ + return 0; +} + +static int __clear_package(const char *pkg_name) +{ + return 0; +} + +static int __recover_package_system(void) +{ + return 0; +} + +int main(int argc, char **argv) +{ + int ret = 0; + pkgmgr_installer *pi = pkgmgr_installer_new(); + + _pi = pi; + + pkgmgr_installer_receive_request(pi, argc, argv); + + int req_type = pkgmgr_installer_get_request_type(pi); + if (PKGMGR_REQ_INVALID >= req_type) + return EINVAL; + + const char *pkg_info = pkgmgr_installer_get_request_info(pi); + + switch (req_type) { + case PKGMGR_REQ_INSTALL: + ret = __install_package(pkg_info); + break; + case PKGMGR_REQ_UNINSTALL: + ret = __uninstall_package(pkg_info); + break; + case PKGMGR_REQ_CLEAR: + ret = __clear_package(pkg_info); + break; + case PKGMGR_REQ_RECOVER: + ret = __recover_package_system(); + break; + default: + ret = EINVAL; + } + + return ret; +} + diff --git a/installers/sample/sample_backendlib.c b/installers/sample/sample_backendlib.c new file mode 100755 index 0000000..d286b7f --- /dev/null +++ b/installers/sample/sample_backendlib.c @@ -0,0 +1,106 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + + + + + +/* sample_backendlib.c + * test package + */ + +#include +#include +#include "package-manager-plugin.h" + +static void pkg_native_plugin_on_unload(void); +static int pkg_plugin_app_is_installed(const char *pkg_name); +static int pkg_plugin_get_installed_apps_list(const char *category, + const char *option, + package_manager_pkg_info_t ** + list, int *count); +static int pkg_plugin_get_app_detail_info(const char *pkg_name, + package_manager_pkg_detail_info_t * + pkg_detail_info); +static int pkg_plugin_get_app_detail_info_from_package(const char *pkg_path, + package_manager_pkg_detail_info_t + *pkg_detail_info); + +static void pkg_native_plugin_on_unload(void) +{ + printf("pkg_native_plugin_unload() is called\n"); +} + +static int pkg_plugin_app_is_installed(const char *pkg_name) +{ + printf("pkg_plugin_app_is_installed() is called\n"); + + return 0; +} + +static int pkg_plugin_get_installed_apps_list(const char *category, + const char *option, + package_manager_pkg_info_t ** + list, int *count) +{ + printf("pkg_plugin_get_installed_apps_list() is called\n"); + + return 0; +} + +static int pkg_plugin_get_app_detail_info(const char *pkg_name, + package_manager_pkg_detail_info_t * + pkg_detail_info) +{ + printf("pkg_plugin_get_app_detail_info() is called\n"); + + return 0; +} + +static int pkg_plugin_get_app_detail_info_from_package(const char *pkg_path, + package_manager_pkg_detail_info_t + *pkg_detail_info) +{ + printf("pkg_plugin_get_app_detail_info_from_package() is called\n"); + + return 0; +} + +__attribute__ ((visibility("default"))) +int pkg_plugin_on_load(pkg_plugin_set *set) +{ + if (set == NULL) { + return -1; + } + + memset(set, 0x00, sizeof(pkg_plugin_set)); + + set->plugin_on_unload = pkg_native_plugin_on_unload; + set->pkg_is_installed = pkg_plugin_app_is_installed; + set->get_installed_pkg_list = pkg_plugin_get_installed_apps_list; + set->get_pkg_detail_info = pkg_plugin_get_app_detail_info; + set->get_pkg_detail_info_from_package = + pkg_plugin_get_app_detail_info_from_package; + + return 0; +} + diff --git a/org.tizen.slp.pkgmgr.service.in b/org.tizen.slp.pkgmgr.service.in new file mode 100644 index 0000000..b9d01d0 --- /dev/null +++ b/org.tizen.slp.pkgmgr.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.tizen.slp.pkgmgr +Exec=@PREFIX@/bin/pkgmgr-server diff --git a/packaging/pkgmgr.spec b/packaging/pkgmgr.spec new file mode 100644 index 0000000..84cb8bc --- /dev/null +++ b/packaging/pkgmgr.spec @@ -0,0 +1,167 @@ +#sbs-git:slp/pkgs/s/slp-pkgmgr pkgmgr 0.1.103 29b53909a5d6e8728429f0a188177eac691cb6ce +Name: pkgmgr +Summary: Packager Manager client library package +Version: 0.1.104 +Release: 1 +Group: TO_BE/FILLED_IN +License: LGPL +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: gettext-tools +BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(security-server) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(ail) +BuildRequires: pkgconfig(appcore-efl) + + +%description +Packager Manager client library package for packaging + + +%package client +Summary: Package Manager client library develpoment package +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description client +Package Manager client library develpoment package for packaging + +%package client-devel +Summary: Package Manager client library develpoment package +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description client-devel +Package Manager client library develpoment package for packaging + +%package server +Summary: Package Manager server +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description server +Package Manager server for packaging + +%package installer +Summary: Library for installer frontend/backend. +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description installer +Library for installer frontend/backend for packaging. + +%package installer-devel +Summary: Dev package for libpkgmgr-installer +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description installer-devel +Dev package for libpkgmgr-installer for packaging. + +%package types-devel +Summary: Package Manager client types develpoment package +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description types-devel +Package Manager client types develpoment package for packaging + + +%prep +%setup -q + +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} + +%build + +make %{?jobs:-j%jobs} +%install +rm -rf %{buildroot} +%make_install + + +%post +/sbin/ldconfig + +mkdir -p /usr/etc/package-manager/frontend +mkdir -p /usr/etc/package-manager/backend + +# For pkgmgr-install: +# Update mime database to support package mime types +update-mime-database /usr/share/mime + +%post server + +/sbin/ldconfig +mkdir -p /usr/etc/package-manager/server + +%post client -p /sbin/ldconfig + +%postun client -p /sbin/ldconfig + +%post installer -p /sbin/ldconfig + +%postun installer -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%{_bindir}/pkgcmd +%exclude %{_bindir}/pkgmgr_backend_sample +%exclude %{_bindir}/pkgmgr_backend_test +%exclude %{_bindir}/pkgmgr_frontend_sample +%exclude %{_bindir}/pkgmgr_frontend_test +%exclude %{_includedir}/pkgmgr/comm_client.h +%exclude %{_includedir}/pkgmgr/comm_config.h +%exclude %{_includedir}/pkgmgr/comm_status_broadcast_server.h +%exclude %{_libdir}/libpkgmgr_backend_lib_sample.so +%exclude /usr/etc/package-manager/server/queue_status + +%files client +%defattr(-,root,root,-) +%{_prefix}/etc/package-manager/pkg_path.conf +%{_datadir}/mime/packages/mime.wac.xml +%{_bindir}/pkgmgr-install +%{_libdir}/libpkgmgr-client.so.* +/opt/share/applications/org.tizen.pkgmgr-install.desktop + +%files client-devel +%defattr(-,root,root,-) +%{_includedir}/package-manager.h +%{_libdir}/pkgconfig/pkgmgr.pc +%{_libdir}/libpkgmgr-client.so + +%files server +%defattr(-,root,root,-) +%{_datadir}/dbus-1/services/org.tizen.slp.pkgmgr.service +%{_bindir}/pkgmgr-server +%{_datadir}/locale/*/LC_MESSAGES/*.mo + +%files installer +%defattr(-,root,root,-) +%{_libdir}/libpkgmgr_installer.so.* +%{_libdir}/libpkgmgr_installer_status_broadcast_server.so.* +%{_libdir}/libpkgmgr_installer_client.so.* + +%files installer-devel +%defattr(-,root,root,-) +%{_includedir}/pkgmgr/pkgmgr_installer.h +%{_libdir}/pkgconfig/pkgmgr-installer-status-broadcast-server.pc +%{_libdir}/pkgconfig/pkgmgr-installer.pc +%{_libdir}/pkgconfig/pkgmgr-installer-client.pc +%{_libdir}/libpkgmgr_installer.so +%{_libdir}/libpkgmgr_installer_client.so +%{_libdir}/libpkgmgr_installer_status_broadcast_server.so + +%files types-devel +%defattr(-,root,root,-) +%{_includedir}/package-manager-types.h +%{_includedir}/package-manager-plugin.h +%{_libdir}/pkgconfig/pkgmgr-types.pc diff --git a/pkg_path.conf.in b/pkg_path.conf.in new file mode 100644 index 0000000..55e8c53 --- /dev/null +++ b/pkg_path.conf.in @@ -0,0 +1,6 @@ +# usage +# frontend:directory_path +# backend:directory_path +frontend:/usr/etc/package-manager/frontend/ +backend:/usr/etc/package-manager/backend/ +backendlib:/usr/etc/package-manager/backendlib/ \ No newline at end of file diff --git a/pkgmgr.pc.in b/pkgmgr.pc.in new file mode 100644 index 0000000..19c932b --- /dev/null +++ b/pkgmgr.pc.in @@ -0,0 +1,16 @@ +# +# Copyright (c) 2008 ~ 2010 Samsung Electronics Co., Ltd. +# All rights reserved. +# + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: package manager +Description: SLP Package Manager Package +Version: @VERSION@ +Requires: security-server dlog pkgmgr-types pkgmgr-installer-client pkgmgr-installer-status-broadcast-server aul +Libs: -L${libdir} -L${libdir}/pkgmgr -lpkgmgr-client +Cflags: -I${includedir} diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt new file mode 100644 index 0000000..e3aebb4 --- /dev/null +++ b/po/CMakeLists.txt @@ -0,0 +1,24 @@ +# for i18n + +SET(POFILES en_US.po en_GB.po ja_JP.po ko_KR.po zh_CN.po) + +SET(MSGFMT "/usr/bin/msgfmt") + +FOREACH(pofile ${POFILES}) + SET(pofile ${CMAKE_CURRENT_SOURCE_DIR}/${pofile}) + MESSAGE("PO: ${pofile}") + GET_FILENAME_COMPONENT(absPofile ${pofile} ABSOLUTE) + GET_FILENAME_COMPONENT(lang ${absPofile} NAME_WE) + SET(moFile ${CMAKE_CURRENT_BINARY_DIR}/${lang}.mo) + ADD_CUSTOM_COMMAND( + OUTPUT ${moFile} + COMMAND ${MSGFMT} -o ${moFile} ${absPofile} + DEPENDS ${absPofile} + ) + INSTALL(FILES ${moFile} + DESTINATION share/locale/${lang}/LC_MESSAGES RENAME ${PROJECT_NAME}.mo) + SET(moFiles ${moFiles} ${moFile}) +ENDFOREACH(pofile) + +MESSAGE(".mo files: ${moFiles}") +ADD_CUSTOM_TARGET(po ALL DEPENDS ${moFiles}) diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..df0ed57 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,2 @@ +# List of source files containing translatable strings. +server/src/pkgmgr-server.c diff --git a/po/en_GB.po b/po/en_GB.po new file mode 100644 index 0000000..af3f93a --- /dev/null +++ b/po/en_GB.po @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-10-14 19:06+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: server/src/pkgmgr-server.c:251 +#, c-format +msgid "Install?" +msgstr "" + +#: server/src/pkgmgr-server.c:287 +#, c-format +msgid "Uninstall?" +msgstr "" + +#: server/src/pkgmgr-server.c:290 +#, c-format +msgid "Invalid request" +msgstr "" diff --git a/po/en_US.po b/po/en_US.po new file mode 100644 index 0000000..af3f93a --- /dev/null +++ b/po/en_US.po @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-10-14 19:06+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: server/src/pkgmgr-server.c:251 +#, c-format +msgid "Install?" +msgstr "" + +#: server/src/pkgmgr-server.c:287 +#, c-format +msgid "Uninstall?" +msgstr "" + +#: server/src/pkgmgr-server.c:290 +#, c-format +msgid "Invalid request" +msgstr "" diff --git a/po/ja_JP.po b/po/ja_JP.po new file mode 100644 index 0000000..1d5f6e0 --- /dev/null +++ b/po/ja_JP.po @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-10-14 19:06+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: server/src/pkgmgr-server.c:251 +#, c-format +msgid "Install?" +msgstr "インストールしますか?" + +#: server/src/pkgmgr-server.c:287 +#, c-format +msgid "Uninstall?" +msgstr "アンインストールしますか?" + +#: server/src/pkgmgr-server.c:290 +#, c-format +msgid "Invalid request" +msgstr "無効なリクエストです" diff --git a/po/ko_KR.po b/po/ko_KR.po new file mode 100644 index 0000000..3850a70 --- /dev/null +++ b/po/ko_KR.po @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-10-14 19:06+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: server/src/pkgmgr-server.c:251 +#, c-format +msgid "Install?" +msgstr "설치할까요?" + +#: server/src/pkgmgr-server.c:287 +#, c-format +msgid "Uninstall?" +msgstr "삭제할까요?" + +#: server/src/pkgmgr-server.c:290 +#, c-format +msgid "Invalid request" +msgstr "요청이 바르지 않습니다" diff --git a/po/package-manager.pot b/po/package-manager.pot new file mode 100644 index 0000000..e9f371b --- /dev/null +++ b/po/package-manager.pot @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-10-14 19:06+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: server/src/pkgmgr-server.c:251 +#, c-format +msgid "Install?" +msgstr "" + +#: server/src/pkgmgr-server.c:287 +#, c-format +msgid "Uninstall?" +msgstr "" + +#: server/src/pkgmgr-server.c:290 +#, c-format +msgid "Invalid request" +msgstr "" diff --git a/po/update-po.sh b/po/update-po.sh new file mode 100755 index 0000000..16fbdc1 --- /dev/null +++ b/po/update-po.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +PACKAGE=package-manager +SRCROOT=.. +POTFILES=POTFILES.in + +#ALL_LINGUAS= am az be ca cs da de el en_CA en_GB es et fi fr hr hu it ja ko lv mk ml ms nb ne nl pa pl pt pt_BR ru rw sk sl sr sr@Latn sv ta tr uk vi zh_CN zh_TW +ALL_LINGUAS="en_US en_GB ja_JP ko_KR zh_CN" + +XGETTEXT=/usr/bin/xgettext +MSGMERGE=/usr/bin/msgmerge + +echo -n "Make ${PACKAGE}.pot " +if [ ! -e $POTFILES ] ; then + echo "$POTFILES not found" + exit 1 +fi + +$XGETTEXT --default-domain=${PACKAGE} --directory=${SRCROOT} \ + --add-comments --keyword=_ --keyword=N_ --files-from=$POTFILES +if [ $? -ne 0 ]; then + echo "xgettext error" + exit 1 +fi + +if [ ! -f ${PACKAGE}.po ]; then + echo "No such file: ${PACKAGE}.po" + exit 1 +fi + +rm -f ${PACKAGE}.pot && mv ${PACKAGE}.po ${PACKAGE}.pot +echo "done" + +for LANG in $ALL_LINGUAS; do + echo "$LANG : " + + if [ ! -e $LANG.po ] ; then + sed 's/CHARSET/UTF-8/g' ${PACKAGE}.pot > ${LANG}.po + echo "${LANG}.po created" + else + if $MSGMERGE ${LANG}.po ${PACKAGE}.pot -o ${LANG}.new.po ; then + if cmp ${LANG}.po ${LANG}.new.po > /dev/null 2>&1; then + rm -f ${LANG}.new.po + else + if mv -f ${LANG}.new.po ${LANG}.po; then + echo "" + else + echo "msgmerge for $LANG.po failed: cannot move $LANG.new.po to $LANG.po" 1>&2 + rm -f ${LANG}.new.po + exit 1 + fi + fi + else + echo "msgmerge for $LANG failed!" + rm -f ${LANG}.new.po + fi + fi + echo "" +done + diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..af3f93a --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-10-14 19:06+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: server/src/pkgmgr-server.c:251 +#, c-format +msgid "Install?" +msgstr "" + +#: server/src/pkgmgr-server.c:287 +#, c-format +msgid "Uninstall?" +msgstr "" + +#: server/src/pkgmgr-server.c:290 +#, c-format +msgid "Invalid request" +msgstr "" diff --git a/queue_status b/queue_status new file mode 100644 index 0000000..5baa80c --- /dev/null +++ b/queue_status @@ -0,0 +1 @@ +This file is for creating required directory. diff --git a/server/include/pkgmgr-server.h b/server/include/pkgmgr-server.h new file mode 100755 index 0000000..e3ea298 --- /dev/null +++ b/server/include/pkgmgr-server.h @@ -0,0 +1,64 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 _PKGMGR_SERVER_H_ +#define _PKGMGR_SERVER_H_ + +#define CONF_FILE "/usr/etc/package-manager/server/.config" +#define DESKTOP_FILE_DIRS "/usr/share/install-info/desktop.conf" + +#define PKG_BACKEND "backend:" +#define PKG_CONF_PATH "/usr/etc/package-manager/pkg_path.conf" + +#define MAX_REQ_ID_LEN 256 +#define MAX_PKG_TYPE_LEN 128 +#define MAX_PKG_NAME_LEN 256 +#define MAX_PKG_ARGS_LEN 4096 +#define MAX_COOKIE_LEN 32 +#define DESKTOP_FILE_DIRS_NUM 1024 + +typedef struct { + char req_id[MAX_REQ_ID_LEN]; + int req_type; + char pkg_type[MAX_PKG_TYPE_LEN]; + char pkg_name[MAX_PKG_NAME_LEN]; + char args[MAX_PKG_ARGS_LEN]; + char cookie[MAX_COOKIE_LEN]; +} pm_dbus_msg; + + +struct pm_inotify_paths_t { + int wd; + char *path; +}; +typedef struct pm_inotify_paths_t pm_inotify_paths; + +char *_get_backend_cmd(char *type); +void _pm_desktop_file_monitor_init(); +void _pm_desktop_file_monitor_fini(); +int _pm_desktop_file_dir_search(pm_inotify_paths *paths, int number); + +#endif /* _PKGMGR_SERVER_H_ */ diff --git a/server/include/pm-queue.h b/server/include/pm-queue.h new file mode 100755 index 0000000..2237c2d --- /dev/null +++ b/server/include/pm-queue.h @@ -0,0 +1,50 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 _PM_QUEUE_H_ +#define _PM_QUEUE_H_ + +#include "pkgmgr-server.h" + +#define STATUS_FILE "/usr/etc/package-manager/server/queue_status" +/* #define STATUS_FILE "./queue_status" */ + +typedef struct _pm_queue_data { + pm_dbus_msg *msg; + struct _pm_queue_data *next; +} pm_queue_data; + +void _pm_queue_init(); +void _pm_queue_push(pm_dbus_msg item); +pm_dbus_msg _pm_queue_pop(); +pm_dbus_msg _pm_queue_get_head(); +void _pm_queue_final(); +void _pm_queue_delete(pm_dbus_msg item); +pm_queue_data *_add_node(); +void _save_queue_status(pm_dbus_msg item, char *status); +void _print_queue(); + +#endif /* _PM_QUEUE_H_ */ diff --git a/server/src/pkgmgr-server.c b/server/src/pkgmgr-server.c new file mode 100755 index 0000000..b99b833 --- /dev/null +++ b/server/src/pkgmgr-server.c @@ -0,0 +1,1222 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pkgmgr_installer.h" +#include "comm_pkg_mgr_server.h" +#include "pkgmgr-server.h" +#include "pm-queue.h" +#include "comm_config.h" + +/* debug output */ +#if defined(NDEBUG) +#define DBG(fmt, args...) +#define __SET_DBG_OUTPUT(fp) +#elif defined(PRINT) +#include +FILE *___log = NULL; +#define DBG(fmt, args...) \ + {if (!___log) ___log = stderr; \ + fprintf(___log, "[DBG:PMS]%s:%d:%s(): " fmt "\n",\ + basename(__FILE__), __LINE__, __func__, ##args); fflush(___log); } +#define __SET_DBG_OUTPUT(fp) \ + (___log = fp) +#else +#include +#undef LOG_TAG +#define LOG_TAG "PKGMGR_SERVER" + +#define DBGE(fmt, arg...) LOGE("[%s,%d] "fmt, __FUNCTION__, __LINE__, ##arg) +#define DBG(fmt, arg...) LOGD("[%s,%d] "fmt, __FUNCTION__, __LINE__, ##arg) +#endif + +#if !defined(PACKAGE) +#define PACKAGE "package-manager" +#endif + +#if !defined(LOCALEDIR) +#define LOCALEDIR "/usr/share/locale" +#endif + +#define DESKTOP_W 720.0 + +static int backend_flag = 0; /* 0 means that backend process is not running */ +static int drawing_popup = 0; /* 0 means that pkgmgr-server has no popup now */ + +/* For pkgs with no desktop file, inotify callback wont be called. +* To handle that case ail_db_update is initialized as 1 +* This flag will be used to ensure that pkgmgr server does not exit +* before the db is updated. */ +int ail_db_update = 1; + +GMainLoop *mainloop = NULL; + +static const char *activate_cmd = "/usr/bin/activator"; + +/* operation_type */ +typedef enum { + OPERATION_INSTALL = 0, + OPERATION_UNINSTALL, + OPERATION_ACTIVATE, + OPERATION_MAX +} OPERATION_TYPE; + +struct appdata { + Evas_Object *win; + Evas_Object *notify; + pm_dbus_msg *item; + OPERATION_TYPE op_type; +}; + +struct pm_desktop_notifier_t { + int ifd; + Ecore_Fd_Handler *handler; +}; +typedef struct pm_desktop_notifier_t pm_desktop_notifier; + +pm_desktop_notifier desktop_notifier; +pm_inotify_paths paths[DESKTOP_FILE_DIRS_NUM]; + +static +void response_cb(void *data, Evas_Object *notify, void *event_info); +static +int create_popup(struct appdata *ad); +static void sighandler(int signo); +gboolean queue_job(void *data); +static Eina_Bool __directory_notify(void *data, Ecore_Fd_Handler *fd_handler); + +static Eina_Bool __directory_notify(void *data, Ecore_Fd_Handler *fd_handler) +{ + ail_db_update = 0; + char *buf = NULL; + ssize_t read_size = 0; + ssize_t len = 0; + ssize_t i = 0; + int fd = -1; + + fd = ecore_main_fd_handler_fd_get(fd_handler); + DBG("ifd [%d]\n", fd); + + if (ioctl(fd, FIONREAD, &read_size) < 0) { + DBG("Failed to get byte size\n"); + ail_db_update = 1; + return ECORE_CALLBACK_CANCEL; + } + + if (read_size <= 0) { + DBG("Buffer is not ready!!!\n"); + ail_db_update = 1; + return ECORE_CALLBACK_RENEW; + } + + buf = malloc(read_size); + if (!buf) { + DBG("Failed to allocate memory for event handling\n"); + ail_db_update = 1; + return ECORE_CALLBACK_RENEW; + } + + len = read(fd, buf, read_size); + if (len < 0) { + free(buf); + /*Stop monitoring about this invalid file descriptor */ + ail_db_update = 1; + return ECORE_CALLBACK_CANCEL; + } + + while (i < len) { + struct inotify_event *event = (struct inotify_event*) &buf[i]; + char *str_potksed = "potksed."; + char *cut; + char *package = NULL; + ssize_t idx; + int nev_name; + + /* 1. check the extension of a file */ + nev_name = strlen(event->name) - 1; + for (idx = 0; nev_name >= 0 && str_potksed[idx]; idx++) { + if (event->name[nev_name] != str_potksed[idx]) { + break; + } + nev_name --; + } + + if (str_potksed[idx] != '\0') { + DBG("This is not a desktop file : %s\n", event->name); + i += sizeof(struct inotify_event) + event->len; + continue; + } + + package = strdup(event->name); + if (package == NULL) + continue; + + cut = strstr(package, ".desktop"); + *cut = '\0'; + DBG("Package : %s\n", package); + + /* add & update */ + if (event->mask & IN_CREATE || event->mask & IN_CLOSE_WRITE || + event->mask & IN_MOVED_TO) { + ail_appinfo_h ai = NULL; + ail_error_e ret; + + ret = ail_package_get_appinfo(package, &ai); + if (ai) + ail_package_destroy_appinfo(ai); + + if (AIL_ERROR_NO_DATA == ret) { + if (ail_desktop_add(package) < 0) { + DBG("Failed to add a new package (%s)\n", event->name); + } + } else if (AIL_ERROR_OK == ret) { + if (ail_desktop_update(package) < 0) { + DBG("Failed to add a new package (%s)\n", event->name); + } + } else; + /* delete */ + } else if (event->mask & IN_DELETE) { + if (ail_desktop_remove(package) < 0) + DBG("Failed to remove a package (%s)\n", + event->name); + } else { + DBG("this event is not dealt with inotify\n"); + } + + free(package); + + i += sizeof(struct inotify_event) + event->len; + } + + free(buf); + ail_db_update = 1; + return ECORE_CALLBACK_RENEW; +} + +static +void response_cb(void *data, Evas_Object *notify, void *event_info) +{ + struct appdata *ad = (struct appdata *)data; + + DBG("start of response_cb()\n"); + + if ((int)event_info == ELM_POPUP_RESPONSE_OK) { /* YES */ + DBG("Uninstalling... [%s]\n", ad->item->pkg_name); + + if (strlen(ad->item->pkg_name) == 0) { + DBG("package_name is empty\n"); + } + + if (strlen(ad->item->pkg_type) == 0) { + DBG("Fail : Uninstalling... [%s]\n", + ad->item->pkg_name); + free(ad->item); + evas_object_del(ad->notify); + evas_object_del(ad->win); + drawing_popup = 0; + + return; + } + + DBG("pkg_type = [%s]\n", ad->item->pkg_type); + + _pm_queue_push(*(ad->item)); + + } else { /* NO */ + pkgmgr_installer *pi; + gboolean ret_parse; + gint argcp; + gchar **argvp; + GError *gerr = NULL; + + pi = pkgmgr_installer_new(); + if (!pi) { + DBG("Failure in creating the pkgmgr_installer object"); + return; + } + + ret_parse = g_shell_parse_argv(ad->item->args, + &argcp, &argvp, &gerr); + if (FALSE == ret_parse) { + DBG("Failed to split args: %s", ad->item->args); + DBG("messsage: %s", gerr->message); + pkgmgr_installer_free(pi); + return; + } + + pkgmgr_installer_receive_request(pi, argcp, argvp); + + pkgmgr_installer_send_signal(pi, ad->item->pkg_type, + ad->item->pkg_name, "end", + "cancel"); + + pkgmgr_installer_free(pi); + } + + /* Free resource */ + free(ad->item); + evas_object_del(ad->notify); + evas_object_del(ad->win); + /***************/ + + g_idle_add(queue_job, NULL); + + DBG("end of response_cb()\n"); + + drawing_popup = 0; + + return; +} + +static char *__get_exe_path(const char *pkg_name) +{ + ail_appinfo_h handle; + ail_error_e ret; + char *str; + char *exe_path; + + ret = ail_package_get_appinfo(pkg_name, &handle); + if (ret != AIL_ERROR_OK) { + DBGE("ail_package_get_appinfo() failed"); + return NULL; + } + + ret = ail_appinfo_get_str(handle, AIL_PROP_X_SLP_EXE_PATH, &str); + if (ret != AIL_ERROR_OK) { + DBGE("ail_appinfo_get_str() failed"); + ail_package_destroy_appinfo(handle); + return NULL; + } + + exe_path = strdup(str); + if (exe_path == NULL) { + DBGE("strdup() failed"); + ail_package_destroy_appinfo(handle); + return NULL; + } + + ret = ail_package_destroy_appinfo(handle); + if (ret != AIL_ERROR_OK) { + DBGE("ail_package_destroy_appinfo() failed"); + return NULL; + } + + return exe_path; +} + +static +int create_popup(struct appdata *ad) +{ + DBG("start of create_popup()\n"); + + drawing_popup = 1; + + char sentence[MAX_PKG_ARGS_LEN] = { '\0' }; + char *pkg_name = NULL; + char app_name[MAX_PKG_NAME_LEN] = { '\0' }; + + ad->win = elm_win_add(NULL, PACKAGE, ELM_WIN_DIALOG_BASIC); + if (!ad->win) { + DBG("Failed to create a new window\n"); + drawing_popup = 0; + return -1; + } + + elm_win_alpha_set(ad->win, EINA_TRUE); + elm_win_title_set(ad->win, "test"); + elm_win_borderless_set(ad->win, EINA_TRUE); + elm_win_raise(ad->win); + + int rotation = 0; + int w; + int h; + int x; + int y; + unsigned char *prop_data = NULL; + int count; + ecore_x_window_geometry_get(ecore_x_window_root_get( + ecore_x_window_focus_get()), + &x, &y, &w, &h); + int ret = + ecore_x_window_prop_property_get(ecore_x_window_root_get + (ecore_x_window_focus_get()), + ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE, + ECORE_X_ATOM_CARDINAL, + 32, &prop_data, &count); + if (ret && prop_data) + memcpy(&rotation, prop_data, sizeof(int)); + if (prop_data) + free(prop_data); + evas_object_resize(ad->win, w, h); + evas_object_move(ad->win, x, y); + if (rotation != -1) + elm_win_rotation_with_resize_set(ad->win, rotation); + + double s; + s = w / DESKTOP_W; + elm_scale_set(s); + + evas_object_show(ad->win); + + ad->notify = elm_popup_add(ad->win); + if (!ad->notify) { + DBG("failed to create notify object\n"); + evas_object_del(ad->win); + drawing_popup = 0; + return -1; + } + + /* Sentence of popup */ + pkg_name = strrchr(ad->item->pkg_name, '/') == NULL ? + ad->item->pkg_name : strrchr(ad->item->pkg_name, '/') + 1; + + if (ad->op_type == OPERATION_INSTALL) { + snprintf(sentence, sizeof(sentence) - 1, _("Install?")); + } else if (ad->op_type == OPERATION_UNINSTALL) { + + ail_appinfo_h handle; + ail_error_e ret; + char *str; + ret = ail_package_get_appinfo(pkg_name, &handle); + if (ret != AIL_ERROR_OK) { + drawing_popup = 0; + evas_object_del(ad->notify); + evas_object_del(ad->win); + return -1; + } + + ret = ail_appinfo_get_str(handle, AIL_PROP_NAME_STR, &str); + if (ret != AIL_ERROR_OK) { + ail_package_destroy_appinfo(handle); + drawing_popup = 0; + evas_object_del(ad->notify); + evas_object_del(ad->win); + return -1; + } + + snprintf(app_name, sizeof(app_name) - 1, str); + + ret = ail_package_destroy_appinfo(handle); + if (ret != AIL_ERROR_OK) { + drawing_popup = 0; + evas_object_del(ad->notify); + evas_object_del(ad->win); + return -1; + } + + pkg_name = app_name; + + snprintf(sentence, sizeof(sentence) - 1, _("Uninstall?")); + } else + snprintf(sentence, sizeof(sentence) - 1, _("Invalid request")); + + elm_popup_title_label_set(ad->notify, pkg_name); + evas_object_size_hint_weight_set(ad->notify, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); +/* elm_popup_mode_set(ad->notify, ELM_POPUP_TYPE_ALERT); */ + + evas_object_show(ad->notify); + /***********************************/ + + elm_popup_desc_set(ad->notify, sentence); + + elm_popup_buttons_add(ad->notify, 2, + dgettext("sys_string", "IDS_COM_SK_YES"), + ELM_POPUP_RESPONSE_OK, dgettext("sys_string", + "IDS_COM_SK_NO"), + ELM_POPUP_RESPONSE_CANCEL, NULL); + evas_object_smart_callback_add(ad->notify, + "response", response_cb, ad); + + evas_object_show(ad->notify); + + DBG("end of create_popup()\n"); + return 0; +} + +static void sighandler(int signo) +{ + int status; + pid_t pid; + + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { + DBG("child exit [%d]\n", pid); + } + + g_idle_add(queue_job, NULL); + + backend_flag = 0; +} + +void req_cb(void *cb_data, const char *req_id, const int req_type, + const char *pkg_type, const char *pkg_name, const char *args, + const char *cookie, int *ret) +{ + static int sig_reg = 0; + int err = -1; + + DBG(">> in callback >> Got request: [%s] [%d] [%s] [%s] [%s] [%s]", + req_id, req_type, pkg_type, pkg_name, args, cookie); + + struct appdata *ad = (struct appdata *)cb_data; + + pm_dbus_msg *item = calloc(1, sizeof(pm_dbus_msg)); + memset(item, 0x00, sizeof(pm_dbus_msg)); + + strncpy(item->req_id, req_id, sizeof(item->req_id) - 1); + item->req_type = req_type; + strncpy(item->pkg_type, pkg_type, sizeof(item->pkg_type) - 1); + strncpy(item->pkg_name, pkg_name, sizeof(item->pkg_name) - 1); + strncpy(item->args, args, sizeof(item->args) - 1); + strncpy(item->cookie, cookie, sizeof(item->cookie) - 1); + + if (sig_reg == 0) { + struct sigaction act; + + act.sa_handler = sighandler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_NOCLDSTOP; + + if (sigaction(SIGCHLD, &act, NULL) < 0) { + DBG("signal: SIGCHLD failed\n"); + } else + DBG("signal: SIGCHLD succeed\n"); + + sig_reg = 1; + } + + DBG("req_type=(%d) drawing_popup=(%d) backend_flag=(%d)\n", req_type, + drawing_popup, backend_flag); + + char *quiet = NULL; + + switch (item->req_type) { + case COMM_REQ_TO_INSTALLER: + /* -q option should be located at the end of command !! */ + if (((quiet = strstr(args, " -q")) && + (quiet[strlen(quiet)] == '\0')) || + ((quiet = strstr(args, " '-q'")) && + (quiet[strlen(quiet)] == '\0'))) { + /* quiet mode */ + _pm_queue_push(*item); + /* Free resource */ + free(item); + + g_idle_add(queue_job, NULL); + *ret = COMM_RET_OK; + } else { + /* non quiet mode */ + if (drawing_popup == 0 && backend_flag == 0) { + /* if there is no popup */ + ad->item = item; + + if (strstr(args, " -i ") + || strstr(args, " '-i' ")) + ad->op_type = OPERATION_INSTALL; + else if (strstr(args, " -d ") + || strstr(args, " '-d' ")) { + ad->op_type = OPERATION_UNINSTALL; + + /* 2011-04-01 + Change the mode temporarily. This should be removed */ + /*strncat(item->args, " -q", + strlen(" -q"));*/ + } else + ad->op_type = OPERATION_MAX; + + err = create_popup(ad); + if (err != 0) { + *ret = COMM_RET_ERROR; + DBG("create popup failed\n"); + queue_job(NULL); + return; + } else { + *ret = COMM_RET_OK; + } + } else { + /* if popup is already being drawn */ + free(item); + *ret = COMM_RET_ERROR; + } + } + break; + case COMM_REQ_TO_ACTIVATOR: + /* In case of activate, there is no popup */ + _pm_queue_push(*item); + /* Free resource */ + free(item); + +/* g_idle_add(queue_job, NULL); */ + queue_job(NULL); + *ret = COMM_RET_OK; + break; + case COMM_REQ_TO_CLEARER: + /* In case of activate, there is no popup */ + _pm_queue_push(*item); + /* Free resource */ + free(item); + +/* g_idle_add(queue_job, NULL); */ + queue_job(NULL); + *ret = COMM_RET_OK; + break; + case COMM_REQ_CANCEL: + ad->item = item; + _pm_queue_delete(*(ad->item)); + free(item); + *ret = COMM_RET_OK; + break; + default: + DBG("Check your request..\n"); + free(item); + *ret = COMM_RET_ERROR; + break; + } +} + +gboolean queue_job(void *data) +{ + /* DBG("queue_job start"); */ + + /* Pop a job from queue */ + pm_dbus_msg item = _pm_queue_get_head(); + pid_t pid; + int ret = 0; + char *backend_cmd = NULL; + char *exe_path = NULL; + + DBG("item.req_type=(%d) backend_flag=(%d)\n", item.req_type, + backend_flag); + + /* queue is empty and backend process is not running, quit */ + if ((item.req_type == -1) && (backend_flag == 0) && + drawing_popup == 0 && ail_db_update == 1) { + if (!getenv("PMS_STANDALONE")) + ecore_main_loop_quit(); /* Quit main loop: + go to cleanup */ + return FALSE; /* Anyway, run queue_job() again. */ + } else if (backend_flag == 1) /* backend process is running */ + return FALSE; + + _pm_queue_pop(); + + switch (item.req_type) { + case COMM_REQ_TO_INSTALLER: + DBG("installer start"); + _save_queue_status(item, "processing"); + DBG("saved queue status. Now try fork()"); + pid = fork(); + + switch (pid) { + case 0: /* child */ + DBG("before run _get_backend_cmd()"); + backend_cmd = _get_backend_cmd(item.pkg_type); + if (NULL == backend_cmd) + break; + + DBG("Try to exec [%s][%s]", item.pkg_type, + backend_cmd); + fprintf(stdout, "Try to exec [%s][%s]\n", + item.pkg_type, backend_cmd); + + /* Create args vector + * req_id + pkg_name + args + * + * vector size = # of args + + *(req_id + pkg_name + NULL termination = 3) + * Last value must be NULL for execv. + */ + gboolean ret_parse; + gint argcp; + gchar **argvp; + GError *gerr = NULL; + ret_parse = g_shell_parse_argv(item.args, + &argcp, &argvp, &gerr); + if (FALSE == ret_parse) { + DBG("Failed to split args: %s", item.args); + DBG("messsage: %s", gerr->message); + exit(1); + } + + /* Setup argument !!! */ + /*char **args_vector = + calloc(argcp + 4, sizeof(char *)); */ + char **args_vector = calloc(argcp + 1, sizeof(char *)); + /*args_vector[0] = strdup(backend_cmd); + args_vector[1] = strdup(item.req_id); + args_vector[2] = strdup(item.pkg_name); */ + int arg_idx; + for (arg_idx = 0; arg_idx < argcp; arg_idx++) { + /* args_vector[arg_idx+3] = argvp[arg_idx]; */ + args_vector[arg_idx] = argvp[arg_idx]; + } + + /* dbg */ + /*for(arg_idx = 0; arg_idx < argcp+3; arg_idx++) { */ + for (arg_idx = 0; arg_idx < argcp + 1; arg_idx++) { + DBG(">>>>>> args_vector[%d]=%s", + arg_idx, args_vector[arg_idx]); + } + + /* Execute backend !!! */ + ret = execv(backend_cmd, args_vector); + + /* Code below: exec failure. Should not be happened! */ + DBG(">>>>>> OOPS 2!!!"); + + /* g_strfreev(args_vector); *//* FIXME: causes error */ + + if (ret == -1) { + perror("fail to exec"); + exit(SIGCHLD); + } + _save_queue_status(item, "done"); + if (NULL != backend_cmd) + free(backend_cmd); + exit(SIGCHLD); /* exit with SIGCHLD */ + break; + + case -1: /* error */ + fprintf(stderr, "Fail to execute fork()\n"); + exit(1); + break; + + default: /* parent */ + backend_flag = 1; + DBG("parent \n"); + _save_queue_status(item, "done"); + break; + } + break; + case COMM_REQ_TO_ACTIVATOR: + DBG("activator start"); + _save_queue_status(item, "processing"); + DBG("saved queue status. Now try fork()"); + pid = fork(); + + switch (pid) { + case 0: /* child */ + /* Execute Activator !!! */ + exe_path = __get_exe_path(item.pkg_name); + if (exe_path == NULL) + break; + + if (item.args[0] == '1') /* activate */ + ret = chmod(exe_path, 0755); + else if (item.args[0] == '0') /* deactivate */ + ret = chmod(exe_path, 0000); + else { + DBG("error in args parameter:[%c]\n", + item.args[0]); + exit(SIGCHLD); + } + + free(exe_path); + + if (ret == -1) { + perror("fail to exec"); + exit(SIGCHLD); + } + _save_queue_status(item, "done"); + exit(SIGCHLD); /* exit with SIGCHLD */ + break; + + case -1: /* error */ + fprintf(stderr, "Fail to execute fork()\n"); + exit(1); + break; + + default: /* parent */ + backend_flag = 1; + DBG("parent exit\n"); + _save_queue_status(item, "done"); + break; + } + break; + case COMM_REQ_TO_CLEARER: + DBG("cleaner start"); + _save_queue_status(item, "processing"); + DBG("saved queue status. Now try fork()"); + pid = fork(); + + switch (pid) { + case 0: /* child */ + DBG("before run _get_backend_cmd()"); + backend_cmd = _get_backend_cmd(item.pkg_type); + if (NULL == backend_cmd) + break; + + DBG("Try to exec [%s][%s]", item.pkg_type, + backend_cmd); + fprintf(stdout, "Try to exec [%s][%s]\n", + item.pkg_type, backend_cmd); + + /* Create args vector + * req_id + pkg_name + args + * + * vector size = # of args + + *(req_id + pkg_name + NULL termination = 3) + * Last value must be NULL for execv. + */ + gboolean ret_parse; + gint argcp; + gchar **argvp; + GError *gerr = NULL; + ret_parse = g_shell_parse_argv(item.args, + &argcp, &argvp, &gerr); + if (FALSE == ret_parse) { + DBG("Failed to split args: %s", item.args); + DBG("messsage: %s", gerr->message); + exit(1); + } + + /* Setup argument !!! */ + /*char **args_vector = + calloc(argcp + 4, sizeof(char *)); */ + char **args_vector = calloc(argcp + 1, sizeof(char *)); + /*args_vector[0] = strdup(backend_cmd); + args_vector[1] = strdup(item.req_id); + args_vector[2] = strdup(item.pkg_name); */ + int arg_idx; + for (arg_idx = 0; arg_idx < argcp; arg_idx++) { + /* args_vector[arg_idx+3] = argvp[arg_idx]; */ + args_vector[arg_idx] = argvp[arg_idx]; + } + + /* dbg */ + /*for(arg_idx = 0; arg_idx < argcp+3; arg_idx++) { */ + for (arg_idx = 0; arg_idx < argcp + 1; arg_idx++) { + DBG(">>>>>> args_vector[%d]=%s", + arg_idx, args_vector[arg_idx]); + } + + /* Execute backend !!! */ + ret = execv(backend_cmd, args_vector); + + /* Code below: exec failure. Should not be happened! */ + DBG(">>>>>> OOPS 2!!!"); + + /* g_strfreev(args_vector); *//* FIXME: causes error */ + + if (ret == -1) { + perror("fail to exec"); + exit(SIGCHLD); + } + _save_queue_status(item, "done"); + if (NULL != backend_cmd) + free(backend_cmd); + exit(SIGCHLD); /* exit with SIGCHLD */ + break; + + case -1: /* error */ + fprintf(stderr, "Fail to execute fork()\n"); + exit(1); + break; + + default: /* parent */ + backend_flag = 1; + DBG("parent \n"); + _save_queue_status(item, "done"); + break; + } + break; + default: + break; + } + + return FALSE; +} + +#define IS_WHITESPACE(CHAR) \ +((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE) + +void _app_str_trim(char *input) +{ + char *trim_str = input; + + if (input == NULL) + return; + + while (*input != 0) { + if (!IS_WHITESPACE(*input)) { + *trim_str = *input; + trim_str++; + } + input++; + } + + *trim_str = 0; + return; +} + +char *_get_backend_cmd(char *type) +{ + FILE *fp = NULL; + char buffer[1024] = { 0 }; + char *command = NULL; + int size = 0; + fp = fopen(PKG_CONF_PATH, "r"); + if (fp == NULL) { + return NULL; + } + + char *path = NULL; + while (fgets(buffer, 1024, fp) != NULL) { + if (buffer[0] == '#') + continue; + + _app_str_trim(buffer); + + if ((path = strstr(buffer, PKG_BACKEND)) != NULL) { + DBG("buffer [%s]", buffer); + path = path + strlen(PKG_BACKEND); + DBG("path [%s]", path); + + command = + (char *)malloc(sizeof(char) * strlen(path) + + strlen(type) + 1); + if (command == NULL) { + fclose(fp); + return NULL; + } + + size = strlen(path) + strlen(type) + 1; + snprintf(command, size, "%s%s", path, type); + command[strlen(path) + strlen(type)] = '\0'; + DBG("command [%s]", command); + + if (fp != NULL) + fclose(fp); + + return command; + } + + memset(buffer, 0x00, 1024); + } + + if (fp != NULL) + fclose(fp); + + return NULL; /* cannot find proper command */ +} + +void _pm_desktop_file_monitor_init() +{ + int wd = 0; + int i = 0; + int ret = 0; + + desktop_notifier.ifd = inotify_init(); + if (desktop_notifier.ifd == -1) { + DBG("inotify_init error: %s\n", strerror(errno)); + return; + } + + ret = _pm_desktop_file_dir_search(paths, DESKTOP_FILE_DIRS_NUM); + if (ret) { + DBG("desktop file dir search failed\n"); + return; + } + + for (i = 0; i < DESKTOP_FILE_DIRS_NUM && paths[i].path; i++) { + DBG("Configuration file for desktop file monitoring [%s] is added\n", paths[i].path); + if (access(paths[i].path, R_OK) != 0) { + ecore_file_mkpath(paths[i].path); + if (chmod(paths[i].path, 0777) == -1) { + DBG("cannot chmod %s\n", paths[i].path); + } + } + + wd = inotify_add_watch(desktop_notifier.ifd, paths[i].path, + IN_CREATE | IN_CLOSE_WRITE | IN_MOVED_TO + | IN_DELETE); + if (wd == -1) { + DBG("inotify_add_watch error: %s\n", strerror(errno)); + close(desktop_notifier.ifd); + return; + } + + paths[i].wd = wd; + } + + desktop_notifier.handler = + ecore_main_fd_handler_add(desktop_notifier.ifd, ECORE_FD_READ, + __directory_notify, NULL, NULL, NULL); + if (!desktop_notifier.handler) { + /* TODO: Handle me.. EXCEPTION!! */ + DBG("cannot add handler for inotify\n"); + } +} + +void _pm_desktop_file_monitor_fini() +{ + register int i; + + if (desktop_notifier.handler) { + ecore_main_fd_handler_del(desktop_notifier.handler); + desktop_notifier.handler = NULL; + } + + for (i = 0; i < DESKTOP_FILE_DIRS_NUM; i++) { + if (paths[i].wd) { + if (inotify_rm_watch(desktop_notifier.ifd, paths[i].wd) + < 0) { + DBG("inotify remove watch failed\n"); + } + paths[i].wd = 0; + } + } + + if (desktop_notifier.ifd) { + close(desktop_notifier.ifd); + desktop_notifier.ifd = -1; + } +} + + +int _pm_desktop_file_dir_search(pm_inotify_paths *paths, int number) +{ + char *buf = NULL; + char *noti_dir = NULL; + char *saveptr = NULL; + int len = 0; + int i = 0; + int fd = -1; + int read_size = 0; + + fd = open(DESKTOP_FILE_DIRS, O_RDONLY); + if (fd < 0) { + DBG("Failed to open %s\n", DESKTOP_FILE_DIRS); + return -EFAULT; + } + + if (ioctl(fd, FIONREAD, &read_size) < 0) { + DBG("Failed to get a size of %s file.\n", DESKTOP_FILE_DIRS); + return -EFAULT; + } + + if (read_size <= 0) { + DBG("Buffer is not ready.\n"); + return -EFAULT; + } + + buf = malloc(read_size); + if (!buf) { + DBG("Failed to allocate heap.\n"); + return -EFAULT; + } + + len = read(fd, buf, read_size); + if (len < 0) { + DBG("Failed to read.\n"); + free(buf); + return -EFAULT; + } + + noti_dir = strtok_r(buf, "\n", &saveptr); + if (!noti_dir) { + DBG("Failed to strtok for %s.\n", buf); + free(buf); + return -EFAULT; + } + + do { + char *begin; + + begin = noti_dir; + while (*begin != 0) { + if (isspace(*begin)) + begin++; + else + break; + } + if (*begin == '#' || *begin == 0) { + noti_dir = strtok_r(NULL, "\n", &saveptr); + continue; + } + + paths[i].path = strdup(begin); + noti_dir = strtok_r(NULL, "\n", &saveptr); + i++; + } while (number > i && noti_dir); + + paths[i].path = NULL; + close(fd); + free(buf); + + return EXIT_SUCCESS; +} + +/**< Called before main loop */ +int app_create(void *user_data) +{ + /* printf("called app_create\n"); */ + return 0; +} + +/**< Called after main loop */ +int app_terminate(void *user_data) +{ + /* printf("called app_terminate\n"); */ + return 0; +} + +/**< Called when every window goes back */ +int app_pause(void *user_data) +{ + /* printf("called app_pause\n"); */ + return 0; +} + +/**< Called when any window comes on top */ +int app_resume(void *user_data) +{ + /* printf("called app_resume\n"); */ + return 0; +} + +/**< Called at the first idler*/ +int app_reset(bundle *b, void *user_data) +{ + /* printf("called app_reset\n"); */ + return 0; +} + +int main(int argc, char *argv[]) +{ + FILE *fp_status = NULL; + char buf[32] = { 0, }; + pid_t pid; + char *backend_cmd = NULL; + char *backend_name = NULL; + int r; + + ecore_init(); + + DBG("server start"); + + if (argv[1]) { + if (strcmp(argv[1], "init") == 0) { + /* if current status is "processing", + execute related backend with '-r' option */ + if (!(fp_status = fopen(STATUS_FILE, "r"))) + return 0; /*if file is not exist, terminated. */ + + fgets(buf, 32, fp_status); + /* if processing <-- unintended termination */ + if (strcmp(buf, "processing") == 0) { + pid = fork(); + + if (pid == 0) { /* child */ + fgets(buf, 32, fp_status); + backend_cmd = _get_backend_cmd(buf); + if (!backend_cmd) { /* if NULL, */ + DBG("fail to get" + " backend command"); + goto err; + } + backend_name = + strrchr(backend_cmd, '/'); + + execl(backend_cmd, backend_name, "-r", + NULL); + if (backend_cmd) + free(backend_cmd); + fprintf(fp_status, " "); + err: + fclose(fp_status); + exit(13); + } else if (pid < 0) { /* error */ + DBG("fork fail"); + fclose(fp_status); + return 0; + } else { /* parent */ + + DBG("parent end\n"); + fprintf(fp_status, " "); + fclose(fp_status); + return 0; + } + } + } + } + + _pm_queue_init(); + /*Initialize inotify to monitor desktop file updates */ + _pm_desktop_file_monitor_init(); + + /* init internationalization */ + r = appcore_set_i18n(PACKAGE, LOCALEDIR); + if (r) + return -1; + + g_type_init(); + mainloop = g_main_loop_new(NULL, FALSE); + ecore_main_loop_glib_integrate(); + + struct appdata ad; + struct appcore_ops ops; + ops.create = app_create; + ops.terminate = app_terminate; + ops.pause = app_pause; + ops.resume = app_resume; + ops.reset = app_reset; + ops.data = &ad; + + DBG("Main loop is created."); + + PkgMgrObject *pkg_mgr; + pkg_mgr = g_object_new(PKG_MGR_TYPE_OBJECT, NULL); + pkg_mgr_set_request_callback(pkg_mgr, req_cb, &ad); + DBG("pkg_mgr object is created, and request callback is registered."); + +/* g_timeout_add_seconds(1, queue_job, NULL); */ + DBG("queue function is added to idler. Now run main loop."); + +/* g_main_loop_run(mainloop); */ + appcore_efl_main(PACKAGE, &argc, &argv, &ops); + + DBG("Quit main loop."); + _pm_desktop_file_monitor_fini(); + _pm_queue_final(); + + DBG("package manager server terminated."); + + return 0; +} diff --git a/server/src/pm-queue.c b/server/src/pm-queue.c new file mode 100755 index 0000000..54f4bd6 --- /dev/null +++ b/server/src/pm-queue.c @@ -0,0 +1,248 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "pkgmgr-server.h" +#include "pm-queue.h" + +pm_queue_data *head = NULL; + +void _pm_queue_init() +{ + head = NULL; +} + +void _pm_queue_push(pm_dbus_msg item) +{ + pm_queue_data *data = NULL; + pm_queue_data *cur = NULL; + + cur = head; + + data = _add_node(); + if (!data) { /* fail to allocate mem */ + fprintf(stderr, "Fail to allocate memory\n"); + return; + } + + strncpy(data->msg->req_id, item.req_id, strlen(item.req_id)); + data->msg->req_type = item.req_type; + strncpy(data->msg->pkg_type, item.pkg_type, strlen(item.pkg_type)); + strncpy(data->msg->pkg_name, item.pkg_name, strlen(item.pkg_name)); + strncpy(data->msg->args, item.args, strlen(item.args)); + strncpy(data->msg->cookie, item.cookie, strlen(item.cookie)); + + data->next = NULL; + + if (head == NULL) /* first push */ + head = data; + else { + while (cur->next) + cur = cur->next; + + cur->next = data; + } +} + +pm_dbus_msg _pm_queue_pop() +{ + pm_dbus_msg ret; + pm_queue_data *cur = NULL; + + cur = head; + + memset(&ret, 0x00, sizeof(pm_dbus_msg)); + + if (!head) { /* queue is empty */ + ret.req_type = -1; + return ret; + } + + strncpy(ret.req_id, cur->msg->req_id, strlen(cur->msg->req_id)); + ret.req_type = cur->msg->req_type; + strncpy(ret.pkg_type, cur->msg->pkg_type, strlen(cur->msg->pkg_type)); + strncpy(ret.pkg_name, cur->msg->pkg_name, strlen(cur->msg->pkg_name)); + strncpy(ret.args, cur->msg->args, strlen(cur->msg->args)); + strncpy(ret.cookie, cur->msg->cookie, strlen(cur->msg->cookie)); + + head = cur->next; + cur->next = NULL; + + free(cur->msg); + free(cur); + + return ret; +} + +pm_dbus_msg _pm_queue_get_head() +{ + pm_dbus_msg ret; + pm_queue_data *cur = NULL; + + cur = head; + + memset(&ret, 0x00, sizeof(pm_dbus_msg)); + + if (!head) { /* queue is empty */ + ret.req_type = -1; + return ret; + } + + strncpy(ret.req_id, cur->msg->req_id, strlen(cur->msg->req_id)); + ret.req_type = cur->msg->req_type; + strncpy(ret.pkg_type, cur->msg->pkg_type, strlen(cur->msg->pkg_type)); + strncpy(ret.pkg_name, cur->msg->pkg_name, strlen(cur->msg->pkg_name)); + strncpy(ret.args, cur->msg->args, strlen(cur->msg->args)); + strncpy(ret.cookie, cur->msg->cookie, strlen(cur->msg->cookie)); + + return ret; +} + +void _pm_queue_final() +{ + pm_queue_data *cur = NULL; + pm_queue_data *tail = NULL; + pm_queue_data *prev = NULL; + + if (!head) { /* in case of head is NULL */ + fprintf(stderr, "queue is NULL\n"); + return; + } + + while (head->next) { + cur = head; + + while (cur->next) { + printf(" -- [%p]\n", cur); + prev = cur; + cur = cur->next; + } + + tail = cur; + printf("%p\n", tail); + + free(tail->msg); + free(tail); + prev->next = NULL; + } + + free(head->msg); + free(head); + + head = NULL; +} + +pm_queue_data *_add_node() +{ + pm_queue_data *newnode = NULL; + + newnode = (pm_queue_data *) malloc(sizeof(pm_queue_data)); + if (!newnode) { /* if NULL */ + fprintf(stderr, "Mem alloc error\n"); + return NULL; + } + memset(newnode, 0x00, sizeof(pm_queue_data)); + + newnode->msg = (pm_dbus_msg *) malloc(sizeof(pm_dbus_msg)); + if (!newnode->msg) { + fprintf(stderr, "Mem alloc error\n"); + free(newnode); + return NULL; + } + memset(newnode->msg, 0x00, sizeof(pm_dbus_msg)); + + return newnode; +} + +void _pm_queue_delete(pm_dbus_msg item) +{ + /* Assume that pacakge name is unique */ + pm_queue_data *cur = NULL; + pm_queue_data *prev = NULL; + + cur = head; + prev = cur; + + while (cur->next) { + if (!strcmp(item.pkg_name, cur->msg->pkg_name)) { + prev->next = cur->next; + + free(cur->msg); + free(cur); + + break; + } + + prev = cur; + cur = cur->next; + } +} + +void _save_queue_status(pm_dbus_msg item, char *status) +{ + FILE *fp_status = NULL; + + fp_status = fopen(STATUS_FILE, "w"); /* overwrite always */ + if (!fp_status) { + fprintf(stderr, "Can't open status file:%s\n", STATUS_FILE); + return; + } + + fprintf(fp_status, "%s\n", status); + printf("[%s]\n", status); + fprintf(fp_status, "%s\n", item.pkg_type); + printf("[%s]\n", item.pkg_type); + + fsync(fp_status->_fileno); + fclose(fp_status); +} + +void _print_queue() +{ + pm_queue_data *cur = NULL; + int index = 1; + + cur = head; + + if (!cur) + printf(" ** queue is NULL **\n"); + + while (cur) { + printf(" * queue[%d]: [%s] [%d] [%s] [%s] [%s] [%s]\n", + index, + cur->msg->req_id, + cur->msg->req_type, + cur->msg->pkg_type, + cur->msg->pkg_name, cur->msg->args, cur->msg->cookie); + + index++; + cur = cur->next; + } +} diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..d63ef99 --- /dev/null +++ b/test.sh @@ -0,0 +1,17 @@ + +#export CFLAGS="" +#export LDFLAGS="" + +cd `dirname $0` + +PREFIX=/usr + +rm -rf cmake_tmp +mkdir -p cmake_tmp +cd cmake_tmp + +CFLAGS="${CFLAGS} -g" LDFLAGS="${LDFLAGS}" cmake .. -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_BUILD_TYPE=Debug && +make && +mkdir -p destdir && +make install DESTDIR=destdir + diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt new file mode 100755 index 0000000..97752a9 --- /dev/null +++ b/tool/CMakeLists.txt @@ -0,0 +1,33 @@ +# Test executables +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_CFLAGS}") + +#Verbose +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/client/include ${CMAKE_SOURCE_DIR}/comm) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs_test REQUIRED ecore dbus-1 ail) +FOREACH(flag ${pkgs_test_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" ) +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") + +add_executable(pkgcmd + pkg_cmd.c) +target_link_libraries(pkgcmd pkgmgr-client ${pkgs_test_LDFLAGS}) +INSTALL(TARGETS pkgcmd DESTINATION bin) + +add_executable(pkgmgr-install pkgmgr-install.c) +target_link_libraries(pkgmgr-install pkgmgr-client) +install(TARGETS pkgmgr-install DESTINATION bin) + +configure_file(org.tizen.pkgmgr-install.desktop.in ${CMAKE_BINARY_DIR}/org.tizen.pkgmgr-install.desktop @ONLY) +install(FILES ${CMAKE_BINARY_DIR}/org.tizen.pkgmgr-install.desktop DESTINATION /opt/share/applications/) + +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mime.wac.xml DESTINATION /usr/share/mime/packages/) + diff --git a/tool/mime.wac.xml b/tool/mime.wac.xml new file mode 100644 index 0000000..099c661 --- /dev/null +++ b/tool/mime.wac.xml @@ -0,0 +1,12 @@ + + + + + WAC Widget + WAC 위젯 + WGT + wac WidGeT + + + + diff --git a/tool/org.tizen.pkgmgr-install.desktop.in b/tool/org.tizen.pkgmgr-install.desktop.in new file mode 100755 index 0000000..7f65a6d --- /dev/null +++ b/tool/org.tizen.pkgmgr-install.desktop.in @@ -0,0 +1,9 @@ +Name=pkgmgr-install +Type=Application +Exec=/usr/bin/pkgmgr-install +Hidden=True +Version=0.1 +Mimetype=application/x-deb;application/x-java-archive;text/vnd.sun.j2me.app-descriptor;application/widget;application/vnd.wac.widget-sharing +X-SLP-TaskManage=False +X-SLP-Multiple=True +X-SLP-Removable=False diff --git a/tool/pkg_cmd.c b/tool/pkg_cmd.c new file mode 100755 index 0000000..356f9ae --- /dev/null +++ b/tool/pkg_cmd.c @@ -0,0 +1,536 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "package-manager.h" +#include "package-manager-types.h" + +#define PKG_TOOL_VERSION "0.1" + +static int __process_request(); +static void __print_usage(); +static int __is_authorized(); +static int __is_app_installed(char *pkgname); +static void __print_pkg_info(pkgmgr_info * pkg_info); +static int __iter_fn(const char *pkg_type, const char *pkg_name, + const char *version, void *data); +static int __return_cb(int req_id, const char *pkg_type, const char *pkg_name, + const char *key, const char *val, const void *pmsg, + void *data); + +/* Supported options */ +const char *short_options = "iuclsd:p:t:n:qh"; +const struct option long_options[] = { + {"install", 0, NULL, 'i'}, + {"uninstall", 0, NULL, 'u'}, + {"clear", 0, NULL, 'c'}, + {"list", 0, NULL, 'l'}, + {"show", 0, NULL, 's'}, + {"descriptor", 1, NULL, 'd'}, + {"package-path", 1, NULL, 'p'}, + {"package-type", 1, NULL, 't'}, + {"package-name", 1, NULL, 'n'}, + {"quiet", 0, NULL, 'q'}, + {"help", 0, NULL, 'h'}, + {0, 0, 0, 0} /* sentinel */ +}; + +enum pm_tool_request_e { + INSTALL_REQ = 1, + UNINSTALL_REQ, + CLEAR_REQ, + LIST_REQ, + SHOW_REQ, + HELP_REQ +}; +typedef enum pm_tool_request_e req_type; + +struct pm_tool_args_t { + req_type request; + char pkg_path[PKG_NAME_STRING_LEN_MAX]; + char pkg_type[PKG_TYPE_STRING_LEN_MAX]; + char pkg_name[PKG_NAME_STRING_LEN_MAX]; + char des_path[PKG_NAME_STRING_LEN_MAX]; + int quiet; + int result; +}; +typedef struct pm_tool_args_t pm_tool_args; +pm_tool_args data; + +static GMainLoop *main_loop = NULL; + +static int __iter_fn(const char *pkg_type, const char *pkg_name, + const char *version, void *data) +{ + printf("pkg_type [%s]\tpkg_name [%s]\tversion [%s]\n", pkg_type, + pkg_name, version); + return 0; +} + +static int __return_cb(int req_id, const char *pkg_type, + const char *pkg_name, const char *key, const char *val, + const void *pmsg, void *priv_data) +{ + printf("__return_cb req_id[%d] pkg_type[%s] " + "pkg_name[%s] key[%s] val[%s]\n", + req_id, pkg_type, pkg_name, key, val); + + if (strncmp(key, "end", strlen("end")) == 0) { + if (strncasecmp(val, "ok", strlen("ok")) != 0) + data.result = EXIT_FAILURE; //error_code + + g_main_loop_quit(main_loop); + } + + return 0; +} + +static int __is_app_installed(char *pkgname) +{ + ail_appinfo_h handle; + ail_error_e ret; + char *str = NULL; + ret = ail_package_get_appinfo(pkgname, &handle); + if (ret != AIL_ERROR_OK) { + return -1; + } + ret = ail_appinfo_get_str(handle, AIL_PROP_NAME_STR, &str); + if (ret != AIL_ERROR_OK) { + return -1; + } + ret = ail_package_destroy_appinfo(handle); + if (ret != AIL_ERROR_OK) { + return -1; + } + + return 0; +} + +static void __print_usage() +{ + printf("\nPackage Manager Tool Version: %s\n\n", PKG_TOOL_VERSION); + printf("-i, --install install the package\n"); + printf("-u, --uninstall uninstall the package\n"); + printf("-c, --clear clear user data\n"); + printf("-l, --list display list of installed packages\n"); + printf("-s, --show show detail package info\n"); + printf("-d, --descriptor provide descriptor path\n"); + printf("-p, --package-path provide package path\n"); + printf("-n, --package-name provide package name\n"); + printf("-t, --package-type provide package type\n"); + printf("-q, --quiet quiet mode operation\n"); + printf("-h, --help print this help\n\n"); + printf("Usage: pkgcmd [options] (--quiet)\n"); + printf + ("pkgcmd -i -t (-d ) -p (-q)\n"); + printf("pkgcmd -u -t -n (-q)\n"); + printf("pkgcmd -l \n"); + printf("pkgcmd -s -t -p (-q)\n"); + printf("pkgcmd -s -t -n (-q)\n\n"); + printf("Example:\n"); + printf("pkgcmd -u -t deb -n org.tizen.calculator\n"); + printf("pkgcmd -i -t deb -p /mnt/nfs/org.tizen.calculator_0.1.2-95_armel.deb\n"); + printf("pkgcmd -c -t deb -n org.tizen.hello\n"); + exit(0); + +} + +static void __print_pkg_info(pkgmgr_info *pkg_info) +{ + char *temp = NULL; + + temp = pkgmgr_info_get_string(pkg_info, "pkg_type"); + if (temp) { + printf("pkg_type : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "pkg_name"); + if (temp) { + printf("pkg_name : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "version"); + if (temp) { + printf("version : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "pkg_vendor"); + if (temp) { + printf("pkg_vendor : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "pkg_description"); + if (temp) { + printf("pkg_description : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "pkg_mimetype"); + if (temp) { + printf("pkg_mimetype : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "pkg_installed_path_package"); + if (temp) { + printf("pkg_installed_path_package : %s\n", temp); + free(temp); + } + + temp = + pkgmgr_info_get_string(pkg_info, "pkg_installed_path_descriptor"); + if (temp) { + printf("pkg_installed_path_descriptor : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "category"); + if (temp) { + printf("category : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "min_platform_version"); + if (temp) { + printf("min_platform_version : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "visible"); + if (temp) { + printf("visible : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "removable"); + if (temp) { + printf("removable : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "installed_size"); + if (temp) { + printf("installed_size : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "installed_time"); + if (temp) { + printf("installed_time : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "data_size"); + if (temp) { + printf("data_size : %s\n", temp); + free(temp); + } + + temp = pkgmgr_info_get_string(pkg_info, "optional_id"); + if (temp) { + printf("optional_id : %s\n", temp); + free(temp); + } +} + +static int __process_request() +{ + int ret = -1; + int mode = PM_DEFAULT; + pkgmgr_client *pc = NULL; + switch (data.request) { + case INSTALL_REQ: + if (data.pkg_type[0] == '\0' || data.pkg_path[0] == '\0') { + printf("Please provide the arguments.\n"); + printf("use -h option to see usage\n"); + ret = -1; + break; + } + g_type_init(); + main_loop = g_main_loop_new(NULL, FALSE); + pc = pkgmgr_client_new(PC_REQUEST); + if (pc == NULL) { + printf("PkgMgr Client Creation Failed\n"); + ret = -1; + break; + } + if (data.quiet == 0) + mode = PM_DEFAULT; + else + mode = PM_QUIET; + if (data.des_path[0] == '\0') + ret = + pkgmgr_client_install(pc, data.pkg_type, NULL, + data.pkg_path, NULL, mode, + __return_cb, pc); + else + ret = + pkgmgr_client_install(pc, data.pkg_type, + data.des_path, data.pkg_path, + NULL, mode, __return_cb, pc); + if (ret < 0) + break; + g_main_loop_run(main_loop); + ret = data.result; + break; + + case UNINSTALL_REQ: + if (data.pkg_type[0] == '\0' || data.pkg_name[0] == '\0') { + printf("Please provide the arguments.\n"); + printf("use -h option to see usage\n"); + ret = -1; + break; + } + g_type_init(); + main_loop = g_main_loop_new(NULL, FALSE); + pc = pkgmgr_client_new(PC_REQUEST); + if (pc == NULL) { + printf("PkgMgr Client Creation Failed\n"); + ret = -1; + break; + } + if (data.quiet == 0) + mode = PM_DEFAULT; + else + mode = PM_QUIET; + ret = __is_app_installed(data.pkg_name); + if (ret == -1) { + printf("package is not installed\n"); + break; + } + ret = + pkgmgr_client_uninstall(pc, data.pkg_type, data.pkg_name, + mode, __return_cb, NULL); + if (ret < 0) + break; + g_main_loop_run(main_loop); + ret = data.result; + break; + + case CLEAR_REQ: + if (data.pkg_type[0] == '\0' || data.pkg_name[0] == '\0') { + printf("Please provide the arguments.\n"); + printf("use -h option to see usage\n"); + ret = -1; + break; + } + + pc = pkgmgr_client_new(PC_REQUEST); + if (pc == NULL) { + printf("PkgMgr Client Creation Failed\n"); + ret = -1; + break; + } + if (data.quiet == 0) + mode = PM_DEFAULT; + else + mode = PM_QUIET; + ret = __is_app_installed(data.pkg_name); + if (ret == -1) { + printf("package is not installed\n"); + break; + } + ret = pkgmgr_client_clear_user_data(pc, data.pkg_type, + data.pkg_name, mode); + if (ret < 0) + break; + ret = data.result; + break; + + case LIST_REQ: + ret = pkgmgr_get_pkg_list(__iter_fn, NULL); + break; + + case SHOW_REQ: + if (data.pkg_name[0] != '\0') { + pkgmgr_info *pkg_info = + pkgmgr_info_new(data.pkg_type, data.pkg_name); + if (pkg_info == NULL) { + printf("Failed to get pkginfo handle\n"); + ret = -1; + break; + } + __print_pkg_info(pkg_info); + ret = pkgmgr_info_free(pkg_info); + break; + } + if (data.pkg_path[0] != '\0') { + pkgmgr_info *pkg_info = + pkgmgr_info_new_from_file(data.pkg_type, + data.pkg_path); + if (pkg_info == NULL) { + printf("Failed to get pkginfo handle\n"); + ret = -1; + break; + } + __print_pkg_info(pkg_info); + ret = pkgmgr_info_free(pkg_info); + break; + } + printf("Either pkgname or pkgpath should be supplied\n"); + ret = -1; + break; + + case HELP_REQ: + __print_usage(); + ret = 0; + break; + + default: + printf("Wrong Request\n"); + ret = -1; + break; + } + + if (pc) { + pkgmgr_client_free(pc); + pc = NULL; + } + return ret; +} + +static int __is_authorized() +{ + /* pkgcmd needs root or developer privileges. + If launched via fork/exec, the launching program + must be running as root */ + + uid_t uid = getuid(); + if ((uid_t) 0 == uid || (uid_t) 5100 == uid) + return 1; + else + return 0; +} + +int main(int argc, char *argv[]) +{ + optind = 1; + int opt_idx = 0; + int c = -1; + int ret = -1; + + if (!__is_authorized()) { + printf("You are not an authorized user!\n"); + return -1; + } + + if (argc == 1) + __print_usage(); + + data.request = -1; + memset(data.des_path, '\0', PKG_NAME_STRING_LEN_MAX); + memset(data.pkg_path, '\0', PKG_NAME_STRING_LEN_MAX); + memset(data.pkg_name, '\0', PKG_NAME_STRING_LEN_MAX); + memset(data.pkg_type, '\0', PKG_TYPE_STRING_LEN_MAX); + data.quiet = 0; + data.result = 0; + while (1) { + c = getopt_long(argc, argv, short_options, long_options, + &opt_idx); + if (c == -1) + break; /* Parse end */ + switch (c) { + case 'i': /* install */ + data.request = INSTALL_REQ; + break; + + case 'u': /* uninstall */ + data.request = UNINSTALL_REQ; + break; + + case 'c': /* clear */ + data.request = CLEAR_REQ; + break; + + case 'l': /* list */ + data.request = LIST_REQ; + break; + + case 's': /* show */ + data.request = SHOW_REQ; + break; + + case 'p': /* package path */ + if (optarg) + strncpy(data.pkg_path, optarg, + PKG_NAME_STRING_LEN_MAX); + break; + + case 'd': /* descriptor path */ + if (optarg) + strncpy(data.des_path, optarg, + PKG_NAME_STRING_LEN_MAX); + break; + + case 'n': /* package name */ + if (optarg) + strncpy(data.pkg_name, optarg, + PKG_NAME_STRING_LEN_MAX); + break; + + case 't': /* package type */ + if (optarg) + strncpy(data.pkg_type, optarg, + PKG_TYPE_STRING_LEN_MAX); + break; + + case 'h': /* help */ + data.request = HELP_REQ; + break; + + case 'q': /* quiet mode */ + data.quiet = 1; + break; + + /* Otherwise */ + case '?': /* Not an option */ + __print_usage(); + break; + + case ':': /* */ + break; + + default: + break; + + } + } + ret = __process_request(); + if (ret != 0) { + printf("processing request %d failed\n", data.request); + } + return ret; +} diff --git a/tool/pkgmgr-install.c b/tool/pkgmgr-install.c new file mode 100755 index 0000000..2adbf5d --- /dev/null +++ b/tool/pkgmgr-install.c @@ -0,0 +1,98 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 "package-manager.h" + +#include +#include +#include +#include + +#define KEY_MIME_TYPE "__AUL_MIME_TYPE__" +#define KEY_MIME_CONTENT "__AUL_MIME_CONTENT__" + +char *supported_mime_type_list[] = { + NULL /* sentinel */ +}; + +static int __parse_argv(int argc, char **argv, + char **mime_type, char **file_path); +static const char *__get_ext_from_file_path(const char *file_path); + +static int __parse_argv(int argc, char **argv, + char **mime_type, char **file_path) +{ + static bundle *b = NULL; + if (b) + bundle_free(b); + + b = bundle_import_from_argv(argc, argv); + if (b == NULL) { + fprintf(stderr, "bundle for bundle_import_from_argv is NULL"); + } + + errno = 0; + + *mime_type = (char *)bundle_get_val(b, KEY_MIME_TYPE); + *file_path = (char *)bundle_get_val(b, KEY_MIME_CONTENT); + + if (errno) + return -1; + + return 0; +} + +static const char *__get_ext_from_file_path(const char *file_path) +{ + return strrchr(file_path, '.') + 1; +} + +int main(int argc, char **argv) +{ + char *mime_type; + char *file_path; + + if (__parse_argv(argc, argv, &mime_type, &file_path)) { + fprintf(stderr, "Failed to parse argv!\n"); + return -1; + } + + const char *extension = __get_ext_from_file_path(file_path); + + int req_id; + + pkgmgr_client *pc = pkgmgr_client_new(PC_REQUEST); + req_id = pkgmgr_client_install(pc, extension, NULL, file_path, NULL, + PM_DEFAULT, NULL, NULL); + pkgmgr_client_free(pc); + + sleep(2); + /* Wait until AULD(launchpad) retrives info of this process. + Its timeout is 1.2s. */ + + return 0; +} + diff --git a/tool/stress_test.py b/tool/stress_test.py new file mode 100755 index 0000000..66ab6ae --- /dev/null +++ b/tool/stress_test.py @@ -0,0 +1,36 @@ +#/usr/bin/python +import sys, subprocess + +num_try = 1 +frontends = {} + +if __name__ == "__main__": + + # Run frontends + for i in range(num_try): + p = subprocess.Popen("pkgmgr_frontend_test -n 2>/dev/null 1>/dev/null".split()) + frontends[i] = p + print("Run %d/%d frontend"%(i, num_try)) + + + # wait frontends to be end + done = {} + seq = [] + while True: + for i in frontends: + if not done.has_key(i): + p = frontends[i] + ret = p.poll() + if not None == ret: + print("Frontend #%d is terminated. Returns: %d"%(i, -ret)) + done[i] = -ret + seq.append(i) + if num_try == len(done): + break + + print("Test done.") + for i in frontends: + print("Return code of frontend #%d = %d"%(i, done[i])) + #print("Terminate seq:") + #print(seq) + diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt new file mode 100755 index 0000000..d0c6708 --- /dev/null +++ b/types/CMakeLists.txt @@ -0,0 +1,9 @@ + +CONFIGURE_FILE(pkgmgr-types.pc.in ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-types.pc @ONLY) + +INSTALL(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/package-manager-types.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/package-manager-plugin.h + DESTINATION include) + +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-types.pc DESTINATION lib/pkgconfig) diff --git a/types/include/package-manager-plugin.h b/types/include/package-manager-plugin.h new file mode 100755 index 0000000..50bf5c7 --- /dev/null +++ b/types/include/package-manager-plugin.h @@ -0,0 +1,69 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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 __PKG_MANAGER_PLUGIN_H__ +#define __PKG_MANAGER_PLUGIN_H__ + +#include "package-manager-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*_pkg_plugin_unload) (void); +typedef int (*_pkg_plugin_pkg_is_installed) (const char *pkg_name); +typedef int (*_pkg_plugin_get_installed_pkg_list) (const char *category, + const char *option, + package_manager_pkg_info_t + **list, int *count); +typedef int (*_pkg_plugin_get_pkg_detail_info) (const char *pkg_name, + package_manager_pkg_detail_info_t + *pkg_detail_info); +typedef int (*_pkg_plugin_get_pkg_detail_info_from_package) (const char + *pkg_path, + package_manager_pkg_detail_info_t + *pkg_detail_info); + +typedef struct _pkg_plugin_set { +char pkg_type[PKG_TYPE_STRING_LEN_MAX]; +void *plugin_handle; +_pkg_plugin_unload plugin_on_unload; +_pkg_plugin_pkg_is_installed pkg_is_installed; +_pkg_plugin_get_installed_pkg_list get_installed_pkg_list; +_pkg_plugin_get_pkg_detail_info get_pkg_detail_info; +_pkg_plugin_get_pkg_detail_info_from_package +get_pkg_detail_info_from_package; +} pkg_plugin_set; + +#ifdef __cplusplus +} +#endif + +#endif /* __PKG_MANAGER_PLUGIN_H__ */ diff --git a/types/include/package-manager-types.h b/types/include/package-manager-types.h new file mode 100755 index 0000000..39f9600 --- /dev/null +++ b/types/include/package-manager-types.h @@ -0,0 +1,120 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * 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. + * + */ + + + + + + + + + +/** + * @file package-manager-types.h + * @author Sewook Park + * @version 0.1 + * @brief This file declares slp-pkgmgr-types + * + * @addtogroup APPLICATION_FRAMEWORK + * @{ + * + * @defgroup pacakge_manager_type + * @section Header to use them: + * @code + * #include "package-manager-types.h" + * @endcode + * + * @addtogroup pacakge_manager_type + * @{ + */ + +#ifndef __PKG_MANAGER_TYPES_H__ +#define __PKG_MANAGER_TYPES_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @mainpage + * + * This is package manager + * + * Packaeg manager is used to install/uninstall the packages.\n + * package includes dpkg, java, widget, etc. and it can be added\n + * Security is considered on current package manager\n + * + */ + +/** + * @file package-manager.h + * @brief Package Manager header + * + * Generated by Sewook Park + */ + +#define PKG_TYPE_STRING_LEN_MAX 128 +#define PKG_NAME_STRING_LEN_MAX 128 +#define PKG_VERSION_STRING_LEN_MAX 128 +#define PKG_VALUE_STRING_LEN_MAX 512 +#define PKG_URL_STRING_LEN_MAX 1024 + +/** + *@brief application's structure retrieved by package-manager + */ +typedef struct _package_manager_pkg_info_t { + char pkg_type[PKG_TYPE_STRING_LEN_MAX]; + char pkg_name[PKG_NAME_STRING_LEN_MAX]; + char version[PKG_VERSION_STRING_LEN_MAX]; + struct _package_manager_pkg_info_t *next; +} package_manager_pkg_info_t; + +typedef struct _package_manager_pkg_detail_info_t { + char pkg_type[PKG_TYPE_STRING_LEN_MAX]; + char pkg_name[PKG_NAME_STRING_LEN_MAX]; + char version[PKG_VERSION_STRING_LEN_MAX]; + char pkg_description[PKG_VALUE_STRING_LEN_MAX]; + char min_platform_version[PKG_VERSION_STRING_LEN_MAX]; + time_t installed_time; /* installed time it must be GMT+0 time */ + int installed_size; /* installed total size */ + int app_size; /* installed app size */ + int data_size; /* data size which is made on run time */ + char optional_id[PKG_NAME_STRING_LEN_MAX]; /*package ID if exists */ + void *pkg_optional_info; +} package_manager_pkg_detail_info_t; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PKG_MANAGER_TYPES_H__ */ +/** + * @} + * @} + */ + diff --git a/types/pkgmgr-types.pc.in b/types/pkgmgr-types.pc.in new file mode 100755 index 0000000..0e53688 --- /dev/null +++ b/types/pkgmgr-types.pc.in @@ -0,0 +1,16 @@ +# +# Copyright (c) 2008 ~ 2010 Samsung Electronics Co., Ltd. +# All rights reserved. +# + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: package manager types +Description: SLP package manager's types header +Version: @VERSION@ +Requires: +Libs: +Cflags: -I${includedir} -- 2.7.4