Merge branch 'jail' into light-rebase

This commit is contained in:
Roman Volosovskyi 2016-07-03 23:20:02 +03:00
commit b5436645c6
4 changed files with 237 additions and 6 deletions

View File

@ -10,11 +10,11 @@ fi
# Create fake Go workspace if it doesn't exist yet.
workspace="$PWD/build/_workspace"
root="$PWD"
ethdir="$workspace/src/github.com/ethereum"
if [ ! -L "$ethdir/go-ethereum" ]; then
ethdir="$workspace/src/github.com/status-im"
if [ ! -L "$ethdir/status-go" ]; then
mkdir -p "$ethdir"
cd "$ethdir"
ln -s ../../../../../. go-ethereum
ln -s ../../../../../. status-go
cd "$root"
fi
@ -25,8 +25,8 @@ GOBIN="$PWD/build/bin"
export GOPATH GOBIN
# Run the command inside the workspace.
cd "$ethdir/go-ethereum"
PWD="$ethdir/go-ethereum"
cd "$ethdir/status-go"
PWD="$ethdir/status-go"
# Launch the arguments with the configured environment.
exec "$@"
exec "$@"

59
src/jail.go Normal file
View File

@ -0,0 +1,59 @@
package main
import (
"github.com/robertkrimen/otto"
"fmt"
"encoding/json"
)
var statusJs string
var vms = make(map[string]*otto.Otto)
func Init(js string) {
statusJs = js
}
func printError(error string) string {
str := JSONError{
Error: error,
}
outBytes, _ := json.Marshal(&str)
return string(outBytes)
}
func printResult(res string, err error) string {
var out string
if err != nil {
out = printError(err.Error())
} else {
if "undefined" == res {
res = "null";
}
out = fmt.Sprintf(`{"result": %s}`, res)
}
return out
}
func Parse(chatId string, js string) string {
vm := otto.New()
jjs := statusJs + js + `
var catalog = JSON.stringify(_status_catalog);
`
vms[chatId] = vm
_, err := vm.Run(jjs)
res, _ := vm.Get("catalog")
return printResult(res.String(), err)
}
func Call(chatId string, path string, args string) string {
vm, ok := vms[chatId]
if !ok {
return printError(fmt.Sprintf("Vm[%s] doesn't exist.", chatId))
}
res, err := vm.Call("call", nil, path, args)
return printResult(res.String(), err);
}

155
src/library.c Normal file
View File

@ -0,0 +1,155 @@
#include <stddef.h>
#include <stdbool.h>
#include <jni.h>
bool GethServiceSignalEvent( const char *jsonEvent );
static JavaVM *gJavaVM = NULL;
static jclass JavaClassPtr_GethService = NULL;
static jmethodID JavaMethodPtr_signalEvent = NULL;
static bool JniLibraryInit( JNIEnv *env );
/*!
* @brief Get interface to JNI.
*
* @return true if thread should be detached from JNI.
*/
static bool JniAttach( JNIEnv **env )
{
jint status;
if (gJavaVM == NULL)
{
env = NULL;
}
status = (*gJavaVM)->GetEnv( gJavaVM, (void **)env, JNI_VERSION_1_6);
if (status == JNI_EDETACHED)
{
// attach thread to JNI
//(*gJavaVM)->AttachCurrentThread( gJavaVM, (void **)env, NULL ); // Oracle JNI API
(*gJavaVM)->AttachCurrentThread( gJavaVM, env, NULL ); // Android JNI API
return true;
}
else if (status != JNI_OK)
{
return false;
}
return false;
}
/*!
* @brief The VM calls JNI_OnLoad when the native library is loaded.
*/
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
bool detach;
JNIEnv *env;
bool result = JNI_VERSION_1_6;
gJavaVM = vm;
// attach thread to JNI
detach = JniAttach( &env );
if (env == NULL)
{
// failed
gJavaVM = NULL;
return 0;
}
if (!JniLibraryInit( env ))
{
// fail loading of JNI library
result = 0;
}
if (detach)
{
// detach thread from JNI
(*gJavaVM)->DetachCurrentThread( gJavaVM );
}
if (result != JNI_VERSION_1_6)
{
gJavaVM = NULL;
}
return result;
}
/*!
* @brief Initialize library.
*/
bool JniLibraryInit( JNIEnv *env )
{
int i;
JavaClassPtr_GethService = (*env)->FindClass( env, "com/statusim/GethService" );
if (JavaClassPtr_GethService == NULL) return false;
JavaClassPtr_GethService = (jclass)(*env)->NewGlobalRef( env, JavaClassPtr_GethService );
if (JavaClassPtr_GethService == NULL) return false;
struct { bool bStatic; jclass classPtr; jmethodID *methodPtr; const char *methodId; const char *params; } javaMethodDescriptors[] =
{
{ true, JavaClassPtr_GethService, &JavaMethodPtr_signalEvent, "signalEvent", "(Ljava/lang/String;)V" },
// { false, JavaClassPtr_GethService, &JavaMethodPtr_someNonStaticMethod, "someNonStaticMethod", "(Ljava/lang/String;)V" },
};
for (i = 0; i < sizeof(javaMethodDescriptors) / sizeof(javaMethodDescriptors[0]); i++)
{
if (javaMethodDescriptors[i].bStatic)
{
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetStaticMethodID( env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params );
}
else
{
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetMethodID( env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params );
}
if (*(javaMethodDescriptors[i].methodPtr) == NULL) return false;
}
return true;
}
/*!
* @brief Calls static method signalEvent of class com.statusim.GethService.
*
* @param jsonEvent - UTF8 string
*/
bool GethServiceSignalEvent( const char *jsonEvent )
{
bool detach;
JNIEnv *env;
// attach thread to JNI
detach = JniAttach( &env );
if (env == NULL)
{
// failed
return false;
}
jstring javaJsonEvent = NULL;
if (jsonEvent != NULL)
{
javaJsonEvent = (*env)->NewStringUTF( env, jsonEvent );
}
(*env)->CallStaticVoidMethod( env, JavaClassPtr_GethService, JavaMethodPtr_signalEvent, javaJsonEvent );
if (javaJsonEvent != NULL) (*env)->DeleteLocalRef( env, javaJsonEvent );
if (detach)
{
// detach thread from JNI
(*gJavaVM)->DetachCurrentThread( gJavaVM );
}
return true;
}

View File

@ -81,3 +81,20 @@ func StartNode(datadir *C.char) *C.char {
return C.CString(string(outBytes))
}
//export parse
func parse(chatId *C.char, js *C.char) *C.char {
res := Parse(C.GoString(chatId), C.GoString(js))
return C.CString(res)
}
//export call
func call(chatId *C.char, path *C.char, params *C.char) *C.char {
res := Call(C.GoString(chatId), C.GoString(path), C.GoString(params))
return C.CString(res)
}
//export initJail
func initJail(js *C.char) {
Init(C.GoString(js))
}