/*-*- mode: C; tab-width:4 -*-*/ #include #include #include #include "protocol.h" static void swrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { int n = fwrite(ptr, size, nmemb, stream); //printf("write char:.:%d\n", (unsigned int) ((char*)ptr)[0]); assert(n==nmemb); } static void sread(void *ptr, size_t size, size_t nmemb, FILE *stream) { int n = fread(ptr, size, nmemb, stream); //printf("read char:.:%d\n", (unsigned int) ((char*)ptr)[0]); assert(n==nmemb); } static void id(proxyenv *env, char id) { swrite(&id, sizeof id, 1, (*env)->peer); } /* * The following Invoke, CreateObject, GetSetProp and LastException methods start everything */ static void do_invoke(proxyenv *env, jobject php_reflect, jmethodID invoke, jobject obj, jstring method, jobjectArray array, jlong result) { swrite(&php_reflect, sizeof php_reflect, 1, (*env)->peer); swrite(&invoke, sizeof invoke, 1, (*env)->peer); swrite(&obj, sizeof obj, 1, (*env)->peer); swrite(&method, sizeof method, 1, (*env)->peer); swrite(&array, sizeof array, 1, (*env)->peer); swrite(&result, sizeof result, 1, (*env)->peer); (*env)->handle_request(env); } static void Invoke(proxyenv *env, jobject php_reflect, jmethodID invoke, jobject obj, jstring method, jobjectArray array, jlong result) { id(env, INVOKE); do_invoke(env, php_reflect, invoke, obj, method, array, result); } static void LastException(proxyenv *env, jobject php_reflect, jmethodID lastEx, jlong result) { id(env, LASTEXCEPTION); swrite(&php_reflect, sizeof php_reflect, 1, (*env)->peer); swrite(&lastEx, sizeof lastEx, 1, (*env)->peer); swrite(&result, sizeof result, 1, (*env)->peer); (*env)->handle_request(env); } static void CreateObject(proxyenv *env, jobject php_reflect, jmethodID invoke, jstring method, jobjectArray array, jlong result) { id(env, CREATEOBJECT); swrite(&php_reflect, sizeof php_reflect, 1, (*env)->peer); swrite(&invoke, sizeof invoke, 1, (*env)->peer); swrite(&method, sizeof method, 1, (*env)->peer); swrite(&array, sizeof array, 1, (*env)->peer); swrite(&result, sizeof result, 1, (*env)->peer); (*env)->handle_request(env); } static void GetSetProp(proxyenv *env, jobject php_reflect, jmethodID gsp, jobject obj, jstring propName, jobjectArray value, jlong result) { id(env, GETSETPROP); do_invoke(env, php_reflect, gsp, obj, propName, value, result); } static jobject AllocObject (proxyenv *env, jclass clazz) { jobject result; id(env, ALLOCOBJECT); swrite(&clazz, sizeof clazz, 1, (*env)->peer); sread(&result, sizeof result, 1, (*env)->peer); return result; } static jobject CallObjectMethod (short count, proxyenv *env, jobject obj, jmethodID methodID, ...) { va_list args; jvalue arg; jobject result; id(env, CALLOBJECTMETHOD); swrite(&count, sizeof count, 1, (*env)->peer); swrite(&obj, sizeof obj, 1, (*env)->peer); swrite(&methodID, sizeof methodID, 1, (*env)->peer); va_start(args, methodID); while(count--) { arg=va_arg(args,jvalue ); swrite(&arg, sizeof arg, 1, (*env)->peer); } va_end(args); sread(&result, sizeof result, 1, (*env)->peer); return result; } static void CallVoidMethod (short count, proxyenv *env, jobject obj, jmethodID methodID, ...) { va_list args; jvalue arg; jobject result; id(env, CALLVOIDMETHOD); swrite(&count, sizeof count, 1, (*env)->peer); swrite(&obj, sizeof obj, 1, (*env)->peer); swrite(&methodID, sizeof methodID, 1, (*env)->peer); va_start(args, methodID); while(count--) { arg=va_arg(args, jvalue); swrite(&arg, sizeof arg, 1, (*env)->peer); } va_end(args); } static void DeleteGlobalRef (proxyenv *env, jobject gref) { id(env, DELETEGLOBALREF); swrite(&gref, sizeof gref, 1, (*env)->peer); } static void DeleteLocalRef (proxyenv *env, jobject obj) { id(env, DELETELOCALREF); swrite(&obj, sizeof obj, 1, (*env)->peer); } static void ExceptionClear (proxyenv *env) { id(env, EXCEPTIONCLEAR); } static jthrowable ExceptionOccurred (proxyenv *env) { jthrowable result; id(env, EXCEPTIONOCCURRED); sread(&result, sizeof result, 1, (*env)->peer); return result; } static jclass FindClass (proxyenv *env, const char *name) { short len=strlen(name); jclass clazz; id(env, FINDCLASS); swrite(&len, sizeof len, 1, (*env)->peer); swrite(name, sizeof*name, len, (*env)->peer); sread(&clazz, sizeof clazz, 1, (*env)->peer); return clazz; } static jsize GetArrayLength (proxyenv *env, jarray array) { jsize result; id(env, GETARRAYLENGTH); swrite(&array, sizeof array, 1, (*env)->peer); sread(&result, sizeof result, 1, (*env)->peer); return result; } static jbyte *GetByteArrayElements (proxyenv *env, jbyteArray array, jboolean *isCopy) { short count; jboolean dummy; jbyte *result; id(env, GETBYTEARRAYELEMENTS); swrite(&array, sizeof array, 1, (*env)->peer); sread(&dummy, sizeof dummy, 1, (*env)->peer); sread(&count, sizeof count, 1, (*env)->peer); result=(jbyte*)calloc(count, sizeof*result); assert(result); sread(result, sizeof*result, count, (*env)->peer); assert(isCopy); if(isCopy) *isCopy=dummy; swrite(&result, sizeof result, 1, (*env)->peer); return result; } static jmethodID GetMethodID (proxyenv *env, jclass clazz, const char *name, const char *sig) { jmethodID mid; short len; id(env, GETMETHODID); swrite(&clazz, sizeof clazz, 1, (*env)->peer); len=strlen(name); swrite(&len, sizeof len, 1, (*env)->peer); swrite(name, sizeof*name, len, (*env)->peer); len=strlen(sig); swrite(&len, sizeof len, 1, (*env)->peer); swrite(sig, sizeof*sig, len, (*env)->peer); sread(&mid, sizeof mid, 1, (*env)->peer); return mid; } static jclass GetObjectClass (proxyenv *env, jobject obj) { jclass result; id(env, GETOBJECTCLASS); swrite(&obj, sizeof obj, 1, (*env)->peer); sread(&result, sizeof result, 1, (*env)->peer); return result; } static const char* GetStringUTFChars (proxyenv *env, jstring str, jboolean *isCopy) { short count; char *result; jboolean dummy; id(env, GETSTRINGUTFCHARS); swrite(&str, sizeof str, 1, (*env)->peer); sread(&dummy, sizeof dummy, 1, (*env)->peer); sread(&count, sizeof count, 1, (*env)->peer); result=(char*)malloc(count+1); assert(result); sread(result, sizeof*result, count, (*env)->peer); result[count]=0; assert(isCopy); if(isCopy) *isCopy=dummy; swrite(&result, sizeof result, 1, (*env)->peer); return result; } static jbyteArray NewByteArray (proxyenv *env, jsize len) { jbyteArray result; id(env, NEWBYTEARRAY); swrite(&len, sizeof len, 1, (*env)->peer); sread(&result, sizeof result, 1, (*env)->peer); return result; } static jobject NewGlobalRef (proxyenv *env, jobject lobj) { jobject result; id(env, NEWGLOBALREF); swrite(&lobj, sizeof lobj, 1, (*env)->peer); sread(&result, sizeof result, 1, (*env)->peer); return result; } static jobject NewObject (short count, proxyenv *env, jclass clazz, jmethodID methodID, ...) { va_list args; jvalue arg; jobject result; id(env, NEWOBJECT); swrite(&count, sizeof count, 1, (*env)->peer); swrite(&clazz, sizeof clazz, 1, (*env)->peer); swrite(&methodID, sizeof methodID, 1, (*env)->peer); va_start(args, methodID); while(count--) { arg=va_arg(args, jvalue); swrite(&arg, sizeof arg, 1, (*env)->peer); } va_end(args); sread(&result, sizeof result, 1, (*env)->peer); return result; } static jobjectArray NewObjectArray (proxyenv *env, jsize len, jclass clazz, jobject init) { jobjectArray result; id(env, NEWOBJECTARRAY); swrite(&len, sizeof len, 1, (*env)->peer); swrite(&clazz, sizeof clazz, 1, (*env)->peer); swrite(&init, sizeof init, 1, (*env)->peer); sread(&result, sizeof result, 1, (*env)->peer); return result; } static jstring NewStringUTF (proxyenv *env, const char *utf) { jstring result; short length=strlen(utf); id(env, NEWSTRINGUTF); swrite(&length, sizeof length, 1, (*env)->peer); swrite(utf, sizeof*utf, length, (*env)->peer); sread(&result, sizeof result, 1, (*env)->peer); return result; } static void ReleaseByteArrayElements (proxyenv *env, jbyteArray array, jbyte *elems, jint mode) { short count; id(env, RELEASEBYTEARRAYELEMENTS); swrite(&array, sizeof array, 1, (*env)->peer); swrite(&elems, sizeof elems, 1, (*env)->peer); swrite(&mode, sizeof mode, 1, (*env)->peer); assert(!mode); free(elems); } static void ReleaseStringUTFChars (proxyenv *env, jstring array, const char*elems) { short count; id(env, RELEASESTRINGUTFCHARS); swrite(&array, sizeof array, 1, (*env)->peer); swrite(&elems, sizeof elems, 1, (*env)->peer); free(elems); } static void SetByteArrayRegion (proxyenv *env, jbyteArray array, jsize start, jsize len, jbyte *buf) { id(env, SETBYTEARRAYREGION); swrite(&array, sizeof array, 1, (*env)->peer); swrite(&start, sizeof start, 1, (*env)->peer); swrite(&len, sizeof len, 1, (*env)->peer); swrite(buf, sizeof*buf, len, (*env)->peer); } static void SetObjectArrayElement (proxyenv *env, jobjectArray array, jsize index, jobject val) { id(env, SETOBJECTARRAYELEMENT); swrite(&array, sizeof array, 1, (*env)->peer); swrite(&index, sizeof index, 1, (*env)->peer); swrite(&val, sizeof val, 1, (*env)->peer); } proxyenv *java_createSecureEnvironment(FILE *peer, int (*handle_request)(proxyenv *env)) { proxyenv *env; env=(proxyenv*)malloc(sizeof *env); *env=(proxyenv)calloc(1, sizeof **env); (*env)->peer = peer; (*env)->handle_request = handle_request; (*env)->LastException=LastException; (*env)->GetSetProp=GetSetProp; (*env)->Invoke=Invoke; (*env)->CreateObject=CreateObject; (*env)->AllocObject=AllocObject; (*env)->CallObjectMethod=CallObjectMethod; (*env)->CallVoidMethod=CallVoidMethod; (*env)->DeleteGlobalRef=DeleteGlobalRef; (*env)->DeleteLocalRef=DeleteLocalRef; (*env)->ExceptionClear=ExceptionClear; (*env)->ExceptionOccurred=ExceptionOccurred; (*env)->FindClass=FindClass; (*env)->GetArrayLength=GetArrayLength; (*env)->GetByteArrayElements=GetByteArrayElements; (*env)->GetMethodID=GetMethodID; (*env)->GetObjectClass=GetObjectClass; (*env)->GetStringUTFChars=GetStringUTFChars; (*env)->NewByteArray=NewByteArray; (*env)->NewGlobalRef=NewGlobalRef; (*env)->NewObject=NewObject; (*env)->NewObjectArray=NewObjectArray; (*env)->NewStringUTF=NewStringUTF; (*env)->ReleaseByteArrayElements=ReleaseByteArrayElements; (*env)->ReleaseStringUTFChars=ReleaseStringUTFChars; (*env)->SetByteArrayRegion=SetByteArrayRegion; (*env)->SetObjectArrayElement=SetObjectArrayElement; return env; }