|
@ -20,12 +20,71 @@ typedef union { |
|
|
void* venv; |
|
|
void* venv; |
|
|
} UnionJNIEnvToVoid; |
|
|
} UnionJNIEnvToVoid; |
|
|
|
|
|
|
|
|
|
|
|
typedef unsigned short char16_t; |
|
|
|
|
|
|
|
|
|
|
|
class String8 { |
|
|
|
|
|
public: |
|
|
|
|
|
String8() { |
|
|
|
|
|
mString = 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
~String8() { |
|
|
|
|
|
if (mString) { |
|
|
|
|
|
free(mString); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void set(const char16_t* o, size_t numChars) { |
|
|
|
|
|
if (mString) { |
|
|
|
|
|
free(mString); |
|
|
|
|
|
} |
|
|
|
|
|
mString = (char*) malloc(numChars + 1); |
|
|
|
|
|
if (!mString) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
for (size_t i = 0; i < numChars; i++) { |
|
|
|
|
|
mString[i] = (char) o[i]; |
|
|
|
|
|
} |
|
|
|
|
|
mString[numChars] = '\0'; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const char* string() { |
|
|
|
|
|
return mString; |
|
|
|
|
|
} |
|
|
|
|
|
private: |
|
|
|
|
|
char* mString; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
static UnionJNIEnvToVoid uenv; |
|
|
static UnionJNIEnvToVoid uenv; |
|
|
static jmethodID newProtectedSocketMethod = NULL; |
|
|
static jmethodID newProtectedSocketMethod = NULL; |
|
|
static jmethodID freeProtectedSocketMethod = NULL; |
|
|
static jmethodID freeProtectedSocketMethod = NULL; |
|
|
static jclass clazz = NULL; |
|
|
static jclass clazz = NULL; |
|
|
|
|
|
|
|
|
static const char *classPathName = "com/github/shadowsocks/Socket"; |
|
|
|
|
|
|
|
|
static const char *classPathName = "com/github/shadowsocks/Daemon"; |
|
|
|
|
|
|
|
|
|
|
|
void Java_com_github_shadowsocks_daemon_exec(JNIEnv *env, jobject thiz, jobjectArray argv) { |
|
|
|
|
|
|
|
|
|
|
|
int argc = argv ? env->GetArrayLength(argv) : 0; |
|
|
|
|
|
char **daemon_argv = NULL; |
|
|
|
|
|
String8 tmp_8; |
|
|
|
|
|
|
|
|
|
|
|
if (argc > 0) { |
|
|
|
|
|
daemon_argv = (char **)malloc((argc+1)*sizeof(char *)); |
|
|
|
|
|
for (int i = 0; i < argc; ++i) { |
|
|
|
|
|
jstring arg = reinterpret_cast<jstring>(env->GetObjectArrayElement(argv, i)); |
|
|
|
|
|
const jchar *str = env->GetStringCritical(arg, 0); |
|
|
|
|
|
tmp_8.set(str, env->GetStringLength(arg)); |
|
|
|
|
|
env->ReleaseStringCritical(arg, str); |
|
|
|
|
|
daemon_argv[i] = strdup(tmp_8.string()); |
|
|
|
|
|
} |
|
|
|
|
|
daemon_argv[args] = NULL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int ret = main(argc, daemon_argv); |
|
|
|
|
|
|
|
|
|
|
|
for (init i = 0; i < argc; i++) free(daemon_argv[i]); |
|
|
|
|
|
free(daemon_argv); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/*
|
|
|
/*
|
|
|
* Register several native methods for one class. |
|
|
* Register several native methods for one class. |
|
@ -54,6 +113,16 @@ static int registerNativeMethods(JNIEnv* env, const char* className) |
|
|
return JNI_FALSE; |
|
|
return JNI_FALSE; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
JNINativeMethod methods[] = { |
|
|
|
|
|
{ "exec", "([Ljava/lang/String;)V", |
|
|
|
|
|
(void*) Java_com_github_shadowsocks_daemon_exec } |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
if (env->RegisterNatives(clazz, methods, 1) < 0) { |
|
|
|
|
|
LOGE("RegisterNatives failed for '%s'", className); |
|
|
|
|
|
return JNI_FALSE; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return JNI_TRUE; |
|
|
return JNI_TRUE; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|