+++ /dev/null
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <gio/gio.h>
-#include <dlog.h>
-#include <tzplatform_config.h>
-
-#define UPDATE_BUS_NAME "org.tizen.system.update"
-#define UPDATE_OBJECT_PATH "/Org/Tizen/System/Update"
-
-#define UPDATE_HELPER_PATH "/usr/share/upgrade/update-helper.sh"
-#define UPDATE_RESULT_PATH "/opt/data/update/result"
-
-#define TIMEOUT_INTERVAL 30
-
-#undef LOG_TAG
-#define LOG_TAG "UPDATE_HELPER"
-#define _D(fmt, args...) SLOGD(fmt, ##args)
-#define _E(fmt, args...) SLOGE(fmt, ##args)
-#define _I(fmt, args...) SLOGI(fmt, ##args)
-
-static GMainLoop *loop;
-static GMutex timeout_mutex;
-static guint timeout_id;
-static GDBusNodeInfo *introspection_data;
-static const gchar introspection_xml[] =
-"<node>"
-" <interface name='org.tizen.system.update.Update'>"
-" <method name='do_update'>"
-" <arg type='s' name='pkg_path' direction='in'/>"
-" <arg type='i' name='ret' direction='out'/>"
-" </method>"
-" <method name='get_result'>"
-" <arg type='i' name='ret' direction='out'/>"
-" </method>"
-" </interface>"
-"</node>";
-
-static int system_command(char *command)
-{
- int pid = 0;
- int status = 0;
- const char *environ[] = { NULL };
-
- if (command == NULL)
- return -1;
-
- pid = fork();
- if (pid == -1)
- return -1;
- if (pid == 0) {
- char *argv[4];
- argv[0] = "sh";
- argv[1] = "-c";
- argv[2] = (char *)command;
- argv[3] = 0;
- execve("/bin/sh", argv, (char **)environ);
- exit(127);
- }
- if (pid < 0)
- return -1;
-
- do {
- if (waitpid(pid, &status, 0) == -1) {
- if (errno != EINTR)
- return -1;
- } else {
- if (WIFEXITED(status))
- return WEXITSTATUS(status);
- else if (WIFSIGNALED(status))
- return WTERMSIG(status);
- else if (WIFSTOPPED(status))
- return WSTOPSIG(status);
- }
- } while (!WIFEXITED(status) && !WIFSIGNALED(status));
-
- return 0;
-}
-
-static void exec_update_helper(const char *pkg_path)
-{
- int ret;
- char command[PATH_MAX];
-
- ret = snprintf(command, sizeof(command), "%s %s",
- UPDATE_HELPER_PATH, pkg_path);
- if (ret < 0) {
- _E("Failed to execute update helper");
- return;
- }
- system_command(command);
-}
-
-static int read_result(void)
-{
- int result = -1;
- FILE *fp = NULL;
-
- if (access(UPDATE_RESULT_PATH, F_OK) || !(fp = fopen(UPDATE_RESULT_PATH, "r"))) {
- _E("Fail to open result file: %s", UPDATE_RESULT_PATH);
- return -1;
- }
-
- if (fscanf(fp, "%x", (unsigned int *)&result) == -1) {
- _E("Fail to fscanf");
- fclose(fp);
- return -1;
- }
-
- fclose(fp);
- return result;
-}
-
-static int timeout_cb(gpointer data)
-{
- _I("Time out!");
- g_main_loop_quit((GMainLoop *)data);
-
- return 0;
-}
-
-static void add_timeout(void)
-{
- g_mutex_lock(&timeout_mutex);
-
- if (timeout_id)
- g_source_remove(timeout_id);
- timeout_id = g_timeout_add_seconds(TIMEOUT_INTERVAL, timeout_cb, loop);
-
- g_mutex_unlock(&timeout_mutex);
- _I("Add loop timeout (%d)", TIMEOUT_INTERVAL);
-}
-
-static void remove_timeout(void)
-{
- g_mutex_lock(&timeout_mutex);
-
- if (timeout_id) {
- g_source_remove(timeout_id);
- timeout_id = 0;
- }
-
- g_mutex_unlock(&timeout_mutex);
- _I("Remove loop timeout");
-}
-
-static void method_call_handler(GDBusConnection *conn,
- const gchar *sender,
- const gchar *object_path,
- const gchar *iface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- gpointer user_data)
-{
- int ret = 0;
- const gchar *arg;
-
- remove_timeout();
-
- if (g_strcmp0(method_name, "do_update") == 0) {
- g_variant_get(parameters, "(&s)", &arg);
- _D("Update package path: %s", arg);
- exec_update_helper(arg);
- } else if (g_strcmp0(method_name, "get_result") == 0) {
- if ((ret = read_result()) < 0)
- _E("Failed to read_result");
- }
-
- g_dbus_method_invocation_return_value(invocation,
- g_variant_new("(i)", ret));
-
- add_timeout();
-}
-
-static const GDBusInterfaceVTable interface_vtable = {
- method_call_handler,
- NULL,
- NULL
-};
-
-static void on_bus_acquired(GDBusConnection *conn,
- const gchar *name,
- gpointer user_data)
-{
- guint registration_id;
-
- registration_id = g_dbus_connection_register_object(conn,
- UPDATE_OBJECT_PATH, introspection_data->interfaces[0],
- &interface_vtable, NULL, NULL, NULL);
- if (registration_id == 0)
- _E("Failed to g_dbus_connection_register_object");
-}
-
-static void on_name_acquired(GDBusConnection *conn,
- const gchar *name,
- gpointer user_data)
-{
- _D("Acquired the name %s on the system bus", name);
-}
-
-static void on_name_lost(GDBusConnection *conn,
- const gchar *name,
- gpointer user_data)
-{
- _D("Lost the name %s on the system bus", name);
-}
-
-static void dbus_init(void)
-{
- GDBusConnection *conn = NULL;
- GError *error = NULL;
-
- introspection_data =
- g_dbus_node_info_new_for_xml(introspection_xml, NULL);
- if (introspection_data == NULL) {
- _E("Failed to init g_dbus_info_new_for_xml");
- return;
- }
-
- conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
- if (!conn) {
- _E("Failed to get dbus");
- return;
- }
-
- if (error) {
- _E("Failed to get dbus: %s", error->message);
- g_error_free(error);
- return;
- }
-
- g_bus_own_name(G_BUS_TYPE_SYSTEM, UPDATE_BUS_NAME,
- G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired,
- on_name_acquired, on_name_lost, NULL, NULL);
-}
-
-int main(int argc, char **argv)
-{
- loop = g_main_loop_new(NULL, false);
-
- dbus_init();
-
- g_mutex_init(&timeout_mutex);
- add_timeout();
-
- _I("update_helper activated");
- g_main_loop_run(loop);
-
- if (introspection_data)
- g_dbus_node_info_unref(introspection_data);
- g_mutex_clear(&timeout_mutex);
- g_main_loop_unref(loop);
-
- return 0;
-}