+++ /dev/null
-/*
- * storaged
- * Copyright (c) 2017 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.
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <errno.h>
-
-#include "storaged_common.h"
-#include "log.h"
-#include "dbus.h"
-
-/* 10 seconds */
-#define DBUS_REPLY_TIMEOUT (10000)
-
-int check_systemd_active(void)
-{
- int ret = FALSE;
- GVariant *msg = NULL;
- GVariant *var = NULL;
- char *state;
-
- _I("%s %s", "org.freedesktop.systemd1.Unit", "ActiveState");
-
- msg = dbus_method_sync_with_reply_var("org.freedesktop.systemd1",
- "/org/freedesktop/systemd1/unit/default_2etarget",
- "org.freedesktop.DBus.Properties",
- "Get", g_variant_new("(ss)", "org.freedesktop.systemd1.Unit", "ActiveState"));
- if (!msg)
- return -EBADMSG;
-
- if (!dh_get_param_from_var(msg, "(v)", &var)) {
- _E("reply is not variant type");
- ret = -EBADMSG;
- goto out;
- }
- if (!dh_get_param_from_var(var, "(s)", &state)) {
- _E("variant doesn't have string (%s)", g_variant_get_type_string(var));
- ret = -EBADMSG;
- goto out;
- }
-
- if (strncmp(state, "active", 6) == 0)
- ret = TRUE;
-
- g_free(state);
-out:
- if (var)
- g_variant_unref(var);
- if (msg)
- g_variant_unref(msg);
-
- return ret;
-}
-
-static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM;
-pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-void dbus_handle_set_default_bus_type(GBusType bus_type)
-{
- if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION)
- return ;
-
- pthread_mutex_lock(&g_mutex);
- g_default_bus_type = bus_type;
- pthread_mutex_unlock(&g_mutex);
-}
-
-GBusType dbus_handle_get_default_bus_type(void)
-{
- GBusType type;
-
- pthread_mutex_lock(&g_mutex);
- type = g_default_bus_type;
- pthread_mutex_unlock(&g_mutex);
-
- return type;
-}
-
-typedef struct {
- const char *bus_name;
- guint id;
-} dbus_name;
-
-/* basic information */
-typedef struct {
- GDBusConnection *conn;
- GBusType bus_type;
- gboolean priv;
- GList *list_names; // dbus_name
- GList *list_object; /* dbus_object_handle_s */
- pthread_mutex_t mutex;// = PTHREAD_MUTEX_INITIALIZER;
-} dbus_handle_s;
-
-/* path + interfaces */
-typedef struct {
- dbus_handle_s *dh; /* dbus handle */
- const char *path;
- GList *list_ifaces; /* dbus_interface_s */
-} dbus_object_handle_s;
-
-typedef struct {
- dbus_object_handle_s *oh;
- const char *name;
- GList *list_methods; // const dbus_method_s;
- guint reg_id;
- int modified;
-} dbus_interface_s;
-
-#define get_dh_from_oh(oh) ((dbus_object_handle_s*)oh)->dh
-
-static dbus_handle_s g_dh[2];
-
-static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type);
-
-dbus_handle_s * _dbus_handle_get_default_connection(void)
-{
- return _dbus_handle_get_connection(dbus_handle_get_default_bus_type());
-}
-
-#define dbus_handle_lock(handle) do {\
- assert(handle);\
- pthread_mutex_lock(&((handle)->mutex));\
-} while (0);
-
-#define dbus_handle_unlock(handle) do {\
- assert(handle);\
- pthread_mutex_unlock(&(handle)->mutex);\
-} while (0);
-
-#define dcl_dbus_handle() dbus_handle_s *dh = (dbus_handle_s *)handle;
-#define dcl_dbus_handle_null_check() dbus_handle_s *dh = (dbus_handle_s *)handle;\
- if (!dh) {\
- _E("dbus handle is null\n");\
- return 0;\
- }
-
-dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path);
-dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name);
-dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name);
-static GVariant* _append_variant(const char *signature, const char *param[]);
-
-dbus_interface_s *_iface_u_to_s(const dbus_interface_u *iface_u)
-{
- dbus_interface_s *iface = NULL;
-
- if (!iface_u || !iface_u->methods) {
- _E("param is null");
- return NULL;
- }
-
- iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s));
- if (!iface) {
- _E("failed to calloc");
- return NULL;
- }
-
- iface->name = iface_u->name;
- iface->modified = TRUE;
-
- for (int i = 0 ; i < iface_u->nr_methods; ++i) {
- //_D("attached %s:%p", iface_u->methods[i].member, iface_u->methods[i].func);
- iface->list_methods = g_list_prepend(iface->list_methods, (void*)(iface_u->methods + i));
- }
-
- return iface;
-}
-
-static GDBusConnection * _get_bus(GBusType bus_type)
-{
- GDBusConnection *conn = NULL;
- GError *err = NULL;
-
- if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
- _E("Wrong bus_type %d", bus_type);
- return NULL;
- }
-
- conn = g_bus_get_sync(bus_type, NULL, &err);
- if (!conn || err) {
- _E("failed to get bus:type:%d, %s\n", bus_type, err->message);
- g_error_free(err);
- return NULL;
- }
-
- return conn;
-}
-
-static GDBusConnection * _get_bus_private(GBusType bus_type)
-{
- GError *err = NULL;
- GDBusConnection *conn = NULL;
- const char * address;
-
- if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
- _E("Wrong bus_type %d", bus_type);
- return NULL;
- }
-
- address = g_dbus_address_get_for_bus_sync(bus_type, NULL, &err);
- if (!address || err) {
- _E("failed to get bus address\n");
- g_error_free(err);
- return NULL;
- }
-
- conn = g_dbus_connection_new_for_address_sync(address,
- (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
- G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
- NULL, /* GDBusAuthObserver */
- NULL,
- &err);
- if (!conn || err) {
- _E("failed to get private bus\n");
- g_error_free(err);
- return NULL;
- }
-
- return conn;
-}
-
-/* ref cout is 1 */
-static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type)
-{
- int ibus = bus_type - 1;
- dbus_handle_s *dh = NULL;
-
- if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
- _E("Unknown bus type %d", bus_type);
- return NULL;
- }
- dh = &g_dh[ibus];
-
- dbus_handle_lock(dh);
-
- if (!dh->conn) {
- dh->conn = _get_bus(bus_type);
- dh->priv = FALSE;
- dh->bus_type = bus_type;
- if (!dh->conn)
- dh = NULL;
- }
-
- dbus_handle_unlock(dh);
-
- return dh;
-}
-
-/* ref cout is 1 */
-static dbus_handle_s *_dbus_handle_get_connection_private(GBusType bus_type)
-{
- dbus_handle_s * dh;
-
- if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
- _E("Unknown bus type %d", bus_type);
- return NULL;
- }
-
- dh = (dbus_handle_s *)calloc(1, sizeof(dbus_handle_s));
- if (!dh) {
- _E("failed to allocate memory for dbus handle");
- return NULL;
- }
-
- dbus_handle_lock(dh);
-
- if (!dh->conn) {
- dh->conn = _get_bus_private(bus_type);
- dh->bus_type = bus_type;
- if (!dh->conn)
- goto err;
- }
-
- dbus_handle_unlock(dh);
-
- return dh;
-err:
- if (dh) {
- dbus_handle_unlock(dh);
- free(dh);
- }
- return NULL;
-}
-
-dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv)
-{
- dbus_handle_s *dh = NULL;
-
- if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
- _E("Wrong bus_type %d\n", bus_type);
- return dh;
- }
-
- /* private */
- if (priv)
- dh = _dbus_handle_get_connection_private(bus_type);
- /* shared */
- else
- dh = _dbus_handle_get_connection(bus_type);
-
- return dh;
-}
-
-static void _dbus_handle_add_bus_name(dbus_handle_s *handle, const char *name, guint id)
-{
- dbus_name *dn = NULL;
- int locked = 0;
-
- if (!handle || !name || !id)
- return ;
-
- dn = (dbus_name*)calloc(1, sizeof(dbus_name));
- if (!dn) {
- _E("failed to calloc");
- assert(0);
- }
- dn->bus_name = name;
- dn->id = id;
-
- // todo : delete lock ?
- locked = pthread_mutex_trylock(&handle->mutex);
- if (locked != 0 && locked != EBUSY) {
- _E("failed to lock %d\n", locked);
- assert(0);
- }
-
- handle->list_names = g_list_prepend(handle->list_names, dn);
-
- // todo : delete lock ?
- if (locked != EBUSY)
- dbus_handle_unlock(handle);
-}
-
-static gint _compare_dbus_name(gconstpointer a, gconstpointer b)
-{
- const char *bus_name = ((dbus_name *)a)->bus_name;
- if (!bus_name || !b)
- return -1;
- return strcmp(bus_name, (const char *)b);
-}
-
-dbus_name * _dbus_handle_lookup_dbus_name(GList *list_name, const char *bus_name)
-{
- if (!list_name || !bus_name)
- return NULL;
-
- GList *item = g_list_find_custom(list_name, bus_name, _compare_dbus_name);
- if (!item)
- return NULL;
-
- return (dbus_name *)item->data;
-}
-
-#define dh_to_ds(x) ((dbus_handle_s*)x)
-
-/* remove dbus_name from dbus handle */
-static void _dbus_handle_remove_bus_name(dbus_handle_s *handle, const char *bus_name)
-{
- dcl_dbus_handle();
- dbus_name *dn = NULL;
-
- if (!bus_name) {
- _E("wrong bus_name %s", bus_name);
- return ;
- }
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return ;
- }
- }
-
- dbus_handle_lock(dh);
- dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
- if (!dn) {
- _E("failed to find dbus name %s", bus_name);
- goto out;
- }
- dh->list_names = g_list_remove(dh->list_names, dn);
- free(dn);
-out:
- dbus_handle_unlock(dh);
-}
-
-static void _name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
-{
- dbus_handle_s *dh = (dbus_handle_s *)user_data;
-
- _D("name %s", name);
-
- if (!dh) {
- _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
- return ;
- }
- // todo: add bus name?
- //dh->bus_name = name;
-}
-
-static void _name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
-{
- _E("%s:%d:%s\n", __func__, __LINE__, name);
- dbus_handle_s *dh = (dbus_handle_s *)user_data;
- if (!dh) {
- _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
- return ;
- }
- _dbus_handle_remove_bus_name(dh, name);
-}
-
-int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name)
-{
- dcl_dbus_handle();
- int id = -1;
- GList *item = NULL;
-
- if (!bus_name) {
- _E("bus_name is NULL");
- return -1;
- }
-
- /* get shared connection */
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
-
- dbus_handle_lock(dh);
- if (!dh->conn) {
- _E("failed to register name: connection is null\n");
- goto out;
- }
-
- /* todo : search name on connection */
- item = g_list_find_custom(dh->list_names, bus_name, _compare_dbus_name);
- if (item) {
- id = ((dbus_name*)(item->data))->id;
- _E("name already exist:%u", id);
- goto out;
- }
-
- id = g_bus_own_name_on_connection(dh->conn, bus_name, G_BUS_NAME_OWNER_FLAGS_NONE, _name_acquired, _name_lost, dh, NULL);
- if (!id) {
- _E("failed to own name:%s\n", bus_name);
- goto out;
- }
-
- _dbus_handle_add_bus_name(dh, bus_name, id);
-
-out:
- dbus_handle_unlock(dh);
- return id;
-}
-
-int dbus_handle_release_bus_name(dbus_handle_h handle, const char *bus_name)
-{
- dcl_dbus_handle();
- dbus_name *dn = NULL;
-
- if (!bus_name) {
- _E("Wrong bus name");
- return -1;
- }
-
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
-
- dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
- if (!dn) {
- _E("failed to find bus_name %s on dbus handle", bus_name);
- return -1;
- }
-
- _E("unown name %d", dn->id);
- /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
- g_bus_unown_name(dn->id);
-
- dbus_handle_lock(dh);
- dh->list_names = g_list_remove(dh->list_names, dn);
- free(dn);
- dbus_handle_unlock(dh);
-
- return 0;
-}
-
-int dbus_handle_free_connection(dbus_handle_h handle)
-{
- dcl_dbus_handle();
- dbus_handle_s *pdh = NULL;
- GError *err = NULL;
- GList *item = NULL;
-
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
-
- if (!dh->conn) {
- _E("connection is NULL");
- return 0;
- }
-
- pdh = dh;
-
- /* disable dbus handler */
- dbus_handle_lock(dh);
- if (!pdh->conn) {
- _E("conn is null");
- free(pdh);
- return 0;
- }
-
- /* flush everything */
- if (!g_dbus_connection_flush_sync(pdh->conn, NULL, &err)) {
- _E("failed to flush %s\n", err->message);
- g_error_free(err);
- err = NULL;
- }
-
- _D("list_names %u", g_list_length(pdh->list_names));
-
- /* unown every well-knwon name */
- if (pdh->list_names) {
- dbus_name *dn = NULL;
- for (item = g_list_first(pdh->list_names); item != NULL; item = g_list_next(item)) {
- dn = (dbus_name *)item->data;
- if (!dn)
- continue;
-
- /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
- _D("unown name id : %u", dn->id);
- g_bus_unown_name(dn->id);
- free(dn);
- }
- g_list_free(pdh->list_names);
- pdh->list_names = NULL;
- }
-
- _D("list_object %u", g_list_length(pdh->list_object));
-
- /* unregister every object */
- if (pdh->list_object) {
- dbus_object_handle_s * oh = NULL;
- //g_list_foreach(pdh->list_object, [] (gpointer data, gpointer user_data) {}, NULL);
- for (item = g_list_first(pdh->list_object); item != NULL; item = g_list_next(item)) {
- oh = (dbus_object_handle_s *)item->data;
- if (!oh || !oh->list_ifaces)
- continue;
-
- _D("delete object path %s", oh->path);
-
- /* unregister every interface, method handles */
- for (GList *iface = g_list_first(oh->list_ifaces); iface != NULL; iface = g_list_next(iface)) {
- dbus_interface_s *ih = (dbus_interface_s *)iface->data;
- if (!ih)
- continue;
-
- _D("delete object iface %s", ih->name);
-
- if (ih->reg_id)
- g_dbus_connection_unregister_object(pdh->conn, ih->reg_id);
- }
- }
- }
-
- /* close connection */
- if (pdh->priv) {
- _E("close private connection\n");
-
- if (!g_dbus_connection_close_sync(pdh->conn, NULL, &err)) {
- _E("Error closing connection %s\n", err->message);
- g_error_free(err);
- err = NULL;
- }
- }
-
- /* _free_func_object callback free the data */
- //assert(g_list_length(pdh->list_names) == 0);
- //assert(g_list_length(pdh->list_object) == 0);
-
- g_object_unref(pdh->conn);
-
- dbus_handle_unlock(dh);
-
- if (dh->priv)
- free(dh);
-
- return 0;
-
- // todo: signal ?
-}
-
-#define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0)
-#define buf_block_size 8192
-
-#define buf_check_space_realloc(buf, nwrite, buf_len) do {\
- if ((nwrite >= buf_len - 1024)) {\
- if (buf_len >= buf_block_size * 10) {\
- _E("buf is too big to allocate. %d", buf_len);\
- } else {\
- _E("buf_check_space_realloc");\
- char *tmp = NULL;\
- buf_len += buf_block_size;\
- tmp = (char *)realloc(buf, buf_len);\
- if (!tmp) {\
- _E("failed to realloc");\
- } else\
- buf = tmp;\
- } \
- } \
-} while (0);
-
-static int _check_brace(const char * expr)
-{
- int len = 0;
- char qu[128];
- int qucnt = 0;
-
- if (!expr)
- return -1;
-
- len = strlen(expr);
-
- if (expr[0] != '(' && expr[0] != '{')
- return -1;
-
- for (int i = 0 ; i < len; ++i) {
-
- if (expr[i] == '(' || expr[i] == '{') {
- qu[qucnt++] = expr[i];
- if (qucnt >= sizeof(qu)) {
- _E("queue is too large. %s", expr);
- return -1;
- }
- continue;
- }
-
- if (expr[i] == ')' || expr[i] == '}') {
- char ch;
-
- if (qucnt > 0)
- ch = qu[qucnt-1];
- else
- return -1;
-
- if (expr[i] == ')') {
- if (ch == '(') {
- --qucnt;
- } else
- return -1;
- } else if (expr[i] == '}') {
- if (ch == '{') {
- --qucnt;
- } else
- return -1;
- } else
- return -1;
-
- if (qucnt == 0) {
- return i + 1;
- }
- }
- }
-
- return -1;
-}
-
-static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces)
-{
- int nwrite = 0;
- int len_args;
- char *buf = NULL;
- const dbus_method_s *pmethod;
- int buf_len = buf_block_size;
-
- if (!interfaces) {
- _E("interfaces is null");
- return -1;
- }
-
- // todo : check dbus naming rule for interface name. ?
- if (!interfaces->name) {
- _E("wrong interface name");
- return -1;
- }
- if (!interfaces->list_methods) {
- _E("no methods");
- return -1;
- }
-
- buf = (char *)malloc(buf_len);
- if (!buf) {
- _E("buf is null. not enough memory\n");
- return -1;
- }
-
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "<node>""\n""\t""<interface name='%s'>""\n", interfaces->name);
-
- /* members */
- for (GList *item = g_list_first(interfaces->list_methods); item != NULL; item = g_list_next(item)) {
- pmethod = (const dbus_method_s *)item->data;
- if (!pmethod)
- continue;
-
- /* check free space of buf */
- buf_check_space_realloc(buf, nwrite, buf_len);
-
- if (pmethod->signature_in == NULL && pmethod->signature_out == NULL) {
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'/>""\n", pmethod->member);
- continue;
- }
-
- /* <method name='###'> */
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'>""\n", pmethod->member);
-
- /* in args */
- len_args = pmethod->signature_in ? strlen(pmethod->signature_in) : 0;
- for (int m = 0; m < len_args; ++m) {
- // todo
- // array a(), as, ay ?
- if (pmethod->signature_in[m] == 'a') {
- int ei; //end index
- ei = _check_brace(pmethod->signature_in + m + 1);
- if (ei > 0) {
- char tmp[128] = {0,};
- strncpy(tmp, pmethod->signature_in + m, ei + 1);
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='in'/>""\n", tmp, m);
- m += ei;
- continue;
- } else {
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], pmethod->signature_in[m+1], m);
- m += 1;
- continue;
- }
- }
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], m);
- }
-
- /* out args */
- len_args = pmethod->signature_out ? strlen(pmethod->signature_out) : 0;
- for (int m = 0; m < len_args; ++m) {
- // array
- // todo: container type
- if (pmethod->signature_out[m] == 'a') {
- int ei; //end index
- ei = _check_brace(pmethod->signature_out + m + 1);
- if (ei > 0) {
- char tmp[128] = {0,};
- strncpy(tmp, pmethod->signature_out + m, ei + 1);
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='out'/>""\n", tmp, m);
- m += ei;
- continue;
- } else {
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], pmethod->signature_out[m+1], m);
- m += 1;
- continue;
- }
- }
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], m);
- }
-
- /* </method> */
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""</method>""\n");
- }
-
- nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""</interface>""\n""</node>""");
-
- *xml = buf;
-
- /* todo: delete log */
-#if 0
- if (nwrite <= 512)
- _E("%s", buf);
- else
- _E("%s", buf + nwrite - 512);
-#endif
- return 0;
-}
-
-static gint _compare_dbus_object(gconstpointer a, gconstpointer b)
-{
- dbus_object_handle_s * pa = (dbus_object_handle_s *)a;
- if (!pa->path || !((const char*)b))
- return -1;
- return strcmp(pa->path, (const char*)b);
-}
-
-static gint _compare_dbus_interface(gconstpointer a, gconstpointer b)
-{
- dbus_interface_s * pa = (dbus_interface_s *)a;
- if (!pa->name || !((const char*)b))
- return -1;
- return strcmp(pa->name, (const char*)b);
-}
-
-static gint _compare_dbus_interface_by_id(gconstpointer a, gconstpointer b)
-{
- dbus_interface_s * pa = (dbus_interface_s *)a;
- if (!pa->reg_id || !((guint*)b))
- return -1;
- return !(pa->reg_id == *((guint*)b));
-}
-
-static gint _compare_dbus_method(gconstpointer a, gconstpointer b)
-{
- dbus_method_s *pa = (dbus_method_s*)a;
- if (!pa->member || !((const char*)b))
- return -1;
- return strcmp(pa->member, (const char*)b);
-}
-
-dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path)
-{
- if (!list_obj || !obj_path)
- return NULL;
-
- GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object);
- if (!item)
- return NULL;
-
- return (dbus_object_handle_s *)item->data;
-}
-
-dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name)
-{
- if (!list_iface || !iface_name)
- return NULL;
-
- GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface);
- if (!item)
- return NULL;
-
- return (dbus_interface_s *)item->data;
-}
-
-dbus_interface_s * _dbus_handle_lookup_interface_by_id(GList *list_iface, guint id)
-{
- if (!list_iface || !id)
- return NULL;
-
- GList *item = g_list_find_custom(list_iface, &id, _compare_dbus_interface_by_id);
- if (!item)
- return NULL;
-
- return (dbus_interface_s *)item->data;
-}
-
-dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name)
-{
- if (!list_methods || !method_name)
- return NULL;
-
- GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method);
- if (!item)
- return NULL;
-
- return (dbus_method_s *)item->data;
-}
-
-static void _free_func_object(gpointer data)
-{
- dbus_interface_s *ih = (dbus_interface_s *)data;
- dbus_object_handle_s *oh = NULL;
-
- if (!ih) {
- _E("interface handle is null");
- assert(0); // something wrong
- return ;
- }
-
- _E("unregister interface %s", ih->name);
-
- /* just free list, not data(static dbus_method_s) */
- g_list_free(ih->list_methods);
-
- oh = ih->oh;
- if (!oh) {
- _E("object handle is null");
- assert(0); // something wrong
- return ;
- }
-
- /* remove ih from list_ifaces */
- oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
-
- /* interface_s is copy of interface_u */
- free(ih);
-
- /* remove oh from list_object */
- if (!oh->list_ifaces) {
- oh->dh->list_object = g_list_remove(oh->dh->list_object, oh);
- free(oh);
- }
-}
-
-static int _dbus_handle_attach_object(dbus_handle_s *dh, const char *obj_path, dbus_interface_s *iface)
-{
- dbus_object_handle_s *oh = NULL;
-
- if (!dh || !obj_path || !iface) {
- _E("failed to attache object. wrong parameter");
- return -1;
- }
-
- /* find object handle */
- if (dh->list_object)
- oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
-
- if (!oh) {
- oh = (dbus_object_handle_s*)calloc(1, sizeof(dbus_object_handle_s));
- if (!oh) {
- _E("failed to calloc");
- return -1;
- }
- oh->dh = dh;
- oh->path = obj_path;
-
- /* attach object */
- dh->list_object = g_list_prepend(dh->list_object, oh);
- }
-
- iface->oh = oh;
- /* attach interface */
- oh->list_ifaces = g_list_prepend(oh->list_ifaces, iface);
-
- return 0;
-}
-
-/* libgio verify path and interface */
-static void _method_call_handler(GDBusConnection *conn,
- const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
- GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
-{
- dbus_interface_s *iface_s = (dbus_interface_s *)user_data;
- const dbus_method_s *methods;
- GVariant *result = NULL;
-
- /* todo: ghash ? */
- methods = _dbus_handle_lookup_method(iface_s->list_methods, name);
- if (methods) {
- result = methods->func(conn, sender, path, iface, name, param, invocation, get_dh_from_oh(iface_s->oh));
-
- /* async, maybe they will reply...maybe.. */
- if (!result) {
- _E("finish method handle : NULL");
- return ;
- }
- } else {
- _E("no methods");
- }
-
- g_dbus_method_invocation_return_value(invocation, result);
- //if (g_variant_is_of_type(result, G_VARIANT_TYPE_TUPLE)) {
- // //_E("TUPLE %s", g_variant_get_type_string(result));
- // g_dbus_method_invocation_return_value(invocation, result);
- //}
- //else if (g_variant_is_container(result)) {
- // /* todo: we don't have any plan to using variant type for reply */
- // _E("CONTAINER %s", g_variant_get_type_string(result));
- // g_dbus_method_invocation_return_value(invocation, result);
- // //g_dbus_method_invocation_return_value(invocation, g_variant_new("(v)", result));
- //} else {
- // _E("Type is not Container : %s", g_variant_get_type_string(result));
- //}
-}
-
-static GDBusInterfaceVTable path_vtable = {_method_call_handler};
-
-
-/*
-before register object, attach object into dbus handle
-_dbus_handle_attach_object()
-*/
-static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, dbus_interface_s *iface)
-{
- dcl_dbus_handle();
- int ret = 0;
- char *buf = NULL;
- GError *err = NULL;
- GDBusNodeInfo * nodeinfo = NULL;
- GDBusInterfaceInfo *ifaceinfo = NULL;
-
- if (!obj_path || !iface) {
- _E("wrong parameter\n");
- return -1;
- }
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
- if (!dh->conn) {
- _E("connection is null\n");
- return -1;
- }
-
- ret = _get_xml_from_interfaces(&buf, iface);
- if (ret < 0) {
- _E("failed to make xml format");
- goto err;
- }
-
- /* todo: delete this */
-#if 0
- if (strlen(buf) <= 512) {
- _E("%s", buf);
- } else {
- _E("%s", buf + strlen(buf) - 512);
- }
-#endif
-
- nodeinfo = g_dbus_node_info_new_for_xml(buf, &err);
- if (!nodeinfo || err) {
- _E("failed to make introspection data:err:%s:xml:%s\n", err->message, buf);
- ret = -1;
- goto err;
- }
-
- ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, iface->name);
- if (!ifaceinfo) {
- _E("failed to g_dbus_node_info_lookup_interface");
- ret = -1;
- goto err;
- }
-
- /*
- path own single interface
- if interface is already registered, then failed.
- g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered
- */
- ret = g_dbus_connection_register_object(dh->conn, obj_path, ifaceinfo/*ref 2*/, &path_vtable, (void*)iface,
- _free_func_object,
- &err);
- if (err) {
- _E("failed to register object:err:%s:\n", err->message);
- ret = -1;
- goto err;
- }
-
- iface->reg_id = ret;
- iface->modified = FALSE;
-
-err:
- /* todo: detach object */
- //_dbus_handle_detach_object(dh, obj_path, iface);
- /* attach interface before register object */
- /*ret = _dbus_handle_detach_object(dh, obj_path, iface);
- if (ret < 0) {
- _E("failed to attach object");
- goto err;
- }*/
-
- if (nodeinfo)
- g_dbus_node_info_unref(nodeinfo);
- if (buf)
- free(buf);
- if (err)
- g_error_free(err);
-
- return ret;
-}
-
-/*
-register same interface at once
-
-if interface is constructed by multiple methods,
-also it is not possible to make methods struct at once,
-
-use dbus_handle_add_dbus_object(), dbus_handle_register_dbus_object_all().
-
-return reg_id
-*/
-int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
-{
- dcl_dbus_handle();
- int ret = 0;
- dbus_interface_s *iface = NULL;
-
- if (!obj_path || !iface_u) {
- _E("wrong parameter\n");
- return -1;
- }
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
- if (!dh->conn) {
- _E("connection is null\n");
- return -1;
- }
-
- /* check registered interface */
- if (dh->list_object) {
- dbus_object_handle_s *oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
- if (oh) {
- dbus_interface_s *ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
- if (ih) {
- _E("path %s, interface %s already registered", obj_path, iface_u->name);
- return -1;
- }
- }
- }
-
- iface = _iface_u_to_s(iface_u);
- if (!iface) {
- _E("failed to _iface_u_to_s");
- return -1;
- }
-
- /* attach interface before register object */
- ret = _dbus_handle_attach_object(dh, obj_path, iface);
- if (ret < 0) {
- _E("failed to attach object");
- goto err;
- }
-
- ret = _dbus_handle_register_dbus_object(dh, obj_path, iface);
- if (ret <= 0) {
- _E("failed to register dbus object%d", ret);
- goto err;
- }
-err:
- return ret;
-}
-
-int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path)
-{
- dcl_dbus_handle();
- dbus_object_handle_s *oh = NULL;
- int ret = 0;
-
- if (!obj_path) {
- return -1;
- }
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
- if (!dh->list_object) {
- _E("list_object is empty");
- return 0;
- }
-
- oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
- if (!oh) {
- _E("no object with name %s", obj_path);
- return -1;
- }
-
- /* unregister every interface of object*/
- for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) {
- dbus_interface_s *ih = item->data;
- if (!ih) {
- _E("this is error");
- assert(0);
- }
-
- /* remove ih from list_ifaces */
- if (!ih->reg_id) {
- item = g_list_previous(item);
-
- /* remove and free link */
- oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
-
- /* free list_methods */
- g_list_free(ih->list_methods);
-
- /* free data */
- free(ih);
- continue;
- }
-
- /* unregister object by id */
- ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id);
- if (!ret)
- _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id);
- }
-
- return 0;
-}
-
-/*
-add object temporarily.
-dbus_handle_register_dbus_object_all will register every objects on connection.
-
-return registered method count
-*/
-int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
-{
- dcl_dbus_handle();
- dbus_object_handle_s *oh = NULL;
- dbus_interface_s *ih = NULL;
- int cnt;
-
- if (!obj_path || !iface_u) {
- _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
- return -1;
- }
- if (iface_u && (!iface_u->name || !iface_u->methods)) {
- _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
- return -1;
- }
-
- cnt = iface_u->nr_methods;
-
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
-
- if (!dh->conn) {
- _E("failed to register method. connection is null\n");
- return -1;
- }
-
- /* if there are no object list, just add */
- if (!dh->list_object) {
- if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
- _E("failed to attach object");
- return -1;
- }
- goto out;
- }
-
- oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
- /* if there are no matched object, just add */
- if (!oh) {
- if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
- _E("failed to attach object");
- return -1;
- }
- goto out;
- }
-
- /* this is an error, interface must have one or more item ? */
- if (!oh->list_ifaces) {
- _E("error. list_ifaces is null\n");
- assert(0);
- goto out;
- }
-
- ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
- /* if there are no matched interface, just add */
- if (!ih) {
- if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
- _E("failed to attach object");
- return -1;
- }
- goto out;
- }
-
- /* todo:
- 1. unregister interface
- 2. update interface and methods
- 3. register interface
- */
- if (ih->reg_id) {
- _E("interface already registered, ignore new interface");
- return -1;
- }
-
- /* attach new methods */
- cnt = 0;
- for (int i = 0; i < iface_u->nr_methods; ++i) {
- GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method);
- if (!item) {
- //_D("attached %s", iface_u->methods[i].member);
- ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i));
- ++cnt;
- }
- }
-
- if (cnt)
- ih->modified = TRUE;
-
-out:
- /*todo: delete debugging log */
- //if (dh && dh->list_object)
- // _D("obj list len %d", g_list_length(dh->list_object));
- //if (oh && oh->list_ifaces)
- // _D("iface list len %d", g_list_length(oh->list_ifaces));
- //if (ih && ih->list_methods)
- // _D("method list len %d", g_list_length(ih->list_methods));
-
- return cnt;
-}
-
-int dbus_handle_register_dbus_object_all(dbus_handle_h handle)
-{
- dcl_dbus_handle();
- dbus_object_handle_s *oh = NULL;
- dbus_interface_s *ih = NULL;
- int ret = 0;
-
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
- if (!dh->conn) {
- _E("connection is null\n");
- return -1;
- }
-
- if (!dh->list_object) {
- _E("obj list is empty");
- return -1;
- }
-
- /*if (dh && dh->list_object)
- _D("obj list len %d", g_list_length(dh->list_object));*/
-
- for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) {
- oh = (dbus_object_handle_s *)item->data;
-
- if (!oh) {
- _E("something wrong");
- assert(0);
- }
- if (!oh->list_ifaces) {
- _E("path %s: list_ifaces are null", oh->path);
- goto err;
- }
-
- //_D("iface list len %d", g_list_length(oh->list_ifaces));
-
- for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) {
- ih = (dbus_interface_s *)li->data;
-
- /* if there are no modification, goto next */
- if (!ih->modified)
- continue;
-
- /* todo: if already registered interface, unregister first */
-
- /*_E("interface %s:", ih->name);
- if (ih && ih->list_methods)
- _D("method list len %d", g_list_length(ih->list_methods));*/
-
- ret = _dbus_handle_register_dbus_object(dh, oh->path, ih);
- if (ret <= 0)
- _E("failed to register dbus object%d", ret);
-
- }
- }
- return 0;
-err:
-
- // todo: delete all updates
-
- return -1;
-}
-
-static void _free_func_signal(gpointer data)
-{
- //_D("free signal subscribe");
-}
-
-guint subscribe_dbus_signal(dbus_handle_h handle, const char *path,
- const char *iface, const char *name,
- GDBusSignalCallback cb, void *data,
- destroy_notified free_func)
-{
- dcl_dbus_handle();
-
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return 0;
- }
- }
-
- if (!dh->conn) {
- _E("connection is null. check bus status");
- return 0;
- }
- return g_dbus_connection_signal_subscribe(dh->conn, NULL, iface, name, path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, cb, data, _free_func_signal);
-}
-
-void unsubscribe_dbus_signal(dbus_handle_h handle, guint id)
-{
- dcl_dbus_handle();
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return ;
- }
- }
-
- if (!dh->conn) {
- _E("connection is null. check bus status");
- return ;
- }
-
- g_dbus_connection_signal_unsubscribe(dh->conn, id);
-}
-
-int _check_type_string_is_container(const char *signature)
-{
- if (!signature)
- return FALSE;
-
- switch (signature[0]) {
- case 'a':
- case 'm':
- case 'r':
- case '(':
- case '{':
- case 'v':
- return TRUE;
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
-GVariant *dbus_handle_make_simple_array(const char *sig, int *param)
-{
- GVariantBuilder *builder = NULL;
- GVariant *var = NULL;
- char format[256];
- int i = 0;
-
- builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
- if (!builder) {
- _E("failed to g_variant_builder_new");
- return NULL;
- }
-
- while (param[i])
- g_variant_builder_add(builder, "i", param[i++]);
-
- snprintf(format, sizeof(format) - 1, "(%s)", sig);
- var = g_variant_new(format, builder);
- g_variant_builder_unref(builder);
- return var;
-}
-
-/* todo: looks like garbage... */
-static GVariant* _append_variant(const char *signature, const char *param[])
-{
- char *ch;
- int i;
- int pi;
- int int_type;
- gboolean bool_type;
- unsigned long long int64_type;
- GVariant *ret;
- int len;
- char container[255];// The maximum length of a signature is 255.
- const char *sig = signature;
- GVariantBuilder *builder = NULL;
-
- if (!signature || !param)
- return 0;
-
- /* workaround for user fault "(i) != i" but we treat this as same signature */
- /* G_VARIANT_TYPE("si") return NULL */
- /* todo: actually user have to use correct signature */
- if (!_check_type_string_is_container(signature)) {
- snprintf(container, sizeof(container) - 1, "(%s)", signature);
- sig = container;
- }
- if (!g_variant_type_is_container(G_VARIANT_TYPE(sig))) {
- _E("signature (%s) is not container type", signature);
- }
-
- builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
- len = strlen(sig);
- pi = 0;
- for (ch = (char *)sig, i = 0; i < len; ++i, ++ch) {
- switch (*ch) {
- case '(':
- case ')':
- continue;
- case 'b':
- bool_type = (atoi(param[pi++]) == 0 ? FALSE : TRUE);
- g_variant_builder_add(builder, "b", bool_type);
- break;
- case 'i':
- int_type = atoi(param[pi++]);
- g_variant_builder_add(builder, "i", int_type);
- break;
- case 'u':
- int_type = strtoul(param[pi++], NULL, 10);
- g_variant_builder_add(builder, "u", int_type);
- break;
- case 't':
- int64_type = atoll(param[pi++]);
- g_variant_builder_add(builder, "t", int64_type);
- break;
- case 's':
- g_variant_builder_add(builder, "s", param[pi++]);
- break;
- case 'a':
- ++ch;
- switch (*ch) {
- case 'y':
- g_variant_builder_add(builder, "^ay", param[pi++]);
- ++i;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
- ret = g_variant_builder_end(builder);
- g_variant_builder_clear(builder);
- g_variant_builder_unref(builder);
-
- return ret;
-}
-
-int dbus_handle_broadcast_dbus_signal(const char *path,
- const char *iface, const char *name,
- const char *signature, const char *param[])
-{
- dbus_handle_s *dh = NULL;
- GError *err = NULL;
- gboolean ret = 0;
- GVariant *var = NULL;
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
-
- if (signature && param)
- var = _append_variant(signature, param);
- ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, var, &err);
- if (err) {
- _E("%d %s\n", ret, err ? err->message : NULL);
- g_error_free(err);
- }
-
- return ret;
-}
-
-int dbus_handle_broadcast_dbus_signal_var(const char *path,
- const char *iface, const char *name,
- GVariant *param)
-{
- dbus_handle_s *dh = NULL;
- GError *err = NULL;
- gboolean ret = 0;
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
-
- ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, param, &err);
- if (err) {
- _E("%d %s\n", ret, err ? err->message : NULL);
- g_error_free(err);
- }
-
- return ret;
-}
-
-GVariant *dbus_method_sync_with_reply(const char *dest, const char *path,
- const char *iface, const char *method,
- const char *signature, const char *param[])
-{
- GError *err = NULL;
- GVariant * var = NULL;
- GVariant * ret = NULL;
- dbus_handle_s *dh = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return NULL;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return NULL;
- }
-
- if (signature && param)
- var = _append_variant(signature, param);
-
- ret = g_dbus_connection_call_sync(dh->conn,
- dest, path, iface, method,
- var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
- if (!ret || err) {
- if (err) {
- _E("failed to g_dbus_connection_call_sync:%s", err->message);
- g_error_free(err);
- } else {
- _E("failed to g_dbus_connection_call_sync");
- g_variant_unref(var);
- }
- return NULL;
- }
-
- return ret;
-}
-
-GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path,
- const char *iface, const char *method, GVariant *var)
-{
- GError *err = NULL;
- GVariant * ret = NULL;
- dbus_handle_s *dh = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- if (var)
- g_variant_unref(var);
- return NULL;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- if (var)
- g_variant_unref(var);
- return NULL;
- }
-
- ret = g_dbus_connection_call_sync(dh->conn,
- dest, path, iface, method,
- var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
- if (!ret || err) {
- if (err) {
- _E("failed to g_dbus_connection_call_sync:%s", err->message);
- g_error_free(err);
- } else {
- _E("failed to g_dbus_connection_call_sync");
- }
- return NULL;
- }
-
- return ret;
-}
-
-GVariant *dbus_method_sync_with_reply_var_timeout(const char *dest, const char *path,
- const char *iface, const char *method, GVariant *var, int timeout)
-{
- GError *err = NULL;
- GVariant * ret = NULL;
- dbus_handle_s *dh = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- if (var)
- g_variant_unref(var);
- return NULL;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- if (var)
- g_variant_unref(var);
- return NULL;
- }
-
- ret = g_dbus_connection_call_sync(dh->conn,
- dest, path, iface, method,
- var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err);
- if (!ret || err) {
- if (err) {
- _E("failed to g_dbus_connection_call_sync:%s", err->message);
- g_error_free(err);
- } else {
- _E("failed to g_dbus_connection_call_sync");
- }
- return NULL;
- }
-
- return ret;
-}
-
-gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size)
-{
- GUnixFDList *fd_list = NULL;
- int length = 0;
-
- fd_list = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation));
-
- if (!fd_list) {
- _E("failed to g_unix_fd_list_get_length: fd_list is null");
- return NULL;
- }
-
- length = g_unix_fd_list_get_length(fd_list);
- if (length == 0) {
- _E("failed to g_unix_fd_list_get_length: list size is 0");
- return NULL;
- }
- if (size)
- *size = length;
-
- return g_unix_fd_list_steal_fds(fd_list, NULL);
-}
-
-GVariant *dbus_method_with_unix_fd_list_sync_with_reply(const char *dest, const char *path,
- const char *iface, const char *method,
- const char *signature, const char *param[],
- int *in_fdlist, int in_size,
- int **out_fdlist, int *out_size)
-{
- GError *err = NULL;
- GVariant * var = NULL;
- GVariant * ret = NULL;
- dbus_handle_s *dh = NULL;
- GDBusProxy *proxy = NULL;
- GUnixFDList *g_infdlist = NULL;
- GUnixFDList *g_outfdlist = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return NULL;
- }
- if (in_fdlist && in_size == 0) {
- _E("wrong in_fdlist is not null but in_size is 0");
- return NULL;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return NULL;
- }
-
- if (signature && param)
- var = _append_variant(signature, param);
-
- proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err);
- if (!proxy) {
- if (err) {
- _E("failed to proxy_new_sync(%s)\n", err->message);
- g_error_free(err);
- } else {
- _E("failed to proxy_new_sync\n");
- if (var)
- g_variant_unref(var);
- }
- }
-
- /* append fd */
- if (in_fdlist) {
- g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
- if (!g_infdlist) {
- _E("failed to g_unix_fd_list_new_from_array\n");
- goto out;
- }
- //g_infdlist = g_unix_fd_list_new();
- //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
- }
-
- ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, var, G_DBUS_CALL_FLAGS_NONE, -1,
- g_infdlist, &g_outfdlist, NULL, &err);
- if (!ret || err) {
- if (err) {
- _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message);
- g_error_free(err);
- } else {
- _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:");
- if (var)
- g_variant_unref(var);
- if (g_infdlist)
- g_object_unref(g_infdlist);
- }
- goto out;
- }
-
- /* fds to out array */
- if (g_outfdlist) {
- *out_size = g_unix_fd_list_get_length(g_outfdlist);
- if (*out_size == 0)
- goto out;
-
- *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
- }
-
-out:
- if (g_outfdlist)
- g_object_unref(g_outfdlist);
- if (proxy)
- g_object_unref(proxy);
-
- return ret;
-}
-
-GVariant *dbus_method_with_unix_fd_list_sync_with_reply_var(const char *dest, const char *path,
- const char *iface, const char *method,
- GVariant *param,
- int *in_fdlist, int in_size,
- int **out_fdlist, int *out_size)
-{
- GError *err = NULL;
- GVariant * ret = NULL;
- dbus_handle_s *dh = NULL;
- GDBusProxy *proxy = NULL;
- GUnixFDList *g_infdlist = NULL;
- GUnixFDList *g_outfdlist = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return NULL;
- }
- if (in_fdlist && in_size == 0) {
- _E("wrong in_fdlist is not null but in_size is 0");
- return NULL;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return NULL;
- }
-
- proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err);
- if (!proxy) {
- if (err) {
- _E("failed to proxy_new_sync(%s)\n", err->message);
- g_error_free(err);
- } else {
- _E("failed to proxy_new_sync\n");
- if (param)
- g_variant_unref(param);
- }
- goto out;
- }
-
- /* append fd */
- if (in_fdlist) {
- g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
- if (!g_infdlist) {
- _E("failed to g_unix_fd_list_new_from_array\n");
- goto out;
- }
- //g_infdlist = g_unix_fd_list_new();
- //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
- }
-
- /* send message */
- ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, param, G_DBUS_CALL_FLAGS_NONE, -1,
- g_infdlist, &g_outfdlist, NULL, &err);
- if (!ret || err) {
- if (err) {
- _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message);
- g_error_free(err);
- } else {
- _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:");
- if (param)
- g_variant_unref(param);
- if (g_infdlist)
- g_object_unref(g_infdlist);
- }
- goto out;
- }
-
- /* copy fds to out array */
- if (g_outfdlist) {
- *out_size = g_unix_fd_list_get_length(g_outfdlist);
- if (*out_size == 0)
- goto out;
- *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
- }
-out:
- if (g_outfdlist)
- g_object_unref(g_outfdlist);
- if (proxy)
- g_object_unref(proxy);
- return ret;
-}
-
-int dbus_method_sync(const char *dest, const char *path,
- const char *iface, const char *method,
- const char *signature, const char *param[])
-{
- int result;
- gboolean result_bool;
- GVariant *reply = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return -1;
- }
-
- reply = dbus_method_sync_with_reply(dest, path, iface, method, signature, param);
- if (!reply)
- return -ECOMM;
-
- if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
- g_variant_get(reply, "(i)", &result);
- } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
- g_variant_get(reply, "(b)", &result_bool);
- result = (int)result_bool;
- } else {
- result = -ENOMSG;
- }
-
- g_variant_unref(reply);
-
- return result;
-}
-
-int dbus_method_sync_var(const char *dest, const char *path,
- const char *iface, const char *method, GVariant *param)
-{
- int result;
- gboolean result_bool;
- GVariant *reply = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return -1;
- }
-
- reply = dbus_method_sync_with_reply_var(dest, path, iface, method, param);
- if (!reply)
- return -ECOMM;
-
- if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
- g_variant_get(reply, "(i)", &result);
- } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
- g_variant_get(reply, "(b)", &result_bool);
- result = (int)result_bool;
- } else {
- result = -ENOMSG;
- }
-
- g_variant_unref(reply);
-
- return result;
-}
-
-int dbus_method_sync_timeout(const char *dest, const char *path,
- const char *iface, const char *method,
- const char *signature, const char *param[], int timeout)
-{
- dbus_handle_s *dh = NULL;
- GError *err = NULL;
- GVariant * var = NULL;
- GVariant * reply = NULL;
- int result = 0;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return -1;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -EPERM;
- }
-
- if (signature && param)
- var = _append_variant(signature, param);
-
- reply = g_dbus_connection_call_sync(dh->conn,
- dest, path, iface, method,
- var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err);
- if (!reply || err) {
- _E("failed to g_dbus_connection_call_sync:%s", err->message);
- g_error_free(err);
- return -1;
- }
-
- if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0)
- g_variant_get(reply, "(i)", &result);
- else
- result = -ENOMSG;
-
- g_variant_unref(reply);
-
- return result;
-}
-
-int dbus_method_sync_pairs(const char *dest, const char *path,
- const char *iface, const char *method,
- int num, va_list args)
-{
- GError *err = NULL;
- GVariant * reply = NULL;
- char *key, *value;
- int ret = 0;
- GVariant *var;
- GVariantBuilder *builder;
- dbus_handle_s *dh = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return -1;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
-
- builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
-
- for (int i = 0 ; i < num ; i = i + 2) {
- key = va_arg(args, char *);
- value = va_arg(args, char *);
- _I("key(%s), value(%s)", key, value);
- g_variant_builder_add(builder, "{ss}", key, value);
- }
-
- var = g_variant_new("(a{ss})", builder);
- g_variant_builder_unref(builder);
-
- reply = g_dbus_connection_call_sync(dh->conn,
- dest, path, iface, method,
- var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
- if (!reply || err) {
- _E("failed to g_dbus_connection_call_sync");
- return -1;
- }
-
- if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0)
- g_variant_get(reply, "(i)", &ret);
- else
- ret = -ENOMSG;
-
- g_variant_unref(reply);
-
- return ret;
-}
-
-int dbus_method_async_pairs(const char *dest, const char *path,
- const char *iface, const char *method,
- int num, va_list args)
-{
- char *key, *value;
- GVariant *var;
- GVariantBuilder *builder;
- dbus_handle_s *dh = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return -1;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
-
- // dict
- builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
-
- for (int i = 0 ; i < num ; i = i + 2) {
- key = va_arg(args, char *);
- value = va_arg(args, char *);
- _I("key(%s), value(%s)", key, value);
- g_variant_builder_add(builder, "{ss}", key, value);
- }
-
- var = g_variant_new("(a{ss})", builder);
- g_variant_builder_unref(builder);
-
- g_dbus_connection_call(dh->conn, dest, path, iface, method,
- var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
- NULL,
- NULL);
-
- return 0;
-}
-
-int dbus_method_async(const char *dest, const char *path,
- const char *iface, const char *method,
- const char *signature, const char *param[])
-{
- GVariant * var = NULL;
- dbus_handle_s *dh = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return -1;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
-
- if (signature && param)
- var = _append_variant(signature, param);
-
- g_dbus_connection_call(dh->conn, dest, path, iface, method,
- var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
- NULL,
- NULL);
-
- return 0;
-}
-
-int dbus_method_async_var(const char *dest, const char *path,
- const char *iface, const char *method, GVariant *param)
-{
- dbus_handle_s *dh = NULL;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return -1;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
-
- g_dbus_connection_call(dh->conn, dest, path, iface, method,
- param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
- NULL,
- NULL);
-
- return 0;
-}
-
-/* callback should free gvariant */
-static void _cb_pending(GDBusConnection *conn,
- GAsyncResult *res,
- gpointer user_data)
-{
- GVariant *reply = NULL;
- GError *err = NULL;
- pending_call_data *data = (pending_call_data *)user_data;
-
- reply = g_dbus_connection_call_finish(conn, res, &err);
- if (!reply || err) {
- if (err) {
- _E("no message : [%s]", err->message);
- g_error_free(err);
- } else {
- _E("no message");
- }
-
- if (data && data->func)
- data->func(NULL, data->data, err);
- goto out;
- }
-
- if (data && data->func)
- data->func(reply, data->data, err);
-out:
- if (data)
- free(data);
-}
-
-int dbus_method_async_with_reply(const char *dest,
- const char *path,
- const char *iface,
- const char *method,
- const char *signature,
- const char *param[],
- dbus_pending_cb cb,
- int timeout_msec,
- void *data)
-{
- dbus_handle_s *dh = NULL;
- pending_call_data *pdata = NULL;
- GVariant * var = NULL;
- int ret = 0;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return -1;
- }
-
- if (timeout_msec < -1) {
- _E("wrong timeout %d", timeout_msec);
- return -1;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -EPERM;
- }
-
- if (signature && param)
- var = _append_variant(signature, param);
-
- if (cb) {
- pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
- if (!pdata) {
- ret = -ENOMEM;
- goto err;
- }
-
- pdata->func = cb;
- pdata->data = data;
- }
- g_dbus_connection_call(dh->conn, dest, path, iface, method,
- var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL,
- (GAsyncReadyCallback)_cb_pending,
- pdata);
-
- return ret;
-err:
- if (var)
- g_variant_unref(var);
- return ret;
-}
-
-int dbus_method_async_with_reply_var(const char *dest,
- const char *path,
- const char *iface,
- const char *method,
- GVariant *param,
- dbus_pending_cb cb,
- int timeout_msec,
- void *data)
-{
- dbus_handle_s *dh = NULL;
- pending_call_data *pdata = NULL;
- int ret = 0;
-
- if (!dest || !path || !iface || !method) {
- _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
- return -1;
- }
-
- if (timeout_msec < -1) {
- _E("wrong timeout %d", timeout_msec);
- return -1;
- }
-
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -EPERM;
- }
-
- if (cb) {
- pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
- if (!pdata) {
- ret = -ENOMEM;
- goto err;
- }
-
- pdata->func = cb;
- pdata->data = data;
- }
- g_dbus_connection_call(dh->conn, dest, path, iface, method,
- param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL,
- (GAsyncReadyCallback)_cb_pending,
- pdata);
-
- return ret;
-err:
- if (param)
- g_variant_unref(param);
- return ret;
-}
-
-int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender)
-{
- GError *err = NULL;
- GVariant *vret = NULL;
- pid_t pid = 0;
-
- if (!conn) {
- _E("connection is null");
- return -1;
- }
- if (!sender) {
- _E("sender is null");
- return -1;
- }
-
- vret = g_dbus_connection_call_sync(conn,
- "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetConnectionUnixProcessID",
- g_variant_new("(s)", sender),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- DBUS_REPLY_TIMEOUT,
- NULL,
- &err);
- if (!vret || err) {
- _E("failed to g_dbus_connection_call_sync:%s", err->message);
- g_error_free(err);
- return -1;
- }
-
- g_variant_get(vret, "(u)", &pid);
- g_variant_unref(vret);
-
- return pid;
-}
-
-int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender)
-{
- dcl_dbus_handle();
-
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
- if (!dh->conn) {
- _E("wrong dbus handle. connection is null");
- assert(0);
- return -1;
- }
-
- return dbus_connection_get_sender_pid(dh->conn, sender);
-}
-
-int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds)
-{
- dcl_dbus_handle();
- GVariant *vret = NULL;
- GError *err = NULL;
- GVariantIter *iter = NULL;
- char * item;
- GVariant *sub;
-
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return -1;
- }
- }
- vret = g_dbus_connection_call_sync(dh->conn, DBUS_BUS_NAME, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME,
- "GetConnectionCredentials", g_variant_new("(s)", name), NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
- if (!vret || err) {
- _E("failed to g_dbus_connection_call_sync:%s", err->message);
- return -1;
- }
-
- g_variant_get(vret, "(a{sv})", &iter);
-
- while (g_variant_iter_loop(iter, "{sv}", &item, &sub)) {
- if (!g_strcmp0(item, "UnixUserID")) {
- g_variant_get(sub, "u", &creds->uid);
- _D("UnixUserID %u", creds->uid);
- } else if (!g_strcmp0(item, "ProcessID")) {
- g_variant_get(sub, "u", &creds->pid);
- _D("ProcessID %u", creds->pid);
- } else if (!g_strcmp0(item, "LinuxSecurityLabel")) {
- g_variant_get(sub, "^ay", &creds->sec_label);
- _D("%s", creds->sec_label);
- }
- }
-
- if (iter)
- g_variant_iter_free(iter);
- if (vret)
- g_variant_unref(vret);
-
- return 0;
-}
-
-void _destroy_notify_watch_name(gpointer data)
-{
- if (data)
- free(data);
-}
-
-int dbus_handle_watch_name(const char *name,
- GBusNameAppearedCallback name_appeared_handler,
- GBusNameVanishedCallback name_vanished_handler,
- void *user_data)
-{
- guint id = 0;
-
- if (!name) {
- _E("wrong name name %s", name);
- return -1;
- }
- if (!name_appeared_handler && !name_vanished_handler) {
- _E("both function pointers are null");
- return -1;
- }
-
- id = g_bus_watch_name(dbus_handle_get_default_bus_type(), name, G_BUS_NAME_WATCHER_FLAGS_NONE, name_appeared_handler, name_vanished_handler, user_data, _destroy_notify_watch_name);
- if (!id) {
- _E("failed to g_bus_watch_name");
- return -1;
- }
-
- return id;
-}
-
-void dbus_handle_unwatch_name(guint id)
-{
- if (id == 0) {
- _E("wrong id %d", id);
- return;
- }
- g_bus_unwatch_name(id);
-}
-
-int _get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
-{
- int fd, ret;
- char buf[PATH_MAX + 1];
- char *filename;
-
- snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
- fd = open(buf, O_RDONLY);
- if (fd < 0) {
- errno = ESRCH;
- return -1;
- }
-
- ret = read(fd, buf, PATH_MAX);
- close(fd);
- if (ret < 0)
- return -1;
-
- buf[PATH_MAX] = '\0';
-
- filename = strrchr(buf, '/');
- if (filename == NULL)
- filename = buf;
- else
- filename = filename + 1;
-
- if (cmdline_size < strlen(filename) + 1) {
- errno = EOVERFLOW;
- return -1;
- }
-
- strncpy(cmdline, filename, cmdline_size - 1);
- cmdline[cmdline_size - 1] = '\0';
- return 0;
-}
-
-// g_strfreev(strv)
-char **dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name)
-{
- dcl_dbus_handle();
- GError *err = NULL;
- GVariant *vret = NULL;
- GVariantIter *iter = NULL;
- gchar **strv = NULL;
- gchar *str = NULL;
- int i = 0;
-
- if (!bus_name) {
- _E("wrong parameter bus_name(%s)", bus_name);
- return NULL;
- }
-
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return NULL;
- }
- }
-
- vret = g_dbus_connection_call_sync(dh->conn,
- "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListQueuedOwners",
- g_variant_new("(s)", bus_name),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- DBUS_REPLY_TIMEOUT,
- NULL,
- &err);
- if (!vret || err) {
- _E("failed to g_dbus_connection_call_sync:%s", err->message);
- g_error_free(err);
- return NULL;
- }
-
- g_variant_get(vret, "(as)", &iter);
- strv = g_new(gchar *, g_variant_iter_n_children(iter) + 1);
-
- i = 0;
- while (g_variant_iter_loop(iter, "s", &str))
- strv[i++] = g_strdup(str);
- strv[i] = NULL;
-
- g_variant_iter_free(iter);
- g_variant_unref(vret);
-
- return strv;
-}
-
-void dbush_handle_check_owner_name(dbus_handle_h handle, const char *owner_name)
-{
- dcl_dbus_handle();
- char exe_name[PATH_MAX];
- int pid;
- char **strv = NULL;
- int i;
-
- if (!dh) {
- dh = _dbus_handle_get_default_connection();
- if (!dh) {
- _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
- return ;
- }
- }
-
- strv = dbus_handle_get_owner_list(dh, owner_name);
- if (!strv) {
- _E("failed to get owner list of %s", owner_name);
- return ;
- }
-
- for (i = 0; strv[i] != NULL; ++i) {
- pid = dbus_handle_get_sender_pid(dh, strv[i]);
- if (_get_cmdline_name(pid, exe_name, PATH_MAX) != 0)
- break;
- _I("%s(%d)", exe_name, pid);
- }
-
- g_strfreev(strv);
-}
-
-dbus_handle_h dbus_handle_init(GBusType type, const char* bus_name)
-{
- dbus_handle_h handle = NULL;
- int i, ret = 0;
-
- if (!bus_name) {
- _E("Wrong bus name, %s", bus_name);
- return NULL;
- }
-
- // todo: do we need retry ? - booting time
- for (i = 0 ; i < 3; ++i) {
- handle = dbus_handle_get_connection(type, FALSE);
- if (handle)
- break;
- usleep(5000);
- }
- ret = dbus_handle_request_bus_name(handle, bus_name);
- if (ret <= 0)
- goto out;
-
- dbush_handle_check_owner_name(NULL, bus_name);
-
- return handle;
-
-out:
- return NULL;
-}
-