diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/common/serialization.h | 37 | ||||
-rw-r--r-- | src/include/cchecker/UIBackend.h | 58 | ||||
-rw-r--r-- | src/include/cchecker/popup-runner.h | 50 | ||||
-rw-r--r-- | src/service/app.h | 2 | ||||
-rw-r--r-- | src/service/logic.cpp | 13 | ||||
-rw-r--r-- | src/ui/UIBackend.cpp | 72 | ||||
-rw-r--r-- | src/ui/popup-bin/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/ui/popup-bin/main.cpp | 59 | ||||
-rw-r--r-- | src/ui/popup-bin/popup-service.cpp | 103 | ||||
-rw-r--r-- | src/ui/popup-bin/popup-service.h | 47 | ||||
-rw-r--r-- | src/ui/popup-bin/popup.cpp | 363 | ||||
-rw-r--r-- | src/ui/popup-bin/popup.h | 83 | ||||
-rw-r--r-- | src/ui/popup-client.cpp | 37 | ||||
-rw-r--r-- | src/ui/popup-client.h | 51 | ||||
-rw-r--r-- | src/ui/popup-runner.cpp | 300 |
16 files changed, 499 insertions, 786 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eb61641..25a1363 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,11 +21,9 @@ ############### CERT_CHECKER ############### PKG_CHECK_MODULES(${TARGET_CERT_CHECKER}_DEP REQUIRED - capi-appfw-application dbus-1 dbus-glib-1 db-util - elementary glib-2.0 gio-2.0 icu-i18n @@ -46,8 +44,7 @@ SET(${TARGET_CERT_CHECKER}_SRCS ${CERT_CHECKER_SERVICE_PATH}/certs.cpp ${CERT_CHECKER_SERVICE_PATH}/ocsp-service.cpp ${CERT_CHECKER_DB_PATH}/sql_query.cpp - ${CERT_CHECKER_UI_PATH}/UIBackend.cpp - ${CERT_CHECKER_UI_PATH}/popup-runner.cpp + ${CERT_CHECKER_UI_PATH}/popup-client.cpp ${DPL_CORE_SRC_PATH}/assert.cpp ${DPL_CORE_SRC_PATH}/char_traits.cpp ${DPL_CORE_SRC_PATH}/errno_string.cpp @@ -62,6 +59,7 @@ SET(${TARGET_CERT_CHECKER}_SRCS INCLUDE_DIRECTORIES(SYSTEM ./ ${${TARGET_CERT_CHECKER}_DEP_INCLUDE_DIRS} + ${CERT_CHECKER_SRC_PATH}/ ${CERT_CHECKER_SRC_PATH}/include/ ${DPL_CORE_PATH}/include/ ${DPL_DB_PATH}/include/ diff --git a/src/common/serialization.h b/src/common/serialization.h index fec50c0..3f41d29 100644 --- a/src/common/serialization.h +++ b/src/common/serialization.h @@ -31,6 +31,7 @@ #include <set> #include <memory> +#include "service/app.h" #include "common/command-id.h" namespace CCHECKER { @@ -144,6 +145,20 @@ struct Serialization { Serialize(stream, static_cast<int>(value)); } + // app_t + static void Serialize(IStream &stream, const app_t app) + { + Serialize(stream, app.app_id); + Serialize(stream, app.pkg_id); + Serialize(stream, static_cast<uint32_t>(app.uid)); + Serialize(stream, app.signatures); + Serialize(stream, static_cast<int>(app.verified)); + } + static void Serialize(IStream &stream, const app_t *const p) + { + Serialize(stream, *p); + } + // std::string template <typename T, typename R, typename A> static void Serialize(IStream &stream, const std::basic_string<T, R, A> &str) @@ -394,6 +409,28 @@ struct Deserialization { value = static_cast<CommandId>(val); } + // app_t + static void Deserialize(IStream &stream, app_t &app) + { + Deserialize(stream, app.app_id); + Deserialize(stream, app.pkg_id); + + uint32_t uid; + Deserialize(stream, uid); + app.uid = static_cast<uid_t>(uid); + + Deserialize(stream, app.signatures); + + int val; + Deserialize(stream, val); + app.verified = static_cast<app_t::verified_t>(val); + } + static void Deserialize(IStream &stream, app_t *&p) + { + p = new app_t(); + Deserialize(stream, *p); + } + static void Deserialize(IStream &stream, bool *&value) { value = new bool; diff --git a/src/include/cchecker/UIBackend.h b/src/include/cchecker/UIBackend.h deleted file mode 100644 index c0ff3ab..0000000 --- a/src/include/cchecker/UIBackend.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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 UIBackend.h - * @author Janusz Kozerski <j.kozerski@samsung.com> - * @brief This file declares class for ask user window - */ - -#pragma once - -#include "service/app.h" - -namespace CCHECKER { -namespace UI { - -enum popup_status : int { - NO_ERROR = 0, - EXIT_ERROR = 1 -}; - -enum response_e : int { - DONT_UNINSTALL = 2, - UNINSTALL = 3, - RESPONSE_ERROR = 4 -}; - -class UIBackend { -public: - explicit UIBackend(int timeout = 60); //timeout in seconds (zero or less means infinity) - virtual ~UIBackend(); - - // Displays popup with question, and - if needed - app_control for removing application. - // Returns true if UI was displayed correctly and user's response was collected. - // If there was a problem with displaying UI or a timeout has been reached (no user's response) - // then returns false. - bool call_popup(const app_t &app); - -private: - response_e run(const app_t &app); - - const int m_responseTimeout; // seconds -}; - -} // UI -} // CCHECKER diff --git a/src/include/cchecker/popup-runner.h b/src/include/cchecker/popup-runner.h deleted file mode 100644 index 17aaccd..0000000 --- a/src/include/cchecker/popup-runner.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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 popup-runner.h - * @author Janusz Kozerski (j.kozerski@samsung.com) - * @version 1.0 - */ - -#include <vector> - -#include <cchecker/dpl/serialization.h> - -namespace CCHECKER { -namespace UI { - -class BinaryStream : public CCHECKER::IStream { -public: - void Read(size_t num, void *bytes); - void Write(size_t num, const void *bytes); - - BinaryStream(); - ~BinaryStream(); - - const unsigned char *char_pointer() const; - size_t size() const; - -private: - std::vector<unsigned char> m_data; - size_t m_readPosition; -}; - -response_e run_popup( - const app_t &app, - int timeout); // zero or negative timeout means infinity - -} // UI -} // CCHECKER diff --git a/src/service/app.h b/src/service/app.h index a12703d..dfd2d4c 100644 --- a/src/service/app.h +++ b/src/service/app.h @@ -36,7 +36,7 @@ typedef std::list<std::string> chain_t; typedef std::list<chain_t> signatures_t; struct app_t { - enum class verified_t : int32_t { + enum class verified_t : int { NO = 0, YES = 1, UNKNOWN = 2 diff --git a/src/service/logic.cpp b/src/service/logic.cpp index 0bef2ee..595f00f 100644 --- a/src/service/logic.cpp +++ b/src/service/logic.cpp @@ -26,8 +26,8 @@ #include <set> #include <cchecker/sql_query.h> -#include <cchecker/UIBackend.h> +#include "ui/popup-client.h" #include "common/binary-queue.h" #include "common/log.h" @@ -477,16 +477,15 @@ void Logic::process_queue(void) bool Logic::call_ui(const app_t &app) { - UI::UIBackend ui; - - if (ui.call_popup(app)) { // If calling popup or app_controll service will fail, + UI::PopupClient client; + if (client.dispatch(app)) { // If calling popup or app_controll service will fail, // do not remove application, and ask about it once again later LogDebug("Popup shown correctly. Application will be removed from DB and buffer"); return true; + } else { + LogDebug("Popup error. Application will be marked to show popup later."); + return false; } - - LogDebug("Popup error. Application will be marked to show popup later."); - return false; } bool Logic::process_app(app_t &app) diff --git a/src/ui/UIBackend.cpp b/src/ui/UIBackend.cpp deleted file mode 100644 index 3bd0663..0000000 --- a/src/ui/UIBackend.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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 UIBackend.cpp - * @author Janusz Kozerski <j.kozerski@samsung.com> - * @brief This file implements class for ask user window - */ - -#include <app_control.h> - -#include "common/log.h" -#include <cchecker/UIBackend.h> -#include <cchecker/popup-runner.h> - -namespace CCHECKER { -namespace UI { - -UIBackend::UIBackend(int timeout) : - m_responseTimeout(timeout) -{} - -UIBackend::~UIBackend() -{} - -response_e UIBackend::run(const app_t &app) -{ - return run_popup(app, m_responseTimeout); -} - -bool UIBackend::call_popup(const app_t &app) -{ - response_e resp; - resp = run(app); - LogDebug(app.str() << " response: " << resp); - - if (resp == response_e::RESPONSE_ERROR) { - return false; - } else if (resp == response_e::UNINSTALL) { - app_control_h service = NULL; - int result = 0; - result = app_control_create(&service); - - if (!service || result != APP_CONTROL_ERROR_NONE) { - return false; - } - - app_control_set_operation(service, APP_CONTROL_OPERATION_DEFAULT); - app_control_set_app_id(service, "setting-manage-applications-efl"); - app_control_add_extra_data(service, "viewtype", "application-info"); - app_control_add_extra_data(service, "pkgname", app.pkg_id.c_str()); - app_control_send_launch_request(service, NULL, NULL); - app_control_destroy(service); - } - - return true; -} - -} // UI -} // CCHECKER diff --git a/src/ui/popup-bin/CMakeLists.txt b/src/ui/popup-bin/CMakeLists.txt index a9e7e14..6d434ae 100644 --- a/src/ui/popup-bin/CMakeLists.txt +++ b/src/ui/popup-bin/CMakeLists.txt @@ -22,13 +22,15 @@ PKG_CHECK_MODULES(CERT_CHECKER_POPUP_DEP elementary libtzplatform-config + capi-appfw-application REQUIRED) set(CERT_CHECKER_POPUP_SRC_DIR ${PROJECT_SOURCE_DIR}/src/ui/popup-bin) set(CERT_CHECKER_POPUP_SOURCES + ${CERT_CHECKER_POPUP_SRC_DIR}/main.cpp ${CERT_CHECKER_POPUP_SRC_DIR}/popup.cpp - ${CERT_CHECKER_UI_PATH}/popup-runner.cpp + ${CERT_CHECKER_POPUP_SRC_DIR}/popup-service.cpp ${CERT_CHECKER_SERVICE_PATH}/app.cpp # dpl ${DPL_CORE_SRC_PATH}/assert.cpp diff --git a/src/ui/popup-bin/main.cpp b/src/ui/popup-bin/main.cpp new file mode 100644 index 0000000..8075612 --- /dev/null +++ b/src/ui/popup-bin/main.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 main.cpp + * @author Sangwan Kwon (sangwan.kwon@samsung.com) + * @version 1.0 + * @brief Popup service main + */ +#include <stdexcept> + +#include <Elementary.h> + +#include "common/log.h" +#include "popup-service.h" + +using namespace CCHECKER::UI; + +namespace { +struct ElmRaii { + ElmRaii(int argc, char **argv) { elm_init(argc, argv); } + ~ElmRaii() { elm_shutdown(); } +}; +} // Anonymous namespace + +int main(int argc, char **argv) +{ + try { + LogDebug("Start to run cert-checker popup program."); + setlocale(LC_ALL, ""); + + ElmRaii er(argc, argv); + + PopupService service(POPUP_STREAM); + service.setTimeout(10); + service.start(); + + LogDebug("Finish running cert-checker popup successfully."); + return 0; + } catch (const std::exception &e) { + LogError("Exception occured in popup main : " << e.what()); + return -1; + } catch (...) { + LogError("Unhandled exception occured in popup main."); + return -1; + } +} diff --git a/src/ui/popup-bin/popup-service.cpp b/src/ui/popup-bin/popup-service.cpp new file mode 100644 index 0000000..0fec83e --- /dev/null +++ b/src/ui/popup-bin/popup-service.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 popup-service.cpp + * @author Sangwan Kwon (sangwan.kwon@samsung.com) + * @version 1.0 + * @brief Popup ui service for cert-checker + */ +#include "popup-service.h" + +#include <memory> + +#include <app_control.h> + +#include "popup.h" +#include "service/app.h" +#include "common/binary-queue.h" +#include "common/log.h" + +namespace CCHECKER { +namespace UI { + +namespace { +struct AppControl { + AppControl() { app_control_create(&handle); } + ~AppControl() { app_control_destroy(handle); } + + app_control_h handle; +}; + +bool launchSettingManager(const std::string &pkgId) +{ + LogDebug("Start to launch setting manager about pkg : " << pkgId); + std::unique_ptr<AppControl> ac(new AppControl); + app_control_set_operation(ac->handle, APP_CONTROL_OPERATION_DEFAULT); + app_control_set_app_id(ac->handle, "setting-manage-applications-efl"); + app_control_add_extra_data(ac->handle, "viewtype", "application-info"); + app_control_add_extra_data(ac->handle, "pkgname", pkgId.c_str()); + auto ret = app_control_send_launch_request(ac->handle, NULL, NULL); + return ret == APP_CONTROL_ERROR_NONE; +} +} // Anonymous namespace + +PopupService::PopupService(const std::string &address) : + Service(address) +{ +} + +void PopupService::onMessageProcess(const ConnShPtr &connection) +{ + LogDebug("Start to process message on popup service."); + auto in = connection->receive(); + connection->send(this->process(connection, in)); +} + +RawBuffer PopupService::process(const ConnShPtr &, RawBuffer &data) +{ + LogDebug("Start to receive data from connection."); + BinaryQueue q; + q.push(data); + + app_t app; + q.Deserialize(app); + + LogDebug("Processing popup-service. [" << app.str() << "]"); + Popup popup(app); + auto response = popup.run(); + + switch (response) { + case ResponseType::UNINSTALL : { + LogDebug("User decide to uninstall package."); + if(launchSettingManager(app.pkg_id)) + LogDebug("Success to launch setting manager."); + else + LogError("Failed to launch setting manager."); + return BinaryQueue::Serialize(true).pop(); + } + case ResponseType::KEEP : { + LogDebug("User decide to keep package."); + return BinaryQueue::Serialize(true).pop(); + } + default : { + LogError("Protocol broken on popup-service."); + return BinaryQueue::Serialize(false).pop(); + } + } +} + +} // namespace UI +} // namespace CCHECKER diff --git a/src/ui/popup-bin/popup-service.h b/src/ui/popup-bin/popup-service.h new file mode 100644 index 0000000..93501a7 --- /dev/null +++ b/src/ui/popup-bin/popup-service.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 popup-service.h + * @author Sangwan Kwon (sagnwan.kwon@samsung.com) + * @version 1.0 + * @brief Popup ui service for cert-checker + */ +#pragma once + +#include <string> + +#include "common/service.h" + +namespace CCHECKER { +namespace UI { + +class PopupService : public Service { +public: + PopupService(const std::string &address); + virtual ~PopupService() = default; + + PopupService(const PopupService &) = delete; + PopupService &operator=(const PopupService &) = delete; + PopupService(PopupService &&) = delete; + PopupService &operator=(PopupService &&) = delete; + +private: + virtual void onMessageProcess(const ConnShPtr &) override; + RawBuffer process(const ConnShPtr &, RawBuffer &); +}; + +} // namespace UI +} // namespace CCHECKER diff --git a/src/ui/popup-bin/popup.cpp b/src/ui/popup-bin/popup.cpp index 23003ab..9c5cc92 100644 --- a/src/ui/popup-bin/popup.cpp +++ b/src/ui/popup-bin/popup.cpp @@ -1,311 +1,134 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * - * 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 + * 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 + * 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. + * 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 popup.cpp * @author Janusz Kozerski (j.kozerski@samsung.com) + * @author Sangwan Kwon (sangwan.kwon@samsung.com) * @version 1.0 + * @brief */ +#include "popup.h" -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <vector> -#include <libintl.h> -#include <sys/select.h> -#include <time.h> +#include <memory> +#include <exception> -#include <Elementary.h> - -#include <popup.h> #include "common/log.h" -#include <cchecker/UIBackend.h> -#include <cchecker/popup-runner.h> -#include <cchecker/dpl/serialization.h> -#include <cchecker/dpl/errno_string.h> -#include <cchecker/dpl/exception.h> -#ifndef FD_SETSIZE -#define FD_SETSIZE 1024 -#endif +#define __(str) dgettext(SERVICE_NAME, str) using namespace CCHECKER::UI; -namespace { // anonymous - -void on_done(void) -{ - // Quit the efl-mainloop - LogDebug("elm_exit()"); - elm_exit(); -} - -void keep_answer(void *data, Evas_Object * /* obj */, void * /* event_info */) -{ - LogDebug("keep_answer"); - - if (NULL == data) { - LogError("data is NULL; return"); - return; - } - - struct cert_checker_popup_data *pdp = static_cast <struct cert_checker_popup_data *>(data); - - pdp->result = response_e::DONT_UNINSTALL; - - on_done(); -} - -void uninstall_answer(void *data, Evas_Object * /* obj */, void * /* event_info */) +Popup::Popup(const app_t &app) : m_app(app) { - LogDebug("uninstall_answer"); - - if (NULL == data) { - LogError("data is NULL; return"); - return; - } - - struct cert_checker_popup_data *pdp = static_cast <struct cert_checker_popup_data *>(data); + m_win = elm_win_add(nullptr, "Cert Checker Popup", ELM_WIN_NOTIFICATION); + elm_win_indicator_opacity_set(m_win, ELM_WIN_INDICATOR_TRANSLUCENT); + elm_win_borderless_set(m_win, EINA_TRUE); + elm_win_alpha_set(m_win, EINA_TRUE); - pdp->result = response_e::UNINSTALL; + m_popup = elm_popup_add(m_win); + this->setDefaultProperties(m_popup); - on_done(); -} + m_box = elm_box_add(m_popup); + this->setDefaultProperties(m_box); + evas_object_show(m_box); -void show_popup(struct cert_checker_popup_data *pdp) -{ - LogDebug("show_popup()"); + m_title = elm_label_add(m_box); + setDefaultProperties(m_title); + elm_object_part_text_set(m_popup, "title,text", + __("SID_TITLE_OCSP_VERIFICATION_FAILED")); + elm_box_pack_end(m_box, m_title); + evas_object_show(m_title); - if (NULL == pdp) { - LogError("pdp is NULL; return"); - return; - } + m_content = elm_label_add(m_box); + this->setDefaultProperties(m_content); - pdp->win = elm_win_add(NULL, - dgettext(SERVICE_NAME, "SID_TITLE_OCSP_VERIFICATION_FAILED"), - ELM_WIN_NOTIFICATION); - elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); - elm_win_autodel_set(pdp->win, EINA_TRUE); - evas_object_show(pdp->win); - elm_win_indicator_opacity_set(pdp->win, ELM_WIN_INDICATOR_TRANSLUCENT); - pdp->popup = elm_popup_add(pdp->win); - pdp->box = elm_box_add(pdp->popup); - evas_object_size_hint_weight_set(pdp->box, EVAS_HINT_EXPAND, 0); - evas_object_size_hint_align_set(pdp->box, EVAS_HINT_FILL, 0.0); - pdp->title = elm_label_add(pdp->popup); - elm_object_style_set(pdp->title, "elm.text.title"); - elm_object_text_set(pdp->title, dgettext(SERVICE_NAME, "SID_TITLE_OCSP_VERIFICATION_FAILED")); - evas_object_show(pdp->title); - elm_box_pack_end(pdp->box, pdp->title); - pdp->content = elm_label_add(pdp->popup); - elm_object_style_set(pdp->content, "elm.swallow.content"); - elm_label_line_wrap_set(pdp->content, ELM_WRAP_MIXED); char *buff = NULL; - int ret; - - // Set message - // App ID may be absent, so in that case we need to use only package ID - if (pdp->app_id == std::string(CCHECKER::TEMP_APP_ID)) { - char *content = dgettext(SERVICE_NAME, "SID_CONTENT_OCSP_PACKAGE VERIFICATION_FAILED"); - ret = asprintf(&buff, content, pdp->pkg_id.c_str()); + if (m_app.app_id == std::string(CCHECKER::TEMP_APP_ID)) { + auto content = __("SID_CONTENT_OCSP_PACKAGE VERIFICATION_FAILED"); + if (-1 == asprintf(&buff, content, m_app.pkg_id.c_str())) + throw std::bad_alloc(); } else { - char *content = dgettext(SERVICE_NAME, "SID_CONTENT_OCSP_VERIFICATION_FAILED"); - ret = asprintf(&buff, content, pdp->app_id.c_str(), pdp->pkg_id.c_str()); + auto content = __("SID_CONTENT_OCSP_VERIFICATION_FAILED"); + if (-1 == asprintf(&buff, content, m_app.app_id.c_str(), + m_app.pkg_id.c_str())) + throw std::bad_alloc(); } - - if (-1 == ret) { - LogError("asprintf failed - returned -1"); - evas_object_del(pdp->content); - evas_object_del(pdp->popup); - evas_object_del(pdp->win); - return; - } - - elm_object_text_set(pdp->content, buff); - LogDebug("Popup label: " << buff); + this->setText(m_content, buff); free(buff); - evas_object_size_hint_weight_set(pdp->content, EVAS_HINT_EXPAND, 0.0); - evas_object_size_hint_align_set(pdp->content, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_show(pdp->content); - elm_box_pack_end(pdp->box, pdp->content); - elm_object_part_content_set(pdp->popup, "default", pdp->box); - pdp->keep_button = elm_button_add(pdp->popup); - elm_object_style_set(pdp->keep_button, "elm.swallow.content.button1"); - elm_object_text_set(pdp->keep_button, dgettext(SERVICE_NAME, "SID_BTN_OCSP_KEEP_APP")); - elm_object_part_content_set(pdp->popup, "button1", pdp->keep_button); - evas_object_smart_callback_add(pdp->keep_button, "clicked", keep_answer, pdp); - pdp->uninstall_button = elm_button_add(pdp->popup); - elm_object_style_set(pdp->uninstall_button, "elm.swallow.content.button2"); - elm_object_text_set(pdp->uninstall_button, dgettext(SERVICE_NAME, "SID_BTN_OCSP_UNINSTALL_APP")); - elm_object_part_content_set(pdp->popup, "button2 ", pdp->uninstall_button); - evas_object_smart_callback_add(pdp->uninstall_button, "clicked", uninstall_answer, pdp); - evas_object_show(pdp->popup); - // Showing the popup window - evas_object_show(pdp->win); - // Run the efl mainloop - elm_run(); - // Shutdown elementary - LogDebug("elm_shutdown()"); - elm_shutdown(); + elm_box_pack_end(m_box, m_content); + evas_object_show(m_content); + + elm_object_part_content_set(m_popup, "default", m_box); + + m_keepBtn = elm_button_add(m_popup); + elm_object_style_set(m_keepBtn, "bottom"); + elm_object_text_set(m_keepBtn, __("SID_BTN_OCSP_KEEP_APP")); + elm_object_part_content_set(m_popup, "button1", m_keepBtn); + m_keepType = ResponseType::KEEP; + this->callbackRegister(m_keepBtn, &m_keepType); + evas_object_show(m_keepBtn); + + m_uninstallBtn = elm_button_add(m_popup); + elm_object_style_set(m_uninstallBtn, "bottom"); + elm_object_text_set(m_uninstallBtn, __("SID_BTN_OCSP_UNINSTALL_APP")); + elm_object_part_content_set(m_popup, "button2", m_uninstallBtn); + m_uninstallType = ResponseType::UNINSTALL; + this->callbackRegister(m_uninstallBtn, &m_uninstallType); + evas_object_show(m_uninstallBtn); + + evas_object_show(m_popup); + evas_object_show(m_win); } -static int wait_for_parent_info(int pipe_in) +Popup::~Popup() { - // wait for parameters from pipe_in - // timeout is set for 10 seconds - struct timeval timeout = {10L, 0L}; - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(pipe_in, &readfds); - int sel = select(pipe_in + 1, &readfds, NULL, NULL, &timeout); + evas_object_del(m_win); +} - if (sel == -1) { - int error = errno; - LogError("Cannot get info from parent. Exit popup"); - LogError("Error: " << CCHECKER::GetErrnoString(error)); - close(pipe_in); - return -1; - } else if (sel == 0) { - LogError("Timeout reached! Exit popup - ERROR"); - close(pipe_in); - return -1; - } +int Popup::response = -1; - return 0; +ResponseType Popup::run(void) noexcept +{ + elm_run(); + return static_cast<ResponseType>(response); } -void deserialize(cert_checker_popup_data *pdp, char *line, ssize_t line_length) +void Popup::setDefaultProperties(Evas_Object *obj) noexcept { - BinaryStream stream; - stream.Write(line_length, static_cast <void *>(line)); - std::string app_id; - std::string pkg_id; - LogDebug("------- Deserialization -------"); - // Deserialization order: - // app_id, pkg_id - CCHECKER::Deserialization::Deserialize(stream, app_id); - LogDebug("app_id : " << app_id.c_str()); - pdp->app_id = app_id.c_str(); - CCHECKER::Deserialization::Deserialize(stream, pkg_id); - LogDebug("pkg_id : " << pkg_id.c_str()); - pdp->pkg_id = pkg_id.c_str(); + // Set width as maximum, height as minimum. + evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, 0); + // Set width as fill parent, height as center. + evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, 0.5); } -} // anonymous - -EAPI_MAIN int -elm_main(int argc, char **argv) +void Popup::setText(Evas_Object *obj, const std::string &text) noexcept { - try { - // int pipe_in and int pipe_out should be passed to Popup via args. - // These parameters should be passed to Popup via pipe_in: - // std::string app_id - // std::string pkg_id - struct cert_checker_popup_data pd; - struct cert_checker_popup_data *pdp = &pd; - LogDebug("############################ popup binary ################################"); - setlocale(LC_ALL, ""); - - if (argc < 3) { - LogError("To few args passed in exec to popup-bin - should be at least 3:"); - LogError("(binary-name, pipe_in, pipe_out)"); - LogError("return ERROR"); - return popup_status::EXIT_ERROR; - } - - LogDebug("Passed args: " << argv[0] << ", " << argv[1] << ", " << argv[2]); - int pipe_in; - int pipe_out; - - // Parsing args (pipe_in, pipe_out) - if (0 == sscanf(argv[1], "%d", &pipe_in)) { - LogError("Error while parsing pipe_in; return ERROR"); - return popup_status::EXIT_ERROR; - } - - if (pipe_in < 0 || pipe_in > FD_SETSIZE) { - LogError("fb about pipe_in is in invalid."); - return popup_status::EXIT_ERROR; - } - - if (0 == sscanf(argv[2], "%d", &pipe_out)) { - LogError("Error while parsing pipe_out; return ERROR"); - return popup_status::EXIT_ERROR; - } - - if (pipe_out < 0 || pipe_out > FD_SETSIZE) { - LogError("fb about pipe_out is in invalid."); - close(pipe_in); - return popup_status::EXIT_ERROR; - } - - LogDebug("Parsed pipes: IN: " << pipe_in << ", OUT: " << pipe_out); - - if (wait_for_parent_info(pipe_in) == -1) { - close(pipe_out); - return popup_status::EXIT_ERROR; - } - - int buff_size = 1024; - char line[buff_size]; - ssize_t count = 0; - - do { - count = TEMP_FAILURE_RETRY(read(pipe_in, line, buff_size)); - } while (0 == count); - - if (count < 0) { - int error = errno; - close(pipe_in); - close(pipe_out); - LogError("read returned a negative value (" << count << ")"); - LogError("error: " << CCHECKER::GetErrnoString(error)); - LogError("Exit popup - ERROR"); - return popup_status::EXIT_ERROR; - } - - LogDebug("Read bytes : " << count); - close(pipe_in); // cleanup - deserialize(pdp, line, count); - pdp->result = response_e::RESPONSE_ERROR; - show_popup(pdp); // Showing popup - // sending validation_result to popup-runner - BinaryStream stream_out; - LogDebug("pdp->result : " << pdp->result); - CCHECKER::Serialization::Serialize(stream_out, pdp->result); + // Enable text line-break automatically. + elm_label_line_wrap_set(obj, ELM_WRAP_WORD); + elm_object_text_set(obj, text.c_str()); +} - if (-1 == TEMP_FAILURE_RETRY(write(pipe_out, stream_out.char_pointer(), stream_out.size()))) { - LogError("Write to pipe failed!"); - close(pipe_out); - return popup_status::EXIT_ERROR; - } +void Popup::callbackRegister(Evas_Object *obj, ResponseType *type) noexcept +{ + evas_object_smart_callback_add(obj, "clicked", btnClickedCb, type); +} - close(pipe_out); - LogDebug("############################ /popup binary ################################"); - LogDebug("Return: " << popup_status::NO_ERROR); - return popup_status::NO_ERROR; - } catch (const CCHECKER::Exception &e) { - LogError("Exception occured in popup main."); - return popup_status::EXIT_ERROR; - } catch (const std::exception &e) { - LogError("Exception occured in popup main : " << e.what()); - return popup_status::EXIT_ERROR; - } catch (...) { - LogError("Unhandled exception occured in popup main."); - return popup_status::EXIT_ERROR; - } +void Popup::btnClickedCb(void *data, Evas_Object *, void *) noexcept +{ + response = *(reinterpret_cast<int *>(data)); + LogDebug("Response : " << response); + elm_exit(); } -ELM_MAIN() diff --git a/src/ui/popup-bin/popup.h b/src/ui/popup-bin/popup.h index a9b88b4..3245694 100644 --- a/src/ui/popup-bin/popup.h +++ b/src/ui/popup-bin/popup.h @@ -1,38 +1,75 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * - * 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 + * 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 + * 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. + * 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 popup.h - * @author Janusz Kozerski (j.kozerski@samsung.com) + * @author Sangwan Kwon (sangwan.kwon@samsung.com) * @version 1.0 + * @brief */ +#pragma once #include <Elementary.h> +#include <string> +#include <vector> +#include <memory> -#include <cchecker/UIBackend.h> +#include "service/app.h" -struct cert_checker_popup_data { - std::string app_id; - std::string pkg_id; - CCHECKER::UI::response_e result; +namespace CCHECKER { +namespace UI { - Evas_Object *popup = NULL; - Evas_Object *win = NULL; - Evas_Object *box = NULL; - Evas_Object *title = NULL; - Evas_Object *content = NULL; - Evas_Object *keep_button = NULL; - Evas_Object *uninstall_button = NULL; +enum class ResponseType : int { + KEEP = 0x01, + UNINSTALL = 0x02, }; + +class Popup { +public: + explicit Popup(const app_t &app); + virtual ~Popup(); + + Popup(const Popup &) = delete; + Popup &operator=(const Popup &) = delete; + Popup(Popup &&) = delete; + Popup &operator=(Popup &&) = delete; + + ResponseType run(void) noexcept; + +private: + void callbackRegister(Evas_Object *obj, ResponseType *type) noexcept; + static void btnClickedCb(void *data, Evas_Object *, void *) noexcept; + + void setDefaultProperties(Evas_Object *obj) noexcept; + void setText(Evas_Object *obj, const std::string &text) noexcept; + + Evas_Object *m_win; + Evas_Object *m_popup; + Evas_Object *m_box; + Evas_Object *m_title; + Evas_Object *m_content; + Evas_Object *m_keepBtn; + Evas_Object *m_uninstallBtn; + + static int response; + + ResponseType m_keepType; + ResponseType m_uninstallType; + + app_t m_app; +}; + +} // namespace UI +} // namespace CCHECKER diff --git a/src/ui/popup-client.cpp b/src/ui/popup-client.cpp new file mode 100644 index 0000000..29d4336 --- /dev/null +++ b/src/ui/popup-client.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 popup-client.cpp + * @author Sangwan Kwon (sangwan.kwon@samsung.com) + * @version 1.0 + * @brief Client about popup service + */ +#include "popup-client.h" + +#include "common/log.h" + +using namespace CCHECKER::UI; + +PopupClient::PopupClient() : m_address(POPUP_STREAM) +{ + m_dispatcher.reset(new Dispatcher(m_address)); +} + +bool PopupClient::dispatch(const app_t &app) +{ + LogDebug("Dispatch popup service. app : " << app.str()); + return m_dispatcher->methodCall<bool>(app); +} diff --git a/src/ui/popup-client.h b/src/ui/popup-client.h new file mode 100644 index 0000000..fd13463 --- /dev/null +++ b/src/ui/popup-client.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 popup-client.h + * @author Sangwan Kwon (sangwan.kwon@samsung.com) + * @version 1.0 + * @brief Client about popup service + */ +#pragma once + +#include <string> +#include <memory> + +#include "service/app.h" +#include "common/dispatcher.h" + +namespace CCHECKER { +namespace UI { + +class PopupClient { +public: + PopupClient(); + virtual ~PopupClient() = default; + + PopupClient(const PopupClient &) = delete; + PopupClient &operator=(const PopupClient &) = delete; + PopupClient(PopupClient &&) = delete; + PopupClient &operator=(PopupClient &&) = delete; + + bool dispatch(const app_t &app); + +private: + std::string m_address; + std::unique_ptr<Dispatcher> m_dispatcher; +}; + +} // namespace UI +} // namespace CCHECKER diff --git a/src/ui/popup-runner.cpp b/src/ui/popup-runner.cpp deleted file mode 100644 index 7c2eb2c..0000000 --- a/src/ui/popup-runner.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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 popup-runner.cpp - * @author Janusz Kozerski (j.kozerski@samsung.com) - * @version 1.0 - */ - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <iostream> -#include <sstream> -#include <sys/types.h> -#include <sys/wait.h> - -#include <tzplatform_config.h> - -#include "service/app.h" -#include "service/logic.h" -#include "common/log.h" -#include <cchecker/UIBackend.h> -#include <cchecker/popup-runner.h> - -namespace { // anonymous - -using namespace CCHECKER::UI; - -const char *POPUP_EXEC = tzplatform_mkpath(TZ_SYS_BIN, - "cert-checker-popup"); // check-checker-popup binary - -std::string response_to_str(response_e response) -{ - switch (response) { - case response_e::DONT_UNINSTALL: - return "DONT_UNINSTALL"; - - case response_e::UNINSTALL: - return "UNINSTALL"; - - default: - return "RESPONSE_ERROR"; - } -} - -int wait_for_popup(int popup_pid, int timeout) -{ - int status; - int ret; - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - sigprocmask(SIG_BLOCK, &set, NULL); - siginfo_t info; - struct timespec time = {timeout, 0L}; - - if (timeout > 0) - ret = TEMP_FAILURE_RETRY(sigtimedwait(&set, &info, &time)); - else - ret = TEMP_FAILURE_RETRY(sigwaitinfo(&set, &info)); - - sigprocmask(SIG_UNBLOCK, &set, NULL); - - if (ret == -1 && errno == EAGAIN) { - LogError("POPUP TIMEOUT"); - goto err; - } else if (ret == SIGCHLD && info.si_pid == popup_pid) { - // call waitpid on the child process to get rid of zombie process - waitpid(popup_pid, NULL, 0); - // The proper signal has been caught and its pid matches to popup_pid - // Now check the popup exit status - status = WEXITSTATUS(info.si_status); - LogDebug("STATUS EXIT ON POPUP (CHILD: " << info.si_pid << "): " << status); - - switch (static_cast<popup_status>(status)) { - case popup_status::NO_ERROR: - LogDebug("NO_ERROR"); - return 0; - - case popup_status::EXIT_ERROR: - LogError("ERROR"); - return -1; - - default: // Unknown exit status - LogError("UNKNOWN_ERROR"); - return -1; - } - } else { - LogError("Some other signal has been caught (pid: " << info.si_pid << ", signal: " << info.si_signo - << ")"); - goto err; - } - -err: - // kill popup process and return error - kill(popup_pid, SIGKILL); - // call waitpid on the child process to get rid of zombie process - waitpid(popup_pid, NULL, 0); - return -1; -} - -void child_process(int fd_send_to_child[2], int fd_send_to_parent[2]) -{ - LogDebug("Child"); - // read data from parent - close(fd_send_to_child[1]); - // send data to parent - close(fd_send_to_parent[0]); - std::stringstream pipe_in_buff; - std::stringstream pipe_out_buff; - pipe_in_buff << fd_send_to_parent[1]; - pipe_out_buff << fd_send_to_child[0]; - std::string pipe_in = pipe_in_buff.str(); - std::string pipe_out = pipe_out_buff.str(); - LogDebug("Passed file descriptors: " << fd_send_to_child[0] << ", " << fd_send_to_parent[1]); - - if (execl(POPUP_EXEC, POPUP_EXEC, pipe_out.c_str(), pipe_in.c_str(), NULL) < 0) { - LogError("execl FAILED"); - } - - LogError("This should not happen!!!"); - _exit(response_e::RESPONSE_ERROR); -} - -int send_message_to_child(const BinaryStream &stream, int fd_send_to_child) -{ - LogDebug("Sending message to popup-bin process"); - unsigned int begin = 0; - int tmp; - - while (begin < stream.size()) { - tmp = TEMP_FAILURE_RETRY(write(fd_send_to_child, - stream.char_pointer() + begin, - stream.size() - begin)); - - if (-1 == tmp) { - LogError("Write to pipe failed!"); - return -1; - } - - begin += tmp; - } - - LogDebug("Message has been sent"); - return 0; -} - -response_e parse_response(int count, char *data) -{ - LogDebug("RESULT FROM POPUP PIPE (CHILD) : [ " << count << " ]"); - int response_int; - response_e response; - BinaryStream stream_in; - stream_in.Write(count, data); - CCHECKER::Deserialization::Deserialize(stream_in, response_int); - response = static_cast <response_e>(response_int); - LogDebug("response :" << response_to_str(response)); - return response; -} - -} // anonymous namespace - -namespace CCHECKER { -namespace UI { - -// BinaryStream class implementation -void BinaryStream::Read(size_t num, void *bytes) -{ - size_t max_size = m_data.size(); - - for (size_t i = 0; i < num; ++i) { - if (i + m_readPosition >= max_size) { - return; - } - - static_cast <unsigned char *>(bytes)[i] = m_data[i + m_readPosition]; - } - - m_readPosition += num; -} - -void BinaryStream::Write(size_t num, const void *bytes) -{ - for (size_t i = 0; i < num; ++i) { - m_data.push_back(static_cast <const unsigned char *>(bytes)[i]); - } -} - -BinaryStream::BinaryStream() : - m_readPosition(0) -{} - -BinaryStream::~BinaryStream() {} - -const unsigned char *BinaryStream::char_pointer() const -{ - return &m_data[0]; -} - -size_t BinaryStream::size() const -{ - return m_data.size(); -} -// BinaryStream - -response_e run_popup( - const app_t &app, - int timeout) -{ - LogDebug(app.str()); - // serialization - BinaryStream stream; - CCHECKER::Serialization::Serialize(stream, app.app_id); - CCHECKER::Serialization::Serialize(stream, app.pkg_id); - int fd_send_to_child[2]; - int fd_send_to_parent[2]; - pid_t childpid; - - if (0 != pipe(fd_send_to_child)) { - LogError("Cannot create pipes!"); - return response_e::RESPONSE_ERROR; - } - - if (0 != pipe(fd_send_to_parent)) { - LogError("Cannot create pipes!"); - close(fd_send_to_child[0]); - close(fd_send_to_child[1]); - return response_e::RESPONSE_ERROR; - } - - if ((childpid = fork()) == -1) { - LogError("Fork() ERROR"); - close(fd_send_to_child[0]); - close(fd_send_to_parent[1]); - goto error; - } - - if (childpid == 0) { // Child process - child_process(fd_send_to_child, fd_send_to_parent); - } else { // Parent process - LogDebug("Parent (child pid: " << childpid << ")"); - // send data to child - close(fd_send_to_child[0]); - // read data from child - close(fd_send_to_parent[1]); - - // writing to child - if (send_message_to_child(stream, fd_send_to_child[1])) - goto error; - - // wait for child - if (wait_for_popup(childpid, timeout) != 0) - goto error; - - // Read message from popup (child) - int buff_size = 1024; - char result[buff_size]; - int count; - count = TEMP_FAILURE_RETRY(read(fd_send_to_parent[0], result, buff_size)); - // Parsing response from child - response_e response; - - if (0 < count) { - response = parse_response(count, result); - } else { - LogDebug("ERROR, count = " << count);; - goto error; - } - - LogDebug("popup-runner: EXIT SUCCESS"); - // cleanup - close(fd_send_to_parent[0]); - close(fd_send_to_child[1]); - return response; - } - - LogError("This should not happen!!!"); -error: - // cleanup - LogDebug("popup-runner: EXIT ERROR"); - close(fd_send_to_parent[0]); - close(fd_send_to_child[1]); - return response_e::RESPONSE_ERROR; -} - -} // UI -} // CCHECKER |