Add abstract socket namespace support to ecore_con.

Lots of work on ecore_dbus
Hilights:
  - get the socket address for system/session/startup busses from the environment
  - can request/release a bus name
  - receive method calls (we need to add a way to register callbacks for specific methods)
  - send signals and method replies (untested)

*** API BREAKAGE ***
ecore_dbus_message_new_method_call() - the 'destination' param has moved to after the 'method' param to keep things consistent with newly supported message types and the param ordering in the spec.


SVN revision: 26081
This commit is contained in:
rephorm 2006-09-24 07:24:52 +00:00 committed by rephorm
parent 9e48ad8026
commit 16f3aae0c9
15 changed files with 541 additions and 169 deletions

View File

@ -18,3 +18,4 @@ dan sinclair <zero@everburning.com>
Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
David 'onefang' Seikel <onefang@gmail.com>
Hisham 'CodeWarrior' Mardam Bey <hisham@hisham.cc>
Brian 'rephorm' Mattern <rephorm@rephorm.com>

View File

@ -889,6 +889,11 @@ if test "x$use_openssl" = "xyes"; then
)
fi
AC_ABSTRACT_SOCKET_TEST(
[AC_DEFINE(HAVE_ABSTRACT_SOCKETS, 1, [Have abstract socket namespace])],
[]
)
want_ecore_ipc="yes";
have_ecore_ipc="no";
ecore_ipc_cflags="";

View File

@ -95,7 +95,8 @@ ecore_test \
ecore_evas_test \
ecore_config \
ecore_dbus_test \
ecore_dbus_hal_test
ecore_dbus_hal_test \
ecore_dbus_receiver_test
ecore_test_SOURCES = \
ecore_test.c
@ -200,3 +201,19 @@ ecore_dbus_hal_test_DEPENDENCIES = \
$(top_builddir)/src/lib/ecore/libecore.la \
$(ECORE_DBUS_LIB)
ecore_dbus_receiver_test_SOURCES = \
ecore_dbus_receiver_test.c \
ecore_dbus_test.h
ecore_dbus_receiver_test_LDADD = \
$(top_builddir)/src/lib/ecore/libecore.la \
$(ECORE_DBUS_LIB)
ecore_dbus_receiver_test_CFLAGS = \
$(CFLAGS) \
$(INCLUDES)
ecore_dbus_receiver_test_DEPENDENCIES = \
$(top_builddir)/src/lib/ecore/libecore.la \
$(ECORE_DBUS_LIB)

View File

@ -23,8 +23,7 @@ main(int argc, char **argv)
{
ecore_dbus_init();
svr = ecore_dbus_server_connect(ECORE_DBUS_BUS_SYSTEM,
"/var/run/dbus/system_dbus_socket", -1, NULL);
svr = ecore_dbus_server_system_connect(NULL);
if (!svr)
{
printf("Couldn't connect to dbus system server!\n");
@ -40,7 +39,7 @@ main(int argc, char **argv)
ecore_dbus_event_server_add, NULL);
handler[i++] = ecore_event_handler_add(ECORE_DBUS_EVENT_SERVER_DEL,
ecore_dbus_event_server_del, NULL);
handler[i++] = ecore_event_handler_add(ECORE_DBUS_EVENT_SERVER_SIGNAL,
handler[i++] = ecore_event_handler_add(ECORE_DBUS_EVENT_SIGNAL,
ecore_dbus_event_server_signal, NULL);
ecore_main_loop_begin();
@ -126,7 +125,7 @@ ecore_dbus_method_error_cb(void *data, const char *error)
static int
ecore_dbus_event_server_signal(void *udata, int ev_type, void *ev)
{
Ecore_DBus_Event_Server_Signal *event;
Ecore_DBus_Event_Signal *event;
event = ev;
printf("ecore_dbus_event_server_signal %s %s.%s\n", event_type_get(event->type),

View File

@ -9,6 +9,7 @@ static int ecore_dbus_event_server_add(void *udata, int ev_type, void *ev);
static int ecore_dbus_event_server_del(void *udata, int ev_type, void *ev);
static void ecore_dbus_method_list_names_cb(void *data, Ecore_DBus_Method_Return *reply);
static void ecore_dbus_method_test_cb(void *data, Ecore_DBus_Method_Return *reply);
static void ecore_dbus_method_error_cb(void *data, const char *error);
static const char *event_type_get(Ecore_DBus_Message_Type type);
@ -18,12 +19,13 @@ static Ecore_DBus_Server *svr = NULL;
int
main(int argc, char **argv)
{
char *bus_addr = NULL, *socket_name = NULL;
ecore_dbus_init();
svr = ecore_dbus_server_connect(ECORE_DBUS_BUS_SYSTEM,
"/var/run/dbus/system_dbus_socket", -1, NULL);
svr = ecore_dbus_server_session_connect(NULL);
if (!svr)
{
printf("Couldn't connect to dbus system server!\n");
printf("Couldn't connect to dbus system server (%s)!\n", socket_name);
}
else
{
@ -59,11 +61,11 @@ ecore_dbus_event_server_add(void *udata, int ev_type, void *ev)
ecore_dbus_method_list_names_cb,
ecore_dbus_method_error_cb, NULL);
ecore_dbus_message_new_method_call(event->server,
"org.freedesktop.DBus" /*destination*/,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"ListName" /*method*/,
ecore_dbus_method_list_names_cb,
"/org/enlightenment/Test" /*path*/,
"org.enlightenment.Test" /*interface*/,
"Test" /*method*/,
"org.enlightenment.Test" /*destination*/,
ecore_dbus_method_test_cb,
ecore_dbus_method_error_cb, NULL,
NULL /*fmt*/);
return 0;
@ -81,6 +83,13 @@ ecore_dbus_event_server_del(void *udata, int ev_type, void *ev)
return 0;
}
static void
ecore_dbus_method_test_cb(void *data,
Ecore_DBus_Method_Return *reply)
{
printf("test reply cb\n");
}
static void
ecore_dbus_method_list_names_cb(void *data,
Ecore_DBus_Method_Return *reply)

View File

@ -1,3 +1,6 @@
/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#ifndef _ECORE_CON_H
#define _ECORE_CON_H
@ -69,9 +72,14 @@ extern "C" {
typedef enum _Ecore_Con_Type
{
ECORE_CON_LOCAL_USER,
ECORE_CON_LOCAL_SYSTEM,
ECORE_CON_REMOTE_SYSTEM,
ECORE_CON_USE_SSL = 16
ECORE_CON_LOCAL_SYSTEM,
#ifdef HAVE_ABSTRACT_SOCKETS
ECORE_CON_LOCAL_ABSTRACT,
#endif
ECORE_CON_REMOTE_SYSTEM
#ifdef USE_OPENSSL
,ECORE_CON_USE_SSL = 16
#endif
} Ecore_Con_Type;
#endif

View File

@ -53,6 +53,7 @@ static int init_count = 0;
static int ssl_init_count = 0;
#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
#define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + (size_t)(((struct sockaddr_un *)NULL)->sun_path))
/**
* @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions
@ -168,18 +169,24 @@ ecore_con_server_add(Ecore_Con_Type compl_type,
/* unset the SSL flag for the following checks */
type &= ~ECORE_CON_USE_SSL;
#endif
if ((type == ECORE_CON_LOCAL_USER) ||
(type == ECORE_CON_LOCAL_SYSTEM))
(type == ECORE_CON_LOCAL_SYSTEM)
#ifdef HAVE_ABSTRACT_SOCKETS
|| (type == ECORE_CON_LOCAL_ABSTRACT)
#endif
)
{
const char *homedir;
struct stat st;
mode_t pmode, mask;
int socket_unix_len;
if (!name) goto error;
mask =
S_IRGRP | S_IWGRP | S_IXGRP |
S_IROTH | S_IWOTH | S_IXOTH;
if (type == ECORE_CON_LOCAL_USER)
{
homedir = getenv("HOME");
@ -229,11 +236,28 @@ ecore_con_server_add(Ecore_Con_Type compl_type,
goto error;
}
socket_unix.sun_family = AF_UNIX;
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
if (bind(svr->fd, (struct sockaddr *)&socket_unix, LENGTH_OF_SOCKADDR_UN(&socket_unix)) < 0)
#ifdef HAVE_ABSTRACT_SOCKET
if (type == ECORE_CON_LOCAL_ABSTRACT)
{
/* . is a placeholder */
snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s", name);
/* first char null indicates abstract namespace */
socket_unix.sun_path[0] = '\0';
socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, name);
}
else
{
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
}
#else
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
#endif
if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
{
if (connect(svr->fd, (struct sockaddr *)&socket_unix,
LENGTH_OF_SOCKADDR_UN(&socket_unix)) < 0)
socket_unix_len) < 0)
{
if ((type == ECORE_CON_LOCAL_USER) ||
(type == ECORE_CON_LOCAL_SYSTEM))
@ -401,9 +425,14 @@ ecore_con_server_connect(Ecore_Con_Type compl_type,
if ((type == ECORE_CON_REMOTE_SYSTEM) && (port < 0)) return NULL;
if ((type == ECORE_CON_LOCAL_USER) ||
(type == ECORE_CON_LOCAL_SYSTEM))
(type == ECORE_CON_LOCAL_SYSTEM)
#ifdef HAVE_ABSTRACT_SOCKETS
|| (type == ECORE_CON_LOCAL_ABSTRACT)
#endif
)
{
const char *homedir;
int socket_unix_len;
if (type == ECORE_CON_LOCAL_USER)
{
@ -435,8 +464,26 @@ ecore_con_server_connect(Ecore_Con_Type compl_type,
if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error;
socket_unix.sun_family = AF_UNIX;
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
if (connect(svr->fd, (struct sockaddr *)&socket_unix, LENGTH_OF_SOCKADDR_UN(&socket_unix)) < 0) goto error;
#ifdef HAVE_ABSTRACT_SOCKETS
if (type == ECORE_CON_LOCAL_ABSTRACT)
{
/* copy name insto sun_path, prefixed by null to indicate abstract namespace */
snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s", name);
socket_unix.sun_path[0] = '\0';
socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix, name);
}
else
{
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
}
#else
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
#endif
if (connect(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) goto error;
svr->path = strdup(buf);
if (!svr->path) goto error;
svr->fd_handler = ecore_main_fd_handler_add(svr->fd,

View File

@ -27,6 +27,9 @@ typedef enum _Ecore_Con_Type
{
ECORE_CON_LOCAL_USER,
ECORE_CON_LOCAL_SYSTEM,
#ifdef HAVE_ABSTRACT_SOCKETS
ECORE_CON_LOCAL_ABSTRACT,
#endif
ECORE_CON_REMOTE_SYSTEM
#if USE_OPENSSL
,ECORE_CON_USE_SSL = 16

View File

@ -3,7 +3,9 @@
*/
#ifndef _ECORE_DBUS_H
#define _ECORE_DBUS_H
#endif
#include "Ecore_Data.h"
#include "Ecore_Con.h"
#ifdef EAPI
#undef EAPI
@ -36,18 +38,13 @@ extern "C" {
typedef struct _Ecore_DBus_Event_Server_Add Ecore_DBus_Event_Server_Add;
typedef struct _Ecore_DBus_Event_Server_Del Ecore_DBus_Event_Server_Del;
typedef struct _Ecore_DBus_Event_Server_Data Ecore_DBus_Event_Server_Data;
typedef struct _Ecore_DBus_Event_Server_Data Ecore_DBus_Event_Server_Signal;
typedef struct _Ecore_DBus_Event_Server_Data Ecore_DBus_Event_Signal;
typedef struct _Ecore_DBus_Event_Server_Data Ecore_DBus_Event_Method_Call;
typedef struct _Ecore_DBus_Event_Server_Data Ecore_DBus_Method_Return;
typedef struct _Ecore_DBus_Message Ecore_DBus_Message;
typedef struct _Ecore_DBus_Message_Arg Ecore_DBus_Message_Arg;
typedef struct _Ecore_DBus_Message_Field Ecore_DBus_Message_Field;
typedef enum _Ecore_DBus_Type
{
ECORE_DBUS_BUS_SESSION,
ECORE_DBUS_BUS_SYSTEM,
ECORE_DBUS_BUS_ACTIVATION
} Ecore_DBus_Type;
typedef struct _Ecore_DBus_Address Ecore_DBus_Address;
typedef enum _Ecore_DBus_Message_Type
{
@ -58,6 +55,12 @@ extern "C" {
ECORE_DBUS_MESSAGE_TYPE_SIGNAL
} Ecore_DBus_Message_Type;
typedef enum _Ecore_DBus_Message_Flag
{
ECORE_DBUS_MESSAGE_FLAG_NO_REPLY_EXPECTED,
ECORE_DBUS_MESSAGE_FLAG_NO_AUTO_START
} Ecore_DBus_Message_Flag;
typedef enum _Ecore_DBus_Data_Type
{
ECORE_DBUS_DATA_TYPE_INVALID = ((int) '\0'),
@ -130,9 +133,18 @@ extern "C" {
ECORE_DBUS_HEADER_FIELD_SIGNATURE
} Ecore_DBus_Message_Header_Field;
struct _Ecore_DBus_Address
{
char *transport;
Ecore_List *keys;
Ecore_List *vals;
};
EAPI extern int ECORE_DBUS_EVENT_SERVER_ADD;
EAPI extern int ECORE_DBUS_EVENT_SERVER_DEL;
EAPI extern int ECORE_DBUS_EVENT_SERVER_SIGNAL;
EAPI extern int ECORE_DBUS_EVENT_METHOD_CALL;
EAPI extern int ECORE_DBUS_EVENT_SIGNAL;
/* callback */
typedef void (*Ecore_DBus_Method_Return_Cb)(void *data, Ecore_DBus_Method_Return *reply);
@ -143,19 +155,39 @@ extern "C" {
EAPI int ecore_dbus_shutdown(void);
/* connection */
EAPI Ecore_DBus_Server *ecore_dbus_server_connect(Ecore_DBus_Type type, char *name, int port, const void *data);
EAPI Ecore_DBus_Server *ecore_dbus_server_system_connect(const void *data);
EAPI Ecore_DBus_Server *ecore_dbus_server_session_connect(const void *data);
EAPI Ecore_DBus_Server *ecore_dbus_server_starter_connect(const void *data);
EAPI Ecore_DBus_Server *ecore_dbus_server_connect(Ecore_Con_Type type, const char *name, int port, const void *data);
EAPI void ecore_dbus_server_del(Ecore_DBus_Server *svr);
/* message */
EAPI int ecore_dbus_server_send(Ecore_DBus_Server *svr, char *command, int length);
EAPI unsigned int ecore_dbus_message_new_method_call(Ecore_DBus_Server *svr,
char *destination, char *path,
char *interface, char *method,
Ecore_DBus_Method_Return_Cb method_cb,
Ecore_DBus_Error_Cb error_cb,
void *data,
char *fmt, ...);
EAPI unsigned int ecore_dbus_message_new_method_call(Ecore_DBus_Server *svr,
char *path, char *interface,
char *method, char *destination,
Ecore_DBus_Method_Return_Cb method_cb,
Ecore_DBus_Error_Cb error_cb,
void *data,
char *signature, ...);
EAPI unsigned int ecore_dbus_message_new_method_return(Ecore_DBus_Server *svr,
int reply_serial, char *destination,
char *signature, ...);
EAPI unsigned int ecore_dbus_message_new_error(Ecore_DBus_Server *svr,
char *error_name,
int reply_serial, char *destination,
char *signature, ...);
EAPI unsigned int ecore_dbus_message_new_signal(Ecore_DBus_Server *svr,
char *path,
char *interface, char *signal_name,
char *destination, void *data,
char *signature, ...);
EAPI void ecore_dbus_message_del(Ecore_DBus_Message *msg);
EAPI void ecore_dbus_message_print(Ecore_DBus_Message *msg);
EAPI void *ecore_dbus_message_header_field_get(Ecore_DBus_Message *msg, Ecore_DBus_Message_Header_Field field);
@ -170,7 +202,22 @@ extern "C" {
EAPI int ecore_dbus_method_get_connection_unix_user(Ecore_DBus_Server *svr, char *connection, Ecore_DBus_Method_Return_Cb method_cb, Ecore_DBus_Error_Cb, void *data);
EAPI int ecore_dbus_method_add_match(Ecore_DBus_Server *svr, char *match, Ecore_DBus_Method_Return_Cb method_cb, Ecore_DBus_Error_Cb, void *data);
EAPI int ecore_dbus_method_remove_match(Ecore_DBus_Server *svr, char *match, Ecore_DBus_Method_Return_Cb method_cb, Ecore_DBus_Error_Cb, void *data);
EAPI int ecore_dbus_method_request_name(Ecore_DBus_Server *svr, char *name, int flags, Ecore_DBus_Method_Return_Cb method_cb, Ecore_DBus_Error_Cb, void *data);
EAPI int ecore_dbus_method_release_name(Ecore_DBus_Server *svr, char *name, Ecore_DBus_Method_Return_Cb method_cb, Ecore_DBus_Error_Cb, void *data);
/* addresses */
EAPI Ecore_DBus_Address *ecore_dbus_address_new();
EAPI void ecore_dbus_address_free(Ecore_DBus_Address *address);
EAPI Ecore_List *ecore_dbus_address_parse(const char *address);
EAPI char *ecore_dbus_address_value_get(Ecore_DBus_Address *address,
char *key);
EAPI void ecore_dbus_print_address_list(Ecore_List *addresses);
EAPI Ecore_DBus_Server *ecore_dbus_address_list_connect(Ecore_List *addrs, const void *data);
EAPI Ecore_DBus_Server *ecore_dbus_address_connect(Ecore_DBus_Address *addr, const void *data);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -26,6 +26,7 @@ ecore_dbus_marshal.c \
ecore_dbus_unmarshal.c \
ecore_dbus_methods.c \
ecore_dbus_utils.c \
ecore_dbus_address.c \
ecore_dbus_private.h
libecore_dbus_la_LIBADD = \

View File

@ -1,6 +1,7 @@
/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "config.h"
#include "Ecore.h"
#include "ecore_private.h"
#include "Ecore_Con.h"
@ -11,7 +12,8 @@
/* About */
/********************************************************************************/
/* Author: Jorge Luis Zapata */
/* Version: 0.2.1 */
/* Author: Brian Mattern (rephorm) */
/* Version: 0.3.0 */
/********************************************************************************/
/* Todo */
/********************************************************************************/
@ -37,12 +39,16 @@
/* */
/* 29-03-05 */
/* 0.2.1 some segfault fixes, new tests */
/* 0.3.0 add ability to send signals, receive method class and respond to them */
/* add address parsing and functions to connect to standard busses */
/* change API of ecore_dbus_message_new_method_call() */
/* global variables */
EAPI int ECORE_DBUS_EVENT_SERVER_ADD = 0;
EAPI int ECORE_DBUS_EVENT_SERVER_DEL = 0;
EAPI int ECORE_DBUS_EVENT_SERVER_SIGNAL = 0;
EAPI int ECORE_DBUS_EVENT_SIGNAL = 0;
EAPI int ECORE_DBUS_EVENT_METHOD_CALL = 0;
/* private function declaration */
@ -89,7 +95,8 @@ ecore_dbus_init(void)
ECORE_DBUS_EVENT_SERVER_ADD = ecore_event_type_new();
ECORE_DBUS_EVENT_SERVER_DEL = ecore_event_type_new();
ECORE_DBUS_EVENT_SERVER_SIGNAL = ecore_event_type_new();
ECORE_DBUS_EVENT_SIGNAL = ecore_event_type_new();
ECORE_DBUS_EVENT_METHOD_CALL = ecore_event_type_new();
handler[i++] = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD,
_ecore_dbus_event_server_add, NULL);
@ -118,37 +125,103 @@ ecore_dbus_shutdown(void)
return init_count;
}
/**
* Connect to the system bus.
*/
EAPI Ecore_DBus_Server *
ecore_dbus_server_connect(Ecore_DBus_Type compl_type, char *name, int port,
ecore_dbus_server_system_connect(const void *data)
{
Ecore_List *addrs;
Ecore_DBus_Server *svr;
char *bus_env;
/* get the system bus address from the environment */
bus_env = getenv("DBUS_SYSTEM_BUS_ADDRESS");
if (bus_env)
{
addrs = ecore_dbus_address_parse(bus_env);
if (addrs)
{
svr = ecore_dbus_address_list_connect(addrs, data);
ecore_list_destroy(addrs);
if (svr) return svr;
}
}
/* if we haven't returned already, try the default location */
return ecore_dbus_server_connect(ECORE_CON_LOCAL_SYSTEM, "/var/run/dbus/system_bus_socket", -1, data);
}
/**
* Connect to the session bus.
*/
EAPI Ecore_DBus_Server *
ecore_dbus_server_session_connect(const void *data)
{
Ecore_List *addrs;
Ecore_DBus_Server *svr;
char *bus_env;
/* get the session bus address from the environment */
bus_env = getenv("DBUS_SESSION_BUS_ADDRESS");
if (bus_env)
{
addrs = ecore_dbus_address_parse(bus_env);
if (addrs)
{
svr = ecore_dbus_address_list_connect(addrs, data);
ecore_list_destroy(addrs);
if (svr) return svr;
}
}
/*
* XXX try getting address from _DBUS_SESSION_BUS_ADDRESS property (STRING) set
* on the root window
*/
return NULL;
}
EAPI Ecore_DBus_Server *
ecore_dbus_server_starter_connect(const void *data)
{
Ecore_List *addrs;
Ecore_DBus_Server *svr;
char *bus_env;
/* get the session bus address from the environment */
bus_env = getenv("DBUS_STARTER_ADDRESS");
if (bus_env)
{
addrs = ecore_dbus_address_parse(bus_env);
if (addrs)
{
svr = ecore_dbus_address_list_connect(addrs, data);
ecore_list_destroy(addrs);
if (svr) return svr;
}
}
return NULL;
}
EAPI Ecore_DBus_Server *
ecore_dbus_server_connect(Ecore_Con_Type con_type, const char *name, int port,
const void *data)
{
/* XXX data isn't used! */
Ecore_DBus_Server *svr;
Ecore_DBus_Type type;
Ecore_Con_Type extra = 0;
svr = calloc(1, sizeof(Ecore_DBus_Server));
if (!svr) return NULL;
type = compl_type;
switch (type)
{
#if 0
/* Get address from DBUS_SESSION_BUS_ADDRESS env */
case ECORE_DBUS_BUS_SESSION:
svr->server =
ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port, svr);
break;
#endif
case ECORE_DBUS_BUS_SYSTEM:
svr->server =
ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr);
break;
default:
free(svr);
return NULL;
}
svr->server =
ecore_con_server_connect(con_type, name, port, svr);
if (!svr->server)
{
printf("Couldn't connect to server\n");
fprintf(stderr, "Ecore_DBus Error: Couldn't connect to server\n");
free(svr);
return NULL;
}
@ -373,7 +446,7 @@ _ecore_dbus_event_server_data(void *udata, int ev_type, void *ev)
}
else
{
printf("Ecore_DBus: Reply without reply serial!\n");
printf("[ecore_dbus] Reply without reply serial!\n");
}
if (sent) _ecore_dbus_message_free(sent);
_ecore_dbus_event_server_data_free(NULL, ev2);
@ -391,7 +464,7 @@ _ecore_dbus_event_server_data(void *udata, int ev_type, void *ev)
}
else
{
printf("Ecore_DBus: Error without reply serial!\n");
printf("[ecore_dbus] Error without reply serial!\n");
}
if (sent) _ecore_dbus_message_free(sent);
_ecore_dbus_event_server_data_free(NULL, ev2);
@ -400,7 +473,14 @@ _ecore_dbus_event_server_data(void *udata, int ev_type, void *ev)
{
Ecore_DBus_Event_Server_Data *ev2;
ev2 = _ecore_dbus_event_create(svr, msg);
ecore_event_add(ECORE_DBUS_EVENT_SERVER_SIGNAL, ev2,
ecore_event_add(ECORE_DBUS_EVENT_SIGNAL, ev2,
_ecore_dbus_event_server_data_free, NULL);
}
else if (msg->type == ECORE_DBUS_MESSAGE_TYPE_METHOD_CALL)
{
Ecore_DBus_Event_Server_Data *ev2;
ev2 = _ecore_dbus_event_create(svr, msg);
ecore_event_add(ECORE_DBUS_EVENT_METHOD_CALL, ev2,
_ecore_dbus_event_server_data_free, NULL);
}
else
@ -410,7 +490,7 @@ _ecore_dbus_event_server_data(void *udata, int ev_type, void *ev)
}
}
}
return 0;
return 1;
}
static void

View File

@ -8,7 +8,18 @@
#include "Ecore_DBus.h"
#include "ecore_dbus_private.h"
static void _ecore_dbus_message_common_header(Ecore_DBus_Message *msg, int type, int flags);
/* message helpers */
static Ecore_DBus_Message *_ecore_dbus_message_create(Ecore_DBus_Server *svr,
int type, int flags, char *path, char *interface,
char *member, char *error_name, int reply_serial,
char *destination, char *signature, va_list args);
static void _ecore_dbus_message_header(Ecore_DBus_Message *msg, int type,
int flags, char *path, char *interface,
char *member, char *error_name, int reply_serial,
char *destination, char *format);
static void _ecore_dbus_message_body(Ecore_DBus_Message *msg,
char *signature, va_list args);
static void _ecore_dbus_message_field_free(void *data);
/* printing functions */
@ -16,108 +27,167 @@ static void _ecore_dbus_message_field_print(Ecore_DBus_Message_Field *f);
static void _ecore_dbus_message_header_field_print(Ecore_DBus_Message_Field_Container *arr);
static void _ecore_dbus_message_print_raw(Ecore_DBus_Message *msg);
/*
* Message types and allowed fields (* indicates required field):
*
* METHOD_CALL
* *path
* interface
* member
* destination
* signature
*
* METHOD_RETURN
* member
* *reply_serial
* destination
* signature
*
* ERROR
* *error_name
* *reply_serial
* destination
* signature
*
* SIGNAL
* *path
* *interface
* *member
* destination
* signature
*
*/
EAPI unsigned int
ecore_dbus_message_new_method_call(Ecore_DBus_Server *svr, char *destination,
char *path, char *interface, char *method,
ecore_dbus_message_new_method_return(Ecore_DBus_Server *svr, int reply_serial,
char *destination, char *signature, ...)
{
va_list args;
Ecore_DBus_Message *msg;
va_start(args, signature);
msg = _ecore_dbus_message_create(svr, ECORE_DBUS_MESSAGE_TYPE_METHOD_RETURN, 0, NULL, NULL, NULL, NULL, reply_serial, destination, signature, args);
va_end(args);
ecore_dbus_server_send(svr, (char *)msg->buffer, msg->length);
ecore_hash_set(svr->messages, (void *)msg->serial, msg);
return msg->serial;
}
EAPI unsigned int
ecore_dbus_message_new_error(Ecore_DBus_Server *svr, char *error_name,
int reply_serial, char *destination,
char *signature, ...)
{
va_list args;
Ecore_DBus_Message *msg;
va_start(args, signature);
msg = _ecore_dbus_message_create(svr, ECORE_DBUS_MESSAGE_TYPE_ERROR, 0, NULL, NULL, NULL, error_name, reply_serial, destination, signature, args);
va_end(args);
ecore_dbus_server_send(svr, (char *)msg->buffer, msg->length);
ecore_hash_set(svr->messages, (void *)msg->serial, msg);
return msg->serial;
}
EAPI unsigned int
ecore_dbus_message_new_signal(Ecore_DBus_Server *svr, char *path,
char *interface, char *signal_name,
char *destination, void *data,
char *signature, ...)
{
va_list args;
Ecore_DBus_Message *msg;
va_start(args, signature);
msg = _ecore_dbus_message_create(svr, ECORE_DBUS_MESSAGE_TYPE_SIGNAL, 0, path, interface, signal_name, NULL, 0, destination, signature, args);
va_end(args);
ecore_dbus_server_send(svr, (char *)msg->buffer, msg->length);
ecore_hash_set(svr->messages, (void *)msg->serial, msg);
return msg->serial;
}
EAPI unsigned int
ecore_dbus_message_new_method_call(Ecore_DBus_Server *svr,
char *path, char *interface,
char *method, char *destination,
Ecore_DBus_Method_Return_Cb method_cb,
Ecore_DBus_Error_Cb error_cb,
void *data,
char *fmt, ...)
char *signature, ...)
{
unsigned int body_start;
char buf[1024];
Ecore_DBus_Message_Field_Array *arr;
va_list args;
Ecore_DBus_Message *msg;
int flags = 0;
if (!method) return 0;
/* init message */
Ecore_DBus_Message *msg = _ecore_dbus_message_new(svr);
if (method_cb)
if (!method_cb && !error_cb) flags |= ECORE_DBUS_MESSAGE_FLAG_NO_REPLY_EXPECTED;
va_start(args, signature);
msg = _ecore_dbus_message_create(svr, ECORE_DBUS_MESSAGE_TYPE_METHOD_CALL, flags, path, interface, method, NULL, 0, destination, signature, args);
va_end(args);
if (method_cb || error_cb)
{
msg->cb.method_return = method_cb;
msg->cb.error = error_cb;
msg->cb.data = data;
}
/* common header */
_ecore_dbus_message_common_header(msg, ECORE_DBUS_MESSAGE_TYPE_METHOD_CALL, 0);
/* send message */
ecore_dbus_server_send(svr, (char *)msg->buffer, msg->length);
ecore_hash_set(svr->messages, (void *)msg->serial, msg);
arr = _ecore_dbus_message_marshal_array_begin(msg, ECORE_DBUS_DATA_TYPE_STRUCT);
/* custom header */
if (path)
{
Ecore_DBus_Message_Field_Struct *s;
return msg->serial;
}
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_PATH);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_OBJECT_PATH, path);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
if (destination)
{
Ecore_DBus_Message_Field_Struct *s;
static Ecore_DBus_Message *
_ecore_dbus_message_create(Ecore_DBus_Server *svr, int type, int flags, char *path, char *interface, char *member, char *error_name, int reply_serial, char *destination, char *signature, va_list args)
{
/* init message */
Ecore_DBus_Message *msg;
msg = _ecore_dbus_message_new(svr);
_ecore_dbus_message_header(msg, type, flags, path, interface, member, error_name, reply_serial, destination, signature);
_ecore_dbus_message_body(msg, signature, args);
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_DESTINATION);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_STRING, destination);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
if (interface)
{
Ecore_DBus_Message_Field_Struct *s;
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_INTERFACE);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_STRING, interface);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
if (method)
{
Ecore_DBus_Message_Field_Struct *s;
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_MEMBER);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_STRING, method);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
if (fmt)
{
Ecore_DBus_Message_Field_Struct *s;
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_SIGNATURE);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_SIGNATURE, fmt);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
_ecore_dbus_message_marshal_array_end(msg, arr);
msg->header = ecore_list_remove_first(msg->fields);
_ecore_dbus_message_padding(msg, 8);
/* show message */
//ecore_dbus_message_print(msg);
return msg;
}
static void
_ecore_dbus_message_body(Ecore_DBus_Message *msg, char *signature, va_list args)
{
unsigned int body_start;
/* message body */
body_start = msg->length;
if (fmt)
if (signature)
{
va_list ap;
va_start(ap, fmt);
while (*fmt)
while (*signature)
{
Ecore_DBus_Data_Type type = *fmt;
Ecore_DBus_Data_Type type = *signature;
switch (type)
{
case ECORE_DBUS_DATA_TYPE_BYTE:
_ecore_dbus_message_marshal_byte(msg, va_arg(ap, int));
_ecore_dbus_message_marshal_byte(msg, va_arg(args, int));
break;
case ECORE_DBUS_DATA_TYPE_UINT32:
_ecore_dbus_message_marshal_uint32(msg, va_arg(ap, unsigned int));
_ecore_dbus_message_marshal_uint32(msg, va_arg(args, unsigned int));
break;
case ECORE_DBUS_DATA_TYPE_STRING:
_ecore_dbus_message_marshal_string(msg, (char *)va_arg(ap, char *));
_ecore_dbus_message_marshal_string(msg, (char *)va_arg(args, char *));
break;
case ECORE_DBUS_DATA_TYPE_OBJECT_PATH:
_ecore_dbus_message_marshal_object_path(msg, (char *)va_arg(ap, char *));
_ecore_dbus_message_marshal_object_path(msg, (char *)va_arg(args, char *));
break;
case ECORE_DBUS_DATA_TYPE_SIGNATURE:
_ecore_dbus_message_marshal_signature(msg, (char *)va_arg(ap, char *));
_ecore_dbus_message_marshal_signature(msg, (char *)va_arg(args, char *));
break;
case ECORE_DBUS_DATA_TYPE_INVALID:
case ECORE_DBUS_DATA_TYPE_BOOLEAN:
@ -138,27 +208,14 @@ ecore_dbus_message_new_method_call(Ecore_DBus_Server *svr, char *destination,
#if 0
default:
#endif
printf("[ecore_dbus] unknown/unhandled data type %c\n", *fmt);
printf("[ecore_dbus] unknown/unhandled data type %c\n", *signature);
break;
}
fmt++;
signature++;
}
va_end(ap);
}
/* set body length */
*(unsigned int *)(msg->buffer + 4) = msg->length - body_start;
/* show message */
//ecore_dbus_message_print(msg);
/* send message */
ecore_dbus_server_send(svr, (char *)msg->buffer, msg->length);
if (interface)
snprintf(buf, sizeof(buf), "%s.%s", interface, method);
else
strcpy(buf, method);
ecore_hash_set(svr->messages, (void *)msg->serial, msg);
return msg->serial;
}
EAPI void
@ -375,14 +432,22 @@ _ecore_dbus_message_free(Ecore_DBus_Message *msg)
/* header functions */
static void
_ecore_dbus_message_common_header(Ecore_DBus_Message *msg, int type, int flags)
_ecore_dbus_message_header(Ecore_DBus_Message *msg, int type, int flags,
char *path, char *interface, char *member,
char *error_name, int reply_serial,
char *destination, char *signature)
{
/* endiannes (1) */
Ecore_DBus_Message_Field_Array *arr;
if (!msg) return;
/* endianness (1) */
/* XXX we need to detect for endianess and send 'B' for Bigendian machines */
msg->buffer[0] = msg->byte_order = 'l';
/* type (1) */
msg->buffer[1] = msg->type = (char)type;
/* flags (1) 0x1 = no reply expected, 0x2 auto activation */
msg->buffer[2] = msg->flags = 0x0;
msg->buffer[2] = msg->flags = flags;
/* protocol (1) */
msg->buffer[3] = msg->protocol = ECORE_DBUS_MAJOR_PROTOCOL_VERSION;
/* autoincrement the client_serial (0 is invalid) */
@ -390,6 +455,61 @@ _ecore_dbus_message_common_header(Ecore_DBus_Message *msg, int type, int flags)
*(unsigned int *)(msg->buffer + 8) = msg->serial = msg->server->cnt_msg;
msg->length = 12;
/* header fields */
arr = _ecore_dbus_message_marshal_array_begin(msg, ECORE_DBUS_DATA_TYPE_STRUCT);
if (path)
{
Ecore_DBus_Message_Field_Struct *s;
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_PATH);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_OBJECT_PATH, path);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
if (interface)
{
Ecore_DBus_Message_Field_Struct *s;
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_INTERFACE);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_STRING, interface);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
if (member)
{
Ecore_DBus_Message_Field_Struct *s;
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_MEMBER);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_STRING, member);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
if (destination)
{
Ecore_DBus_Message_Field_Struct *s;
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_DESTINATION);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_STRING, destination);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
if (signature)
{
Ecore_DBus_Message_Field_Struct *s;
s = _ecore_dbus_message_marshal_struct_begin(msg);
_ecore_dbus_message_marshal_byte(msg, ECORE_DBUS_HEADER_FIELD_SIGNATURE);
_ecore_dbus_message_marshal_variant(msg, ECORE_DBUS_DATA_TYPE_SIGNATURE, signature);
_ecore_dbus_message_marshal_struct_end(msg, s);
}
_ecore_dbus_message_marshal_array_end(msg, arr);
/* move the header fields to the header */
msg->header = ecore_list_remove_last(msg->fields);
/* pad to an 8 bit boundary */
_ecore_dbus_message_padding(msg, 8);
}
static void
@ -581,3 +701,4 @@ _ecore_dbus_message_print_raw(Ecore_DBus_Message *msg)
printf("\n");
printf("[ecore_dbus] end raw message\n");
}

View File

@ -20,10 +20,10 @@ ecore_dbus_method_hello(Ecore_DBus_Server *svr,
return 0;
}
return ecore_dbus_message_new_method_call(svr,
"org.freedesktop.DBus" /*destination*/,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"Hello" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
NULL /*fmt*/);
}
@ -35,10 +35,10 @@ ecore_dbus_method_list_names(Ecore_DBus_Server *svr,
void *data)
{
return ecore_dbus_message_new_method_call(svr,
"org.freedesktop.DBus" /*destination*/,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"ListNames" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
NULL /*fmt*/);
}
@ -50,10 +50,10 @@ ecore_dbus_method_name_has_owner(Ecore_DBus_Server *svr, char *name,
void *data)
{
return ecore_dbus_message_new_method_call(svr,
"org.freedesktop.DBus" /*destination*/,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"NameHasOwner" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
"s" /*fmt*/, name);
}
@ -65,10 +65,10 @@ ecore_dbus_method_start_service_by_name(Ecore_DBus_Server *svr, char *name, unsi
void *data)
{
return ecore_dbus_message_new_method_call(svr,
"org.freedesktop.DBus" /*destination*/,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"StartServiceByName" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
"su" /*fmt*/, name, flags);
}
@ -80,10 +80,10 @@ ecore_dbus_method_get_name_owner(Ecore_DBus_Server *svr, char *name,
void *data)
{
return ecore_dbus_message_new_method_call(svr,
"org.freedesktop.DBus" /*destination*/,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"GetNameOwner" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
"s" /*fmt*/, name);
}
@ -95,10 +95,10 @@ ecore_dbus_method_get_connection_unix_user(Ecore_DBus_Server *svr, char *connect
void *data)
{
return ecore_dbus_message_new_method_call(svr,
"org.freedesktop.DBus" /*destination*/,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"GetConnectionUnixUser" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
"s" /*fmt*/, connection);
}
@ -110,10 +110,10 @@ ecore_dbus_method_add_match(Ecore_DBus_Server *svr, char *match,
void *data)
{
return ecore_dbus_message_new_method_call(svr,
"org.freedesktop.DBus" /*destination*/,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"AddMatch" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
"s" /*fmt*/, match);
}
@ -125,10 +125,40 @@ ecore_dbus_method_remove_match(Ecore_DBus_Server *svr, char *match,
void *data)
{
return ecore_dbus_message_new_method_call(svr,
"org.freedesktop.DBus" /*destination*/,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"RemoveMatch" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
"s" /*fmt*/, match);
}
EAPI int
ecore_dbus_method_request_name(Ecore_DBus_Server *svr, char *name, int flags,
Ecore_DBus_Method_Return_Cb method_cb,
Ecore_DBus_Error_Cb error_cb,
void *data)
{
return ecore_dbus_message_new_method_call(svr,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"RequestName" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
"su" /*fmt*/, name, flags);
}
EAPI int
ecore_dbus_method_release_name(Ecore_DBus_Server *svr, char *name,
Ecore_DBus_Method_Return_Cb method_cb,
Ecore_DBus_Error_Cb error_cb,
void *data)
{
return ecore_dbus_message_new_method_call(svr,
"/org/freedesktop/DBus" /*path*/,
"org.freedesktop.DBus" /*interface*/,
"RequestName" /*method*/,
"org.freedesktop.DBus" /*destination*/,
method_cb, error_cb, data,
"s" /*fmt*/, name);
}

View File

@ -4,6 +4,9 @@
#ifndef _ECORE_DBUS_PRIVATE_H
#define _ECORE_DBUS_PRIVATE_H
#include "Ecore_Con.h"
#include "Ecore_Data.h"
typedef unsigned char *(*Ecore_DBus_Auth_Transaction)(void *);
typedef struct _Ecore_DBus_Auth Ecore_DBus_Auth;
@ -56,7 +59,7 @@ typedef enum _Ecore_DBus_Auth_Type
struct _Ecore_DBus_Server
{
Ecore_List2 __list_data;
Ecore_List2 __list_data;
Ecore_Con_Server *server;
int authenticated;
int auth_type;

View File

@ -202,3 +202,4 @@ _ecore_dbus_message_field_value_get(Ecore_DBus_Message_Field *f)
}
return NULL;
}