/** * Win32-specific thread proc */ STATIC DWORD WINAPI WIN32_ThreadProc(LPVOID arg) { ThrData * thr = arg; /* This must succeed since we are not allocating any memory */ VERIFY(VECTOR_Init(&thr->cleanupList,0,NULL,NULL)); #ifdef _USE_EXCEPTION_HANDLING __try { #endif /* _USE_EXCEPTION_HANDLING */ ASSERT(TlsGetValue(WIN32_TLS_ThrID) == NULL); VERIFY(TlsSetValue(WIN32_TLS_ThrID, thr)); if (WIN32_TLS_ThrID != TLS_OUT_OF_INDEXES) { ASSERT(TlsGetValue(WIN32_TLS_Data) == NULL); VERIFY(TlsSetValue(WIN32_TLS_Data, thr)); } (*thr->proc)(thr->arg); #ifdef _USE_EXCEPTION_HANDLING } __except(EXCEPTION_EXECUTE_HANDLER) { ASSMSG1("EXCEPTION %08lX in thread proc!",GetExceptionCode()); } #endif /* _USE_EXCEPTION_HANDLING */ THREAD_Cleanup(thr); return 0; }
/* * XML_Handle parses well-formed XML stream returning the root tag context * on success, NULL on failure. The endTag callback provided by the root tag * handler can be used to deallocate the root tag can context without any * side effects. However, in order to extract any useful information from the * root tag context, each object providing root tag handler would normally * provide a function that would exract such information from the root tag * (and deallocate everything else). * * The last parameter is a context parameter passed to the root tag callback * as the first argument. The code calling XML_Handle or the XMLHandleRoot * callback directly must know that XMLHandleRoot expects as a context * parameter. Typically, this is not a problem, but the use of this parameter * is discouraged. The XML stream should be self-sufficient, i.e. it should * contain all the information necessary to completely parse it. The context * parameter exists primarily to support for legacy XML file formats that * require extra parsing information in addition to the information contained * in the XML stream itself. */ XMLTag * XML_Handle(File * f, Str tag, XMLHandleRoot root, void * ctx) { XMLTag * rootTag = NULL; XMLContext context; memset(&context, 0, sizeof(context)); context.rootTagName = tag; context.rootHandler = root; context.rootContext = ctx; if (VECTOR_Init(&context.stack, 0, NULL, XML_VectorFreeTagContext)) { XMLCallbacks cb; memset(&cb, 0, sizeof(cb)); cb.startElem = XML_HandleStartElem; cb.endElem = XML_HandleEndElem; cb.charData = XML_HandleCharData; if (!XML_ParseStream(f, &cb, &context)) { context.error = True; } if (!context.error) { rootTag = context.rootTag; } else if (context.rootTag) { if (context.rootTag->endTag) { context.rootTag->endTag(context.rootTag, NULL); } else { MEM_Free(context.rootTag); } } /* * VECTOR_Destroy would destroy the elements starting with the * first element. We must start with the last element, which is * a natural cleanup order for a stack. If parsing was successful, * the vector is already empty. However, if parsing failed, the * vector may be non-empty and the order in which we deallocate the * tags must be opposite to the order in which they were created. */ while (!VECTOR_IsEmpty(&context.stack)) { VECTOR_Remove(&context.stack, VECTOR_Size(&context.stack)-1); } VECTOR_Destroy(&context.stack); } return rootTag; }
/** * This does essentially the same as JVM_Find2, only additional directories * are passed in as a variable list of strings. The list of directories * must be NULL terminated, for example: * * JVM_FindVa("../lib/jre", NULL); */ JVMSet * JVM_FindVa(Str dir1, ...) { if (!dir1) { return JVM_Find2(NULL, 0); } else { JVMSet* jvms; Str arg = dir1; va_list va; Vector dirs; VECTOR_Init(&dirs, 0, NULL, NULL); va_start(va, dir1); while (arg) { if (!VECTOR_Add(&dirs, arg)) { VECTOR_Destroy(&dirs); return NULL; } arg = va_arg(va, Str); } va_end(va); jvms = JVM_Find2((Str*)VECTOR_GetElements(&dirs), VECTOR_Size(&dirs)); VECTOR_Destroy(&dirs); return jvms; } }
/** * This routine runs EXPAT parser */ Bool XML_ParseStream(File * f, const XMLCallbacks * cb, void * ctx) { XML_Parser parser; Bool ok = False; /* set up memory management functions */ XML_Memory_Handling_Suite mem; memset(&mem, 0, sizeof(mem)); mem.malloc_fcn = MEM_Alloc; mem.realloc_fcn = MEM_Realloc; mem.free_fcn = MEM_Free; /* create parser */ parser = XML_ParserCreate_MM(NULL,&mem,NULL); if (parser) { int bufsize = 4096; void * buf = NULL; Bool done = False; /* initialize EXPAT */ ExpatContext expat; expat.ctx = ctx; expat.cb = (*cb); STRBUF_Init(&expat.sb); BUFFER_Init(&expat.buf); VECTOR_Init(&expat.atts, 0, NULL, NULL); /* initialize the parser */ XML_SetElementHandler(parser, EXPAT_StartElement, EXPAT_EndElement); XML_SetCharacterDataHandler(parser, EXPAT_Characters); XML_SetUserData(parser, &expat); /* * By obtaining the buffer from Expat with the XML_GetBuffer, * we can avoid double copying of the input. */ ok = True; while (ok && !done && (buf = XML_GetBuffer(parser,bufsize)) != NULL) { int len = -1; if (!FILE_Eof(f)) { len = FILE_Read(f, buf, bufsize); } if (len <= 0) { done = True; len = 0; } ok = XML_ParseBuffer(parser, len, done); } #if DEBUG if (!ok) { enum XML_Error code = XML_GetErrorCode(parser); int l = XML_GetCurrentLineNumber(parser); int c = XML_GetCurrentColumnNumber(parser); Str fname = FILE_Name(f); const char * msg = XML_ErrorString(code); if (!fname) fname = TEXT("<noname>"); if (!msg) msg = "<no message>"; # ifdef _WIN32 TRACE4("EXPAT: %s: line %d, column %d: %hs\n",fname,l,c,msg); # else /* _WIN32 */ TRACE4("EXPAT: %s: line %d, column %d: %s\n",fname,l,c,msg); # endif /* _WIN32 */ } #endif /* DEBUG */ if (!buf) ok = False; /* deallocate parser */ XML_ParserFree(parser); STRBUF_Destroy(&expat.sb); BUFFER_Destroy(&expat.buf); VECTOR_Destroy(&expat.atts); } return (ok); }
/** * The program entry point */ int main(int argc, char * argv[]) { int mask = ECMTGW_LISTEN_DEFAULT_MASK; Bool traceReceive = False; Bool traceSend = False; Str host = NULL; Str file = NULL; CmdLine* c; GwTrace trace; XRpcRegistry * r; /* Initialize the XRPC library */ XRPC_Init(); /* First step of initializing GwTrace context */ memset(&trace, 0, sizeof(trace)); VECTOR_Init(&trace.includeUid, 0, NULL, NULL); VECTOR_Init(&trace.excludeUid, 0, NULL, NULL); /* Parse command line */ c = CMDLINE_Create(pname); if (c) { CmdOpt* includeOpt; CmdOpt* excludeOpt; Bool done = False; Bool help = False; CMDLINE_SetMaxArgs(c, 1); CMDLINE_AddTrueOpt(c,'h',"help", "print this help and exit",&help); CMDLINE_AddTrueOpt(c,'s',"sent", "trace packets sent to the handset",&traceSend); CMDLINE_AddTrueOpt(c,'r',"receive", "trace packets received from the handset",&traceReceive); includeOpt = CMDLINE_AddOpt(c,'u',"include", "include this UID in the trace (repeatable)", GWTRACE_ParseUidOpt, &trace.includeUid, "UID"); excludeOpt = CMDLINE_AddOpt(c,'x',"exclude", "exclude this UID from the trace (repeatable)", GWTRACE_ParseUidOpt, &trace.excludeUid, "UID"); CMDLINE_SetParamName(CMDLINE_AddStrOpt(c,'o',"output", "write binary Ecmt messages into a file",&file),"FILE"); CMDLINE_SetRepeatable(includeOpt); CMDLINE_SetRepeatable(excludeOpt); CMDLINE_Exclude(includeOpt, excludeOpt); if (!CMDLINE_Parse1(c,argv+1,argc-1,0,&host) || help) { CMDLINE_Usage(c, "[HOST]", 0); CMDLINE_Delete(c); VECTOR_Destroy(&trace.includeUid); VECTOR_Destroy(&trace.excludeUid); XRPC_Deinit(); return 0; } CMDLINE_Delete(c); } if (traceReceive || traceSend) { mask = 0; if (traceReceive) mask |= ECMTGW_LISTEN_MASK_RECEIVE; if (traceSend) mask |= ECMTGW_LISTEN_MASK_SEND; } /* connect to the registry */ r = XREG_ConnectRegistry(host, XREG_DEFAULT_PORT); if (r) { /* find the server port */ XRpcPort gwPort = 0; XREG_List(r, ECMTGW_PROTOCOL, GWTRACE_ListCB, &gwPort); XREG_FreeRegistry(r); if (gwPort) { if (EVENT_Init(&exitEvent)) { if (GWTRACE_Init(&trace, host, gwPort, file)) { /* Install signal handlers */ #ifndef _WIN32 signal(SIGPIPE, GWTRACE_Interrupt); #endif /* _WIN32 */ signal(SIGINT, GWTRACE_Interrupt); /* Enable notifications */ XRPC_FormatNotify(XRPC_GetClient(trace.session), ECMTGW_PROTOCOL, ECMTGW_REGISTER_LISTENER_METHOD,"%" ECMTGW_LISTENER_PROTOCOL_PARAM"!s%" ECMTGW_LISTENER_MASK_PARAM"!i", ECMTGW_LISTENER_PROTOCOL, mask); /* Wait */ EVENT_Wait(&exitEvent); /* cleanup */ XRPC_FreeSession(trace.session); XRPC_FreeServer(trace.server); if (trace.file) FILE_Close(trace.file); } EVENT_Destroy(&exitEvent); } } else { PRINT_Error("%s: Ecmt Gateway is not running.\n",pname); } } else if (host) { PRINT_Verbose("%s: XRPC registry is not running on %s\n",pname,host); PRINT_Error("%s: Ecmt Gateway is not running on %s.\n",pname,host); } else { PRINT_Verbose("%s: XRPC registry is not running\n",pname); PRINT_Error("%s: Ecmt Gateway is not running.\n",pname); } VECTOR_Destroy(&trace.includeUid); VECTOR_Destroy(&trace.excludeUid); /* Deinitialize the XRPC library */ XRPC_Deinit(); return 0; }
/** * Discovers all available JVMs. If no JVMs are discovered, returns NULL. * In addition to the standard directories, also looks in the additional * directories specified by the dirs array. Note that this directory list * replaces the default list ("jre","../jre") used by JVM_Find, it does not * adds new directories to the list. */ JVMSet * JVM_Find2(const Str dirs[], int n) { JVMSet * jvms = MEM_New(JVMSet); if (jvms) { memset(jvms, 0, sizeof(*jvms)); if (VECTOR_Init(&jvms->found, 0, JVM_VectorEquals, JVM_VectorFree)) { /* Look for JVMs in the Windows registry */ JVM_Discover(jvms); /* Look for JVMs in the additional directories */ if (n > 0) { int i; StrBuf sb,sb2; Char* baseDir = NULL; STRBUF_Init(&sb); STRBUF_Init(&sb2); TRACE("JNILIB: checking special directories\n"); for (i=0; i<n; i++) { Str javaHome = NULL; JvmPathType pathType = JVM_GetPathType(dirs[i]); if (pathType == JvmPathRelative) { LPTSTR filePath; TRACE1("JNILIB: relative path: %s\n",dirs[i]); if (baseDir) { STRBUF_Copy(&sb, baseDir); } else { int separator; JVM_GetModuleFileName(NULL,&sb); STRBUF_Replace(&sb, '/', '\\'); separator = STRBUF_LastIndexOf(&sb,'\\'); STRBUF_SetLength(&sb,separator+1); baseDir = STRBUF_Dup(&sb); if (!baseDir) continue; TRACE1("JNILIB: base dir: %s\n",baseDir); } STRBUF_Append(&sb, dirs[i]); STRBUF_Replace(&sb, '/', '\\'); STRBUF_Alloc(&sb2, STRBUF_Length(&sb)); sb2.len = GetFullPathName(STRBUF_Text(&sb), sb2.alloc, sb2.s, &filePath); ASSERT(sb2.len && sb2.s[0]); javaHome = STRBUF_Text(&sb2); } else if (pathType == JvmPathAbsolute) { TRACE1("JNILIB: absolute path: %s\n",dirs[i]); javaHome = dirs[i]; } else if (pathType == JvmPathSystem) { /* directory on the system drive */ TRACE1("JNILIB: system path: %s\n",dirs[i]); STRBUF_Alloc(&sb,GetSystemDirectory(NULL,0)+1); STRBUF_SetLength(&sb,GetSystemDirectory(sb.s,sb.alloc)); STRBUF_Clear(&sb2); STRBUF_AppendChar(&sb2,STRBUF_CharAt(&sb,0)); STRBUF_AppendChar(&sb2,':'); STRBUF_Append(&sb2, dirs[i]); javaHome = STRBUF_Text(&sb2); } else { TRACE1("JNILIB: invalid path: %s\n",dirs[i]); continue; } if (javaHome) { TRACE1("JNILIB: Java home: %s\n",javaHome); if (FILE_IsDir(javaHome)) { JVM* jvm = JVM_CreateDirContext(javaHome); if (jvm) { jvm->flags |= JVM_FLAG_SPECIAL; if (JVM_Add(jvms, jvm) && !jvms->specialVM) { jvms->specialVM = jvm; } } } else { TRACE1("JNILIB: no such directory: %s\n",javaHome); } } } MEM_Free(baseDir); STRBUF_Destroy(&sb); STRBUF_Destroy(&sb2); } /* Did we find anything? */ if (!VECTOR_IsEmpty(&jvms->found)) { JVM_Sort(jvms, JVM_DefaultSort); TRACE1("JNILIB: found %d JVM(s)\n",VECTOR_Size(&jvms->found)); return jvms; } TRACE("JNILIB: found no JVMs\n, sorry"); VECTOR_Destroy(&jvms->found); } MEM_Free(jvms); } return NULL; }