/* * Library of functions for the Search4j utility */ #include "libsearch4j.h" #ifdef WINDOWS //minimal launch4j stuff #define NO_JAVA_FOUND 0 #define FOUND_JRE 1 #define FOUND_SDK 2 //windows functions #define popen _popen #define pclose _pclose #define strcmp _stricmp #endif /* WINDOWS */ void replace_all ( std::string & str, std::string const & pattern, std::string const & replacement ) { std::string::size_type start = str.find( pattern, 0 ); while ( start != str.npos ) { str.replace( start, pattern.size(), replacement ); start = str.find( pattern, start+replacement.size() ); } } int process( string command, bool render ) { #ifdef WINDOWS STARTUPINFO si; PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(pi)); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); DWORD dwExitCode = -1; char* cmd = (char*)command.c_str(); bool result; if ( render ) { result = CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); } else { result = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi); } if ( result ) { WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &dwExitCode); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } return dwExitCode; #else return system( command.c_str() ); #endif } int process_and_catch_output( string command, string &output ) { #ifdef WINDOWS char cmd[1024] = "cmd.exe /c "; strcat(cmd, command.c_str()); strcat(cmd, " > cmd_output.txt 2>&1"); //cerr << "command: " << cmd << endl; int code = process( cmd, false ); if ( code!= 0 ) return code; string line; ifstream myfile("cmd_output.txt"); if ( !myfile.is_open() ) { return -1; } while ( !myfile.eof() ) { getline(myfile,line); output.append( line ); } myfile.close(); _unlink( "cmd_output.txt" ); return code; #else FILE *pPipe; char cmd[1024]; strcpy(cmd, command.c_str()); strcat(cmd, " 2>&1" ); //if ( verbose ) cout << "process(): running '" << command << "'" << endl; if( (pPipe = popen( cmd, "r" )) == NULL ) { //if ( verbose ) cout << "could not start process" << endl; pclose( pPipe ); return -1; } //if ( verbose ) cout << "started process" << endl; /* Read pipe until end of file. */ while( !feof( pPipe ) ) { char psBuffer[128]; //if ( verbose ) cout << "get some data" << endl; if( fgets( psBuffer, 128, pPipe ) != NULL ) { //if ( verbose ) cout << "got: " << psBuffer << endl; output.append( psBuffer ); } else { //if ( verbose ) cout << "none left" << endl; } } /* Close pipe and return return value of pPipe. */ int code = pclose( pPipe ); return code; #endif } //Jvm class methods Jvm::Jvm() { healthy = false; } void Jvm::setJavaHome( string jh ) { healthy = true; javaHome = jh; setVersionFromExeOuput(); } string Jvm::getJavaHome() { return javaHome; } string Jvm::getExecutable() { string exec = ""; exec.append( javaHome ); #ifdef WINDOWS exec.append( "\\bin\\java.exe" ); #endif #ifndef WINDOWS exec.append( "/bin/java" ); #endif return exec; } #ifdef WINDOWS string Jvm::getWinExecutable() { string exec = ""; exec.append( javaHome ); exec.append( "\\bin\\javaw.exe" ); return exec; } #endif string Jvm::getVersion() { stringstream ss; ss << era << "." << major << "." << minor << "_" << update; return ss.str(); } bool Jvm::check() { return healthy; } bool Jvm::setVersionFromString( string version ) { era = atoi( version.substr(0,1).c_str() ); major = atoi( version.substr(2,1).c_str() ); minor = atoi( version.substr(4,1).c_str() ); update = atoi( version.substr(6,2).c_str() ); return true; } int Jvm::compare( Jvm otherJvm ) { //era if ( era > otherJvm.getEra() ) return 1; else if ( era < otherJvm.getEra() ) return -1; //major if ( major > otherJvm.getMajor() ) return 1; else if ( major < otherJvm.getMajor() ) return -1; //minor if ( minor > otherJvm.getMinor() ) return 1; else if ( minor < otherJvm.getMinor() ) return -1; //update if ( update > otherJvm.getUpdate() ) return 1; else if ( update < otherJvm.getUpdate() ) return -1; //all the same so far, must be exactly the same return 0; } int Jvm::getEra() { return era; } int Jvm::getMajor() { return major; } int Jvm::getMinor() { return minor; } int Jvm::getUpdate() { return update; } void Jvm::setVersionFromExeOuput() { string command = "", output = ""; command.append( "\"" ); command.append( getExecutable() ); command.append( "\"" ); command.append(" -version"); //cerr << "command: " << command << endl; int result = process_and_catch_output( command, output ); //cerr << "output: " << output << endl; if ( result == 0 ) { if ( strcmp( output.substr( 0, 12 ).c_str() , "java version" ) == 0 || true ) { era = atoi( output.substr(14,1).c_str() ); major = atoi( output.substr(16,1).c_str() ); minor = atoi( output.substr(18,1).c_str() ); update = atoi( output.substr(20,2).c_str() ); } else { healthy=false; } } else { healthy = false; } } //end of Jvm class methods #ifdef WINDOWS int regSearch(HKEY hKey, const char* keyName, int searchType, char* foundJavaVer ) { DWORD x = 0; unsigned long size = 1024; FILETIME time; char buffer[1024] = {0}; int foundJava = NO_JAVA_FOUND; while (RegEnumKeyEx( hKey, // handle to key to enumerate x++, // index of subkey to enumerate buffer, // address of buffer for subkey name &size, // address for size of subkey buffer NULL, // reserved NULL, // address of buffer for class string NULL, // address for size of class buffer &time) == ERROR_SUCCESS) { strcpy(foundJavaVer, buffer); foundJava = searchType; size = 1024; } return foundJava; } #endif /* * function to find java * implements the logic drawn on the dl lab whiteboard in feb 08 * return a Jvm object which represents the jvm on disk */ bool find( Jvm &jvm, bool use_minimum, Jvm minimum, string phint, string hint, bool verbose ) { if ( verbose ) cout << "Searching for a JVM" << endl; char *javaHome = ""; bool jvmFound = false; if ( !jvmFound ) { //try the priority hint if ( verbose ) cout << " - trying priority hint: "; if ( strcmp(phint.c_str(),"") != 0 ) { if ( verbose ) cout << "(" << phint << ") "; jvm.setJavaHome( phint ); if ( jvm.check() ) { if ( use_minimum ) { if ( jvm.compare( minimum ) >= 0 ) { jvmFound = true; } } else { jvmFound = true; } } } if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; } } if ( !jvmFound ) { //try JAVA_HOME if ( verbose ) cout << " - trying JAVA_HOME: "; javaHome = getenv( "JAVA_HOME" ); if ( javaHome != NULL ) { if ( verbose ) cout << "(" << javaHome << ") "; jvm.setJavaHome( javaHome ); if ( jvm.check() ) { if ( use_minimum ) { if ( jvm.compare( minimum ) >= 0 ) { jvmFound = true; } } else { jvmFound = true; } } } if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; } } if ( !jvmFound ) { //try JRE_HOME if ( verbose ) cout << " - trying JRE_HOME: "; javaHome = getenv( "JRE_HOME" ); if ( javaHome != NULL ) { if ( verbose ) cout << "(" << javaHome << ") "; jvm.setJavaHome( javaHome ); if ( jvm.check() ) { if ( use_minimum ) { if ( jvm.compare( minimum ) >= 0 ) { jvmFound = true; } } else { jvmFound = true; } } } if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; } } #ifdef WINDOWS if ( !jvmFound ) { //try the registry - this code based on launch4j code char foundJavaVer[8192] = {0}; int foundJava = NO_JAVA_FOUND; if ( verbose ) cout << " - trying the registry: "; cout.flush(); HKEY hKey; const char jre[] = "SOFTWARE\\JavaSoft\\Java Runtime Environment"; const char sdk[] = "SOFTWARE\\JavaSoft\\Java Development Kit"; if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(jre), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) { foundJava = regSearch(hKey, jre, FOUND_JRE, foundJavaVer); RegCloseKey(hKey); } if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(sdk), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS ) { foundJava = regSearch(hKey, sdk, FOUND_SDK, foundJavaVer); RegCloseKey(hKey); } if ( foundJava != NO_JAVA_FOUND ) { char path[1024] = {0}; char keyBuffer[1024]; unsigned long datatype; unsigned long bufferlength = 1024; if (foundJava == FOUND_JRE) { strcpy(keyBuffer, jre); } else { strcpy(keyBuffer, sdk); } strcat(keyBuffer, "\\"); strcat(keyBuffer, foundJavaVer); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(keyBuffer), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { unsigned char buffer[1024] = {0}; if (RegQueryValueEx(hKey, "JavaHome", NULL, &datatype, buffer, &bufferlength) == ERROR_SUCCESS) { int i = 0; do { path[i] = buffer[i]; } while (path[i++] != 0); if (foundJava == FOUND_SDK) { strcat(path, "\\jre"); } if ( verbose ) cerr << "path: " << path << endl ; jvm.setJavaHome( path ); if ( jvm.check() ) { if ( use_minimum ) { if ( jvm.compare( minimum ) >= 0 ) { jvmFound = true; } } else { jvmFound = true; } } } RegCloseKey(hKey); } } if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; } } #endif if ( !jvmFound ) { //try the hint if ( verbose ) cout << " - trying hint: "; if ( strcmp(hint.c_str(),"") != 0 ) { if ( verbose ) cout << "(" << hint << ") "; jvm.setJavaHome( hint ); if ( jvm.check() ) { if ( use_minimum ) { if ( jvm.compare( minimum ) >= 0 ) { jvmFound = true; } } else { jvmFound = true; } } } if ( verbose ) { if( jvmFound ) cout << "yes" << endl; else cout << "no" << endl; } } return jvmFound; }