bool util_findFile(const char* dirs[], unsigned int numDirs, const char* relativeFilePath, char* absoluteFilePath) { bool found = false; // check if it is an absolute file path if (util_fileExists(relativeFilePath)) { STRCPY(absoluteFilePath, relativeFilePath); found = true; } unsigned int d; for (d=0; d < numDirs && !found; ++d) { // do the following: tmpPath = dirs[d] + sPS + relativeFilePath char* tmpPath = util_allocStr(strlen(dirs[d]) + 1 + strlen(relativeFilePath)); //char tmpPath[strlen(dirs[d]) + 1 + strlen(relativeFilePath) + 1]; tmpPath[0]= '\0'; tmpPath = STRCAT(tmpPath, dirs[d]); tmpPath = STRCAT(tmpPath, sPS); tmpPath = STRCAT(tmpPath, relativeFilePath); if (util_fileExists(tmpPath)) { STRCPY(absoluteFilePath, tmpPath); found = true; } free(tmpPath); } return found; }
/** * Creates the Java library path. * -> where native shared libraries are searched * * It will consist of the following: * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/lib/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/lib/ */ static bool java_createNativeLibsPath(char* libraryPath, const size_t libraryPath_sizeMax) { // {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/ const char* const dd_r = callback->AIInterface_Info_getValueByKey(interfaceId, AI_INTERFACE_PROPERTY_DATA_DIR); if (dd_r == NULL) { simpleLog_logL(SIMPLELOG_LEVEL_ERROR, "Unable to find read-only data-dir."); return false; } else { STRCPYS(libraryPath, libraryPath_sizeMax, dd_r); } // {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/lib/ char* dd_lib_r = callback->DataDirs_allocatePath(interfaceId, NATIVE_LIBS_DIR, false, false, true, false); if (dd_lib_r == NULL) { simpleLog_logL(SIMPLELOG_LEVEL_NORMAL, "Unable to find read-only native libs data-dir (optional): %s", NATIVE_LIBS_DIR); } else { STRCATS(libraryPath, libraryPath_sizeMax, ENTRY_DELIM); STRCATS(libraryPath, libraryPath_sizeMax, dd_lib_r); FREE(dd_lib_r); } // {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/ const char* const dd_r_common = callback->AIInterface_Info_getValueByKey(interfaceId, AI_INTERFACE_PROPERTY_DATA_DIR_COMMON); if (dd_r_common == NULL || !util_fileExists(dd_r_common)) { simpleLog_logL(SIMPLELOG_LEVEL_NORMAL, "Unable to find common read-only data-dir (optional)."); } else { STRCATS(libraryPath, libraryPath_sizeMax, ENTRY_DELIM); STRCATS(libraryPath, libraryPath_sizeMax, dd_r_common); } // {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/lib/ if (dd_r_common != NULL) { char* dd_lib_r_common = callback->DataDirs_allocatePath(interfaceId, NATIVE_LIBS_DIR, false, false, true, true); if (dd_lib_r_common == NULL || !util_fileExists(dd_lib_r_common)) { simpleLog_logL(SIMPLELOG_LEVEL_NORMAL, "Unable to find common read-only native libs data-dir (optional)."); } else { STRCATS(libraryPath, libraryPath_sizeMax, ENTRY_DELIM); STRCATS(libraryPath, libraryPath_sizeMax, dd_lib_r_common); FREE(dd_lib_r_common); } } return true; }
bool util_findDir(const char* dirs[], unsigned int numDirs, const char* relativeDirPath, char* absoluteDirPath, bool searchOnlyWriteable, bool create) { bool found = false; // check if it is an absolute file path if (util_fileExists(relativeDirPath)) { STRCPY(absoluteDirPath, relativeDirPath); found = true; } if (searchOnlyWriteable && numDirs > 1) { numDirs = 1; } unsigned int d; for (d=0; d < numDirs && !found; ++d) { // do the following: tmpPath = dirs[d] + sPS + relativeFilePath char* tmpPath = util_allocStr(strlen(dirs[d]) + 1 + strlen(relativeDirPath)); //char tmpPath[strlen(dirs[d]) + 1 + strlen(relativeDirPath) + 1]; tmpPath[0]= '\0'; tmpPath = STRCAT(tmpPath, dirs[d]); tmpPath = STRCAT(tmpPath, sPS); tmpPath = STRCAT(tmpPath, relativeDirPath); if (util_fileExists(tmpPath)) { STRCPY(absoluteDirPath, tmpPath); found = true; } free(tmpPath); } // not found -> create it if (!found && create && numDirs >= 1) { STRCAT(absoluteDirPath, dirs[0]); STRCAT(absoluteDirPath, sPS); STRCAT(absoluteDirPath, relativeDirPath); found = util_makeDir(absoluteDirPath); } return found; }
bool util_makeDirRecursive(const char* dirPath) { if (!util_fileExists(dirPath)) { char parentDir[strlen(dirPath)+1]; bool hasParent = util_getParentDir(dirPath, parentDir); if (hasParent) { bool parentExists = util_makeDirRecursive(parentDir); if (parentExists) { return util_makeDir(dirPath); } } return false; } return true; }
/** * Creates a Skirmish AI local Java class path. * * It will consist of the following: * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/SkirmishAI.jar * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/(j)?config/ * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/(j)?config/[*].jar * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/(j)?resources/ * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/(j)?resources/[*].jar * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/(j)?script/ * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/(j)?script/[*].jar * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/jlib/ * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/jlib/[*].jar * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/common/(j)?config/ * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/common/(j)?config/[*].jar * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/common/(j)?resources/ * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/common/(j)?resources/[*].jar * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/common/(j)?script/ * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/common/(j)?script/[*].jar * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/common/jlib/ * {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/common/jlib/[*].jar */ static size_t java_createAIClassPath(const char* shortName, const char* version, char** classPathParts, const size_t classPathParts_sizeMax) { size_t classPathParts_size = 0; // the .jar files in the following list will be added to the classpath const size_t jarFiles_sizeMax = classPathParts_sizeMax; char** jarFiles = (char**) calloc(jarFiles_sizeMax, sizeof(char*)); size_t jarFiles_size = 0; const char* const skirmDD = callback->SkirmishAIs_Info_getValueByKey(interfaceId, shortName, version, SKIRMISH_AI_PROPERTY_DATA_DIR); if (skirmDD == NULL) { simpleLog_logL(SIMPLELOG_LEVEL_ERROR, "Retrieving the data-dir of Skirmish AI %s-%s failed.", shortName, version); } // {spring-data-dir}/{SKIRMISH_AI_DATA_DIR}/{ai-name}/{ai-version}/SkirmishAI.jar jarFiles[jarFiles_size++] = util_allocStrCatFSPath(2, skirmDD, "SkirmishAI.jar"); // the directories in the following list will be searched for .jar files // which then will be added to the classpath, plus they will be added // to the classpath directly, so you can keep .class files in there const size_t jarDirs_sizeMax = classPathParts_sizeMax; char** jarDirs = (char**) calloc(jarDirs_sizeMax, sizeof(char*)); size_t jarDirs_size = 0; // add to classpath ... // {spring-data-dir}/Skirmish/MyJavaAI/0.1/SkirmishAI/ // this can be usefull for AI devs while testing, // if they do not want to put everything into a jar all the time jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDD, "SkirmishAI"); // add to classpath: // {spring-data-dir}/Skirmish/MyJavaAI/0.1/${x}/ jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDD, "jconfig"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDD, "config"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDD, "jresources"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDD, "resources"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDD, "jscript"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDD, "script"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDD, "jlib"); // "lib" is for native libs only // add the dir common for all versions of the Skirmish AI, // if it is specified and exists const char* const skirmDDCommon = callback->SkirmishAIs_Info_getValueByKey(interfaceId, shortName, version, SKIRMISH_AI_PROPERTY_DATA_DIR_COMMON); if (skirmDDCommon != NULL) { // add to classpath: // {spring-data-dir}/Skirmish/MyJavaAI/common/${x}/ jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDDCommon, "jconfig"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDDCommon, "config"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDDCommon, "jresources"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDDCommon, "resources"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDDCommon, "jscript"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDDCommon, "script"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, skirmDDCommon, "jlib"); // "lib" is for native libs only } // add the directly specified .jar files size_t jf; for (jf = 0; (jf < jarFiles_size) && (classPathParts_size < classPathParts_sizeMax); ++jf) { classPathParts[classPathParts_size++] = util_allocStrCpy(jarFiles[jf]); FREE(jarFiles[jf]); } // add the dirs and the contained .jar files size_t jd, sjf; for (jd = 0; (jd < jarDirs_size) && (classPathParts_size < classPathParts_sizeMax); ++jd) { if (jarDirs[jd] != NULL && util_fileExists(jarDirs[jd])) { // add the jar dir (for .class files) // For this to work properly with URLClassPathHandler, // we have to ensure there is a '/' at the end, // for the class-path-part to be recognized as a directory. classPathParts[classPathParts_size++] = util_allocStrCat(2, jarDirs[jd], "/"); // add the jars in the dir const size_t subJarFiles_sizeMax = classPathParts_sizeMax - classPathParts_size; char** subJarFiles = (char**) calloc(subJarFiles_sizeMax, sizeof(char*)); const size_t subJarFiles_size = util_listFiles(jarDirs[jd], ".jar", subJarFiles, true, subJarFiles_sizeMax); for (sjf = 0; (sjf < subJarFiles_size) && (classPathParts_size < classPathParts_sizeMax); ++sjf) { // .../[*].jar classPathParts[classPathParts_size++] = util_allocStrCatFSPath(2, jarDirs[jd], subJarFiles[sjf]); FREE(subJarFiles[sjf]); } FREE(subJarFiles); } FREE(jarDirs[jd]); } FREE(jarDirs); FREE(jarFiles); return classPathParts_size; }
/** * Creates the AI Interface global Java class path. * * It will consist of the following: * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/AIInterface.jar * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?config/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?config/[*].jar * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?resources/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?resources/[*].jar * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?script/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?script/[*].jar * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/jlib/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/jlib/[*].jar * TODO: {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/jlib/ * TODO: {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/jlib/[*].jar */ static size_t java_createClassPath(char* classPathStr, const size_t classPathStr_sizeMax) { // the dirs and .jar files in the following array // will be concatenated with intermediate path separators // to form the classPathStr static const size_t classPath_sizeMax = 128; char** classPath = (char**) calloc(classPath_sizeMax, sizeof(char*)); size_t classPath_size = 0; // the Java AI Interfaces java library file path (.../AIInterface.jar) // We need to search for this jar, instead of looking only where // the AIInterface.so/InterfaceInfo.lua is, because on some systems // (eg. Debian), the .so is in /usr/lib, and the .jar's are in /usr/shared. char* mainJarPath = callback->DataDirs_allocatePath(interfaceId, JAVA_AI_INTERFACE_LIBRARY_FILE_NAME, false, false, false, false); classPath[classPath_size++] = util_allocStrCpy(mainJarPath); bool ok = util_getParentDir(mainJarPath); if (!ok) { simpleLog_logL(SIMPLELOG_LEVEL_ERROR, "Retrieving the parent dir of the path to AIInterface.jar (%s) failed.", mainJarPath); } char* jarsDataDir = mainJarPath; mainJarPath = NULL; // the directories in the following list will be searched for .jar files // which will then be added to the classPathStr, plus the dirs will be added // to the classPathStr directly, so you can keep .class files in there static const size_t jarDirs_sizeMax = 128; char** jarDirs = (char**) calloc(jarDirs_sizeMax, sizeof(char*)); size_t jarDirs_size = 0; // add to classpath: // {spring-data-dir}/Interfaces/Java/0.1/${x}/ jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "jconfig"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "config"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "jresources"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "resources"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "jscript"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "script"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "jlib"); // "lib" is for native libs only // add the jar dirs (for .class files) and all contained .jars recursively size_t jd, jf; for (jd=0; (jd < jarDirs_size) && (classPath_size < classPath_sizeMax); ++jd) { if (util_fileExists(jarDirs[jd])) { // add the dir directly // For this to work properly with URLClassPathHandler, // we have to ensure there is a '/' at the end, // for the class-path-part to be recognized as a directory. classPath[classPath_size++] = util_allocStrCat(2, jarDirs[jd], "/"); // add the contained jars recursively static const size_t jarFiles_sizeMax = 128; char** jarFiles = (char**) calloc(jarFiles_sizeMax, sizeof(char*)); const size_t jarFiles_size = util_listFiles(jarDirs[jd], ".jar", jarFiles, true, jarFiles_sizeMax); for (jf=0; (jf < jarFiles_size) && (classPath_size < classPath_sizeMax); ++jf) { classPath[classPath_size++] = util_allocStrCatFSPath(2, jarDirs[jd], jarFiles[jf]); FREE(jarFiles[jf]); } FREE(jarFiles); } FREE(jarDirs[jd]); } FREE(jarDirs); // concat the classpath entries classPathStr[0] = '\0'; if (classPath[0] != NULL) { STRCATS(classPathStr, classPathStr_sizeMax, classPath[0]); FREE(classPath[0]); } size_t cp; for (cp=1; cp < classPath_size; ++cp) { if (classPath[cp] != NULL) { STRCATS(classPathStr, classPathStr_sizeMax, ENTRY_DELIM); STRCATS(classPathStr, classPathStr_sizeMax, classPath[cp]); FREE(classPath[cp]); } } FREE(classPath); return classPath_size; }