您的位置:首页 > 其它

一个简单的dbus服务器及其客户端

2013-06-13 23:20 417 查看
由于systemd合并udev之后,咱们就不能再用udev的规则来挂接移动硬盘了

所以决定利用dbus的机制来规避systemd对于cgroup控制导致的挂接移动硬盘问题

开发一个简单的dbus服务器,其功能很简单,接收从客户端过来的命令参数,然后调用system()来执行

这当然是有安全问题的,但在自己的机器使用,谁管呢

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-bindings.h>
#include <glib-object.h>
#include "dbus_exec_cmd.h"
#include "simple_exec_glue.h"

/* Generate the GObject boilerplate */
G_DEFINE_TYPE(DbusExecCmd, dbus_exec_cmd, G_TYPE_OBJECT)

GQuark simple_exec_error (void)
{
static GQuark quark = 0;
if (!quark)
quark = g_quark_from_static_string ("simple_exec_error");
return quark;
}

/* Class init */
static void dbus_exec_cmd_class_init (DbusExecCmdClass *dbus_exec_cmd_class)
{
dbus_g_object_type_install_info (G_OBJECT_CLASS_TYPE (dbus_exec_cmd_class), &dbus_glib_simple_exec_object_info);
}

/* Instance init */
static void dbus_exec_cmd_init (DbusExecCmd *dbus_exec_cmd)
{
}

gboolean simple_exec_command(DbusExecCmd *exec_cmd, const char* cmd_str, GError **error)
{
int status;
g_print ("[Simple Dbus Exec]Start to execute: %s\n", cmd_str);
status = system(cmd_str);
if (0 != status)
{
/* We have an error, set the gerror */
g_set_error (error, simple_exec_error(), 1, "[Simple Dbus Exec]fail to execute command:%s\n", cmd_str);
g_warning("[Simple Dbus Exec]fail to execute: %s, error: %d\n", cmd_str, status);

return FALSE;
}
if(WIFEXITED(status))
{
g_warning("normal termination, exit status = %d\n", WEXITSTATUS(status)); //鍙栧緱cmdstring鎵ц缁撴灉
}
else if(WIFSIGNALED(status))
{
g_warning("abnormal termination,signal number =%d\n", WTERMSIG(status)); //濡傛灉cmdstring琚俊鍙蜂腑鏂紝鍙栧緱淇″彿鍊?    }
else if(WIFSTOPPED(status))
{
g_warning("process stopped, signal number =%d\n", WSTOPSIG(status)); //濡傛灉cmdstring琚俊鍙锋殏鍋滄墽琛岋紝鍙栧緱淇″彿鍊?    }
g_print ("[Simple Dbus Exec]Finish to execute command\n");

return TRUE;
}

static void die (const char *prefix, GError *error)
{
g_error("%s: %s", prefix, error->message);
g_error_free (error);
exit(1);
}

#define SIMPLE_EXEC_SERVICE_NAME "org.dbus_exec_cmd.simple_exec"

int main (int argc, char **argv)
{
GMainLoop *loop;
DBusGConnection *connection;
GError *error = NULL;
GObject *obj;
DBusGProxy *driver_proxy;
guint32 request_name_ret;

g_type_init ();

if (!g_thread_supported ())
g_thread_init (NULL);

dbus_g_thread_init ();

loop = g_main_loop_new (NULL, FALSE);

g_print ("[Simple Dbus Exec]Launching Simple Exec Object\n");

/* Obtain a connection to the session bus */
connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (connection == NULL)
{
die ("[Simple Dbus Exec]Failed to open connection to bus", error);
}

obj = g_object_new (DBUS_EXEC_CMD_TYPE, NULL);

dbus_g_connection_register_g_object (connection,
"/org/dbus_exec_cmd/simple_exec",
obj);

driver_proxy = dbus_g_proxy_new_for_name (connection,
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);

if (!org_freedesktop_DBus_request_name (driver_proxy, SIMPLE_EXEC_SERVICE_NAME,
0, &request_name_ret, &error))
{
die ("[Simple Dbus Exec]Failed to get name", error);
}

if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
{
g_error ("[Simple Dbus Exec]Got result code %u from requesting name", request_name_ret);
exit (1);
}

g_print ("[Simple Dbus Exec]GLib service has name: [%s]\n", SIMPLE_EXEC_SERVICE_NAME);

g_print ("[Simple Dbus Exec]GLib service entering main loop\n");
g_main_loop_run (loop);
g_print ("[Simple Dbus Exec]Successfully completed %s\n", argv[0]);

return 0;
}


#include <glib-object.h>

typedef struct DbusExecCmd DbusExecCmd;
typedef struct DbusExecCmdClass DbusExecCmdClass;

GType dbus_exec_cmd_get_type (void);

struct DbusExecCmd
{
GObject parent;
};

struct DbusExecCmdClass
{
GObjectClass parent;
};

#define DBUS_EXEC_CMD_TYPE              (dbus_exec_cmd_get_type ())
#define DBUS_EXEC_CMD(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), DBUS_EXEC_CMD_TYPE, DbusExecCmd))
#define DBUS_EXEC_CMD_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), DBUS_EXEC_CMD_TYPE, DbusExecCmdClass))
#define IS_DBUS_EXEC_CMD(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), DBUS_EXEC_CMD_TYPE))
#define IS_DBUS_EXEC_CMD_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUS_EXEC_CMD_TYPE))
#define DBUS_EXEC_CMD_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUS_EXEC_CMD_TYPE, DbusExecCmdClass))

typedef enum
{
ECHO_ERROR_GENERIC
} DbusExecCmdError;

gboolean simple_exec_command(DbusExecCmd *exec_cmd, const char* cmd_str, GError **error);


<?xml version="1.0" encoding="UTF-8" ?>
<node name="/org/dbus_exec_cmd/simple_exec">
<interface name='org.dbus_exec_cmd.simple_exec'>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="simple"/>
<method name='exec_command'>
<arg type='s' name='cmd_str' direction='in' />
</method>
</interface>
</node>


<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>

<policy user="root">
<allow own="org.dbus_exec_cmd.simple_exec"/>
</policy>

<!-- Allow anyone to invoke methods -->
<policy user="root">
<allow send_destination="org.dbus_exec_cmd.simple_exec"/>
<allow receive_sender="org.dbus_exec_cmd.simple_exec"/>
</policy>
</busconfig>


[D-BUS Service]
Name=org.dbus_exec_cmd.simple_exec
Exec=@bindir@/simple_exec
User=root


simple_dbus_exec.004.7z
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: