#include <string.h>
#include <dlfcn.h>
-#define TRACE_TAG TRACE_SDB
+//#define TRACE_TAG TRACE_SDB
+#define LOG_TAG "SDBD_TRACE_SDB"
#include "log.h"
#include "sdb.h"
#include "plugin.h"
#include "sdbd_plugin.h"
-static void* plugin_handle = NULL;
+void* g_plugin_handle = NULL;
PLUGIN_INIT plugin_init_proc = NULL;
PLUGIN_SYNCHRONOUS_CMD_PROC plugin_sync_proc = NULL;
hashtable* plugin_cmd_hashtable = NULL;
+char* extcmd = NULL;
+
+typedef struct _async_parameter {
+ int cmd;
+ parameters* in;
+ int out_fd;
+} async_parameter;
+
// handler of event to be detected by plugin
int plugin_event_handler ( int event_type, parameters* data )
{
static int plugin_register_command ( int command, priority cmd_priority )
{
if ( plugin_cmd_hashtable ) {
- hashtable_put ( plugin_cmd_hashtable, command, cmd_priority );
+ int ret = hashtable_put ( plugin_cmd_hashtable, command, cmd_priority );
+ D ("register plugin command : cmd(%d), result(%d)\n", command, ret);
+ } else {
+ I ("hashtable is not created\n");
}
return 0;
}
plugin_sync_proc = NULL;
plugin_async_proc = NULL;
- plugin_handle = dlopen ( PLUGIN_PATH, RTLD_NOW );
- if ( plugin_handle == NULL ) {
- D ( "failed to dlopen(%s). error: %s\n", PLUGIN_PATH, dlerror() );
+ g_plugin_handle = dlopen ( PLUGIN_PATH, RTLD_NOW );
+ if ( g_plugin_handle == NULL ) {
+ E ( "failed to dlopen(%s). error: %s\n", PLUGIN_PATH, dlerror() );
return 0;
}
- plugin_init_proc = dlsym ( plugin_handle, PLUGIN_PROC_NAME_INIT );
+ plugin_init_proc = dlsym ( g_plugin_handle, PLUGIN_PROC_NAME_INIT );
if ( plugin_init_proc == NULL ) {
- D ( "failed to get the sdbd plugin init function. error: %s\n", dlerror() );
- dlclose ( plugin_handle );
- plugin_handle = NULL;
+ E ( "failed to get the sdbd plugin init function. error: %s\n", dlerror() );
+ dlclose ( g_plugin_handle );
+ g_plugin_handle = NULL;
return 0;
}
// if there is no implementation of plugin_sync_proc and plugin_async_proc,
// then use default_plugin_sync_proc and default_plugin_async_proc
- plugin_sync_proc = dlsym ( plugin_handle, PLUGIN_PROC_NAME_SYNC_CMD );
+ plugin_sync_proc = dlsym ( g_plugin_handle, PLUGIN_PROC_NAME_SYNC_CMD );
if ( plugin_sync_proc == NULL ) {
plugin_sync_proc = default_plugin_sync_proc;
}
- plugin_async_proc = dlsym ( plugin_handle, PLUGIN_PROC_NAME_ASYNC_CMD );
+ plugin_async_proc = dlsym ( g_plugin_handle, PLUGIN_PROC_NAME_ASYNC_CMD );
if ( plugin_async_proc == NULL ) {
plugin_async_proc = default_plugin_async_proc;
}
return 1;
}
+void readxml() {
+ char * buffer = NULL;
+ long length;
+ size_t result;
+ FILE * fptr = fopen(PLUGIN_XML_PATH, "rb");
+
+ if (fptr == NULL) {
+ E("failed to open commands.xml\n");
+ return;
+ }
+
+ fseek(fptr, 0, SEEK_END);
+ length = ftell(fptr);
+ if (length <= 0) {
+ E("commands.xml is empty\n");
+ fclose(fptr);
+ return;
+ }
+ fseek(fptr, 0, SEEK_SET);
+ buffer = malloc(length);
+ if (buffer) {
+ result = fread(buffer, 1, length, fptr);
+ if (result != length) {
+ E("xml file read error\n");
+ free(buffer);
+ fclose(fptr);
+ return;
+ }
+ }
+ fclose(fptr);
+ if (buffer) {
+ D("command xml data: %s\n", buffer);
+ extcmd = buffer;
+ }
+}
+
void load_sdbd_plugin()
{
int ret;
plugin_sync_proc = default_plugin_sync_proc;
plugin_async_proc = default_plugin_async_proc;
- D ( "using default plugin interface.\n" );
+ I ( "using default plugin interface.\n" );
} else {
D ( "using sdbd plugin interface.(%s)\n", PLUGIN_PATH );
plugin_init_proc ( plugin_event_handler, plugin_register_command );
+ readxml();
}
// use default plugin feature for the commands or events that are not supported by plugin
plugin_cmd_hashtable = NULL;
}
- if ( plugin_handle ) {
- dlclose ( plugin_handle );
- plugin_handle = NULL;
+ if ( g_plugin_handle ) {
+ dlclose ( g_plugin_handle );
+ g_plugin_handle = NULL;
+ }
+
+ if (extcmd) {
+ free(extcmd);
+ extcmd = NULL;
}
}
if ( plugin_cmd_hashtable ) {
int value;
ret = hashtable_get ( plugin_cmd_hashtable, cmd, &value );
+ D ("get from hashtable : cmd(%d), result(%d)\n", cmd, ret);
+ } else {
+ D ("hashtable is not created\n");
}
return ret;
}
-static int request_sync_cmd ( int cmd, parameters* in, parameters* out )
+int request_sync_cmd ( int cmd, parameters* in, parameters* out )
{
int ret, pr;
out->number_of_parameter = 0;
out->array_of_parameter = NULL;
- ret = hashtable_get ( plugin_cmd_hashtable, cmd, &pr );
- if ( ret == 1 ) {
- // supported by plugin
- ret = plugin_sync_proc ( cmd, in, out );
- if ( ret == PLUGIN_CMD_NOT_SUPPORT ) {
- // not supported by plugin
- ret = default_plugin_sync_proc ( cmd, in, out );
- }
+ if ( plugin_cmd_hashtable ) {
+ ret = hashtable_get ( plugin_cmd_hashtable, cmd, &pr );
+ if ( ret == 1 ) {
+ // supported by plugin
+ ret = plugin_sync_proc ( cmd, in, out );
+ if ( ret == PLUGIN_CMD_NOT_SUPPORT ) {
+ // not supported by plugin
+ ret = default_plugin_sync_proc ( cmd, in, out );
+ }
+ } else {
+ // not supported by plugin
+ ret = default_plugin_sync_proc ( cmd, in, out );
+ }
} else {
- // not supported by plugin
- ret = default_plugin_sync_proc ( cmd, in, out );
+ ret = default_plugin_sync_proc ( cmd, in, out );
}
return ret;
}
+static void request_async_cmd ( int cmd, parameters* in, int out_fd )
+{
+ int ret, pr;
+
+ if ( plugin_cmd_hashtable ) {
+ ret = hashtable_get ( plugin_cmd_hashtable, cmd, &pr );
+ if ( ret == 1 ) {
+ // supported by plugin
+ ret = plugin_async_proc ( cmd, in, out_fd );
+ if ( ret == PLUGIN_CMD_NOT_SUPPORT ) {
+ // not supported by plugin
+ ret = default_plugin_async_proc ( cmd, in, out_fd );
+ }
+ } else {
+ // not supported by plugin
+ ret = default_plugin_async_proc ( cmd, in, out_fd );
+ }
+ } else {
+ ret = default_plugin_async_proc ( cmd, in, out_fd );
+ }
+
+ release_parameters(in);
+ free(in);
+ sdb_close(out_fd);
+}
+
+static void *async_proc_bootstrap_func(void *x)
+{
+ async_parameter *p = x;
+ request_async_cmd(p->cmd, p->in, p->out_fd);
+ free(p);
+ return 0;
+}
+
+static int create_async_proc_thread( int cmd, parameters* in )
+{
+ async_parameter* async_param;
+ sdb_thread_t t;
+ int s[2];
+
+ if (sdb_socketpair(s)) {
+ release_parameters(in);
+ free(in);
+ E("cannot create async proc socket pair\n");
+ return -1;
+ }
+
+ async_param = (async_parameter*)malloc(sizeof(async_parameter));
+ if (async_param == NULL) {
+ release_parameters(in);
+ free(in);
+ fatal("cannot allocate async_parameter");
+ return -1;
+ }
+
+ async_param->cmd = cmd;
+ async_param->in = in;
+ async_param->out_fd = s[1];
+
+ if (sdb_thread_create(&t, async_proc_bootstrap_func, async_param)) {
+ free(async_param);
+ sdb_close(s[0]);
+ sdb_close(s[1]);
+ release_parameters(in);
+ free(in);
+ E("cannot create async proc thread\n");
+ return -1;
+ }
+
+ D("async proc thread started, %d:%d\n",s[0], s[1]);
+ return s[0];
+}
+
+static void *async_proc_extcmd_bootstrap_func(void *x)
+{
+ async_parameter *p = x;
+ plugin_async_proc(p->cmd, p->in, p->out_fd);
+ release_parameters(p->in);
+ free(p->in);
+ sdb_close(p->out_fd);
+ free(p);
+ return 0;
+}
+
+int create_async_extcmd_proc_thread( int cmd, parameters* in )
+{
+ async_parameter* async_param;
+ sdb_thread_t t;
+ int s[2];
+
+ if (sdb_socketpair(s)) {
+ release_parameters(in);
+ free(in);
+ E("cannot create extcmd async proc socket pair\n");
+ return -1;
+ }
+
+ async_param = (async_parameter*)malloc(sizeof(async_parameter));
+ if (async_param == NULL) {
+ release_parameters(in);
+ free(in);
+ fatal("cannot allocate async_parameter");
+ return -1;
+ }
+
+ async_param->cmd = cmd;
+ async_param->in = in;
+ async_param->out_fd = s[1];
+
+ if (sdb_thread_create(&t, async_proc_extcmd_bootstrap_func, async_param)) {
+ free(async_param);
+ sdb_close(s[0]);
+ sdb_close(s[1]);
+ release_parameters(in);
+ free(in);
+ E("cannot create extcmd async proc thread\n");
+ return -1;
+ }
+
+ D("extcmd async proc thread started, %d:%d\n",s[0], s[1]);
+ return s[0];
+}
// return 1 if succeed to get capability from plugin
// return 0 otherwise
in.number_of_parameter = 1;
in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+ if (in.array_of_parameter == NULL) {
+ E("failed to allocate memory for the parameter\n");
+ return success;
+ }
in.array_of_parameter[0].type = type_int32;
in.array_of_parameter[0].v_int32 = cap;
+ D ("requested capability : %d\n", cap);
+
ret = request_sync_cmd ( PLUGIN_SYNC_CMD_CAPABILITY, &in, &out );
if ( ret == PLUGIN_CMD_SUCCESS ) {
- strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
- out_buf[out_len - 1] = '\0';
- success = 1;
+ if(out.array_of_parameter[0].v_string.data != NULL) {
+ strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
+ out_buf[out_len - 1] = '\0';
+ success = 1;
+ }
release_parameters ( &out );
+
+ D ("request capability success : %s\n", out_buf);
}
release_parameters ( &in );
if ( in_buf != NULL ) {
in.number_of_parameter = 1;
in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+ if (in.array_of_parameter == NULL) {
+ D("failed to allocate memory for the parameter\n");
+ return success;
+ }
in.array_of_parameter[0].type = type_string;
in.array_of_parameter[0].v_string.length = strlen ( in_buf );
in.array_of_parameter[0].v_string.data = strdup ( in_buf );
in.array_of_parameter = NULL;
}
+ D ("requested validity : %d, %s\n", cmd, in_buf);
+
ret = request_sync_cmd ( cmd, &in, &out );
if ( ret == PLUGIN_CMD_SUCCESS ) {
success = ( out.array_of_parameter[0].v_int32 == PLUGIN_RET_VALID ) ? 1 : 0;
release_parameters ( &out );
+
+ D ("request validity success : %d\n", success);
+ }
+
+ release_parameters ( &in );
+ return success;
+}
+
+// return 1 if allowed by plugin (valid)
+// return 0 if disallowed by plugin (invalid)
+int request_extcmd_validity_to_plugin ( int cmd, const char* in_buf)
+{
+ int success = 0;
+ int ret;
+ parameters in, out;
+
+ if ( in_buf != NULL ) {
+ in.number_of_parameter = 1;
+ in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+ if (in.array_of_parameter == NULL) {
+ D("failed to allocate memory for the parameter\n");
+ return success;
+ }
+ in.array_of_parameter[0].type = type_string;
+ in.array_of_parameter[0].v_string.length = strlen ( in_buf );
+ in.array_of_parameter[0].v_string.data = strdup ( in_buf );
+ } else {
+ in.number_of_parameter = 0;
+ in.array_of_parameter = NULL;
+ }
+
+ D ("requested validity : %d, %s\n", cmd, in_buf);
+
+ out.number_of_parameter = 0;
+ out.array_of_parameter = NULL;
+ ret = plugin_sync_proc ( cmd, &in, &out );
+ if ( ret == PLUGIN_CMD_SUCCESS ) {
+ success = ( out.array_of_parameter[0].v_int32 == PLUGIN_RET_VALID ) ? 1 : 0;
+ release_parameters ( &out );
+
+ D ("request validity success : %d\n", success);
}
release_parameters ( &in );
int ret;
parameters in, out;
- in.number_of_parameter = 1;
- in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
- in.array_of_parameter[0].type = type_string;
- in.array_of_parameter[0].v_string.length = strlen ( in_buf );
- in.array_of_parameter[0].v_string.data = strdup ( in_buf );
+ if ( in_buf != NULL ) {
+ in.number_of_parameter = 1;
+ in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+ if (in.array_of_parameter == NULL) {
+ E("failed to allocate memory for the parameter\n");
+ return success;
+ }
+ in.array_of_parameter[0].type = type_string;
+ in.array_of_parameter[0].v_string.length = strlen ( in_buf );
+ in.array_of_parameter[0].v_string.data = strdup ( in_buf );
+ } else {
+ in.number_of_parameter = 0;
+ in.array_of_parameter = NULL;
+ }
ret = request_sync_cmd ( cmd, &in, &out );
if ( ret == PLUGIN_CMD_SUCCESS ) {
- strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
- out_buf[out_len - 1] = '\0';
- success = 1;
+ if(out.array_of_parameter[0].v_string.data != NULL) {
+ strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
+ out_buf[out_len - 1] = '\0';
+ success = 1;
+ }
+ release_parameters ( &out );
+ }
+
+ release_parameters ( &in );
+ return success;
+}
+
+// return 1 if succeed to convert
+// return 0 otherwise
+int request_extcmd_conversion_to_plugin ( int cmd, const char* in_buf, char* out_buf, unsigned int out_len )
+{
+ int success = 0;
+ int ret;
+ parameters in, out;
+
+ if ( in_buf != NULL ) {
+ in.number_of_parameter = 1;
+ in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+ if (in.array_of_parameter == NULL) {
+ E("failed to allocate memory for the parameter\n");
+ return success;
+ }
+ in.array_of_parameter[0].type = type_string;
+ in.array_of_parameter[0].v_string.length = strlen ( in_buf );
+ in.array_of_parameter[0].v_string.data = strdup ( in_buf );
+ } else {
+ in.number_of_parameter = 0;
+ in.array_of_parameter = NULL;
+ }
+
+ out.number_of_parameter = 0;
+ out.array_of_parameter = NULL;
+
+ ret = plugin_sync_proc ( cmd, &in, &out );
+ if ( ret == PLUGIN_CMD_SUCCESS ) {
+ if(out.array_of_parameter[0].v_string.data != NULL) {
+ strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
+ out_buf[out_len - 1] = '\0';
+ success = 1;
+ }
release_parameters ( &out );
}
in.number_of_parameter = 1;
in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+ if (in.array_of_parameter == NULL) {
+ E("failed to allocate memory for the parameter\n");
+ return result;
+ }
in.array_of_parameter[0].type = type_int32;
in.array_of_parameter[0].v_int32 = lock_type;
return result;
}
+
+// return 1 if shell command handled by plugin (handle)
+// return 0 if shell command not handled by plugin (not handle)
+int request_handlecmd_to_plugin ( int cmd, const char* in_buf )
+{
+ int success = 0;
+ int ret;
+ parameters in, out;
+
+ if ( in_buf != NULL ) {
+ in.number_of_parameter = 1;
+ in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+ if (in.array_of_parameter == NULL) {
+ D("failed to allocate memory for the parameter\n");
+ return success;
+ }
+ in.array_of_parameter[0].type = type_string;
+ in.array_of_parameter[0].v_string.length = strlen ( in_buf );
+ in.array_of_parameter[0].v_string.data = strdup ( in_buf );
+ } else {
+ in.number_of_parameter = 0;
+ in.array_of_parameter = NULL;
+ }
+
+ D ("requested command handling : %d, %s\n", cmd, in_buf);
+
+ ret = request_sync_cmd ( cmd, &in, &out );
+ if ( ret == PLUGIN_CMD_SUCCESS ) {
+ success = ( out.array_of_parameter[0].v_int32 == PLUGIN_RET_HANDLE ) ? 1 : 0;
+ release_parameters ( &out );
+
+ D ("request command handling success : %d\n", success);
+ }
+
+ release_parameters ( &in );
+ return success;
+}
+
+int request_shellcmd_to_plugin ( const char* in_buf )
+{
+ parameters* in;
+ int fd;
+
+ in = (parameters*)malloc(sizeof(parameters));
+ if (in == NULL) {
+ E("failed to allocate memory for the parameters\n");
+ return -1;
+ }
+
+ if ( in_buf != NULL ) {
+ in->number_of_parameter = 1;
+ in->array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+ if (in->array_of_parameter == NULL) {
+ free(in);
+ E("failed to allocate memory for the parameter\n");
+ return -1;
+ }
+ in->array_of_parameter[0].type = type_string;
+ in->array_of_parameter[0].v_string.length = strlen ( in_buf );
+ in->array_of_parameter[0].v_string.data = strdup ( in_buf );
+ } else {
+ in->number_of_parameter = 0;
+ in->array_of_parameter = NULL;
+ }
+
+ fd = create_async_proc_thread( PLUGIN_ASYNC_CMD_HANDLEBYPLUGIN_SERVICE, in );
+
+ return fd;
+}
+
+// return nonnegative integer that is a socket descriptor for communication
+// with async proc thread if success to create async proc thread
+// return -1 if failed to create async proc thread
+int request_appcmd_to_plugin ( const char* in_buf )
+{
+ parameters* in;
+ int fd;
+
+ in = (parameters*)malloc(sizeof(parameters));
+ if (in == NULL) {
+ E("failed to allocate memory for the parameters\n");
+ return -1;
+ }
+
+ if ( in_buf != NULL ) {
+ in->number_of_parameter = 1;
+ in->array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+ if (in->array_of_parameter == NULL) {
+ free(in);
+ E("failed to allocate memory for the parameter\n");
+ return -1;
+ }
+ in->array_of_parameter[0].type = type_string;
+ in->array_of_parameter[0].v_string.length = strlen ( in_buf );
+ in->array_of_parameter[0].v_string.data = strdup ( in_buf );
+ } else {
+ in->number_of_parameter = 0;
+ in->array_of_parameter = NULL;
+ }
+
+ fd = create_async_proc_thread( PLUGIN_ASYNC_CMD_APPCMD_SERVICE, in );
+
+ return fd;
+}
+