osal_lib_search *osal_library_search(const char *searchpath) { osal_lib_search *head = NULL, *curr = NULL; DIR *dir; struct dirent *entry; #ifdef __APPLE__ const char* suffix = ".dylib"; #else const char* suffix = ".so"; #endif dir = opendir(searchpath); if (dir == NULL) return NULL; /* look for any shared libraries in this folder */ while ((entry = readdir(dir)) != NULL) { osal_lib_search *newlib = NULL; if (strcmp(entry->d_name + strlen(entry->d_name) - strlen(suffix), suffix) != 0) continue; /* this is a .so file, so add it to the list */ newlib = malloc(sizeof(osal_lib_search)); if (newlib == NULL) { DebugMessage(M64MSG_ERROR, "Memory allocation error in osal_library_search()!"); osal_free_lib_list(head); closedir(dir); return NULL; } if (head == NULL) { head = curr = newlib; } else { curr->next = newlib; curr = newlib; } /* set up the filepath and filename members */ strncpy(curr->filepath, searchpath, PATH_MAX-2); curr->filepath[PATH_MAX-2] = 0; if (curr->filepath[strlen(curr->filepath)-1] != '/') strcat(curr->filepath, "/"); int pathlen = strlen(curr->filepath); curr->filename = curr->filepath + pathlen; strncat(curr->filepath, entry->d_name, PATH_MAX - pathlen - 1); curr->filepath[PATH_MAX-1] = 0; /* set plugin_type and next pointer */ curr->plugin_type = 0; curr->next = NULL; } closedir(dir); return head; }
/* global functions */ m64p_error PluginSearchLoad() { m64p_handle ConfigUI; if (ConfigGetSectionHandle(CONFIG_SECTION_UI, &ConfigUI) != M64ERR_SUCCESS) { return M64ERR_PLUGIN_FAIL; } osal_lib_search *lib_filelist = NULL; int i; /* start by checking the directory given on the command line */ if (g_PluginDir != NULL) { lib_filelist = osal_library_search(g_PluginDir); if (lib_filelist == NULL) { fprintf(stderr, "Error: No plugins found in --plugindir path: %s\n", g_PluginDir); return M64ERR_INPUT_NOT_FOUND; } } /* if no plugins found, search the PluginDir in the UI-console section of the config file */ if (lib_filelist == NULL) { const char *plugindir = (*ConfigGetParamString)(ConfigUI, "PluginDir"); lib_filelist = osal_library_search(plugindir); } /* if still no plugins found, search some common system folders */ if (lib_filelist == NULL) { for (i = 0; i < osal_libsearchdirs; i++) { lib_filelist = osal_library_search(osal_libsearchpath[i]); if (lib_filelist != NULL) break; } } /* try to load one of each type of plugin */ for (i = 0; i < 4; i++) { m64p_plugin_type type = g_PluginMap[i].type; const char *cmdline_path = NULL; const char *config_var = NULL; int use_dummy = 0; switch (type) { case M64PLUGIN_RSP: cmdline_path = g_RspPlugin; config_var = "RspPlugin"; break; case M64PLUGIN_GFX: cmdline_path = g_GfxPlugin; config_var = "VideoPlugin"; break; case M64PLUGIN_AUDIO: cmdline_path = g_AudioPlugin; config_var = "AudioPlugin"; break; case M64PLUGIN_INPUT: cmdline_path = g_InputPlugin; config_var = "InputPlugin"; break; default: cmdline_path = NULL; config_var = ""; } /* first search for a plugin matching what was given on the command line */ if (cmdline_path != NULL) { /* if full path was given, try loading exactly this file */ if (strchr(cmdline_path, OSAL_DIR_SEPARATOR) != NULL) { PluginLoadTry(cmdline_path, i); } else if (strcmp(cmdline_path, "dummy") == 0) { use_dummy = 1; } else /* otherwise search through the plugin directory to find a match with this name */ { osal_lib_search *curr = lib_filelist; while (curr != NULL && g_PluginMap[i].handle == NULL) { if (strncmp(curr->filename, cmdline_path, strlen(cmdline_path)) == 0) PluginLoadTry(curr->filepath, i); curr = curr->next; } } /* exit with error if we couldn't find the specified plugin */ if (!use_dummy && g_PluginMap[i].handle == NULL) { fprintf(stderr, "Error: Specified %s plugin not found: %s\n", g_PluginMap[i].name, cmdline_path); osal_free_lib_list(lib_filelist); return M64ERR_INPUT_NOT_FOUND; } } else /* otherwise search for a plugin specified in the config file */ { const char *config_path = (*ConfigGetParamString)(ConfigUI, config_var); if (config_path != NULL && strlen(config_path) > 0) { /* if full path was given, try loading exactly this file */ if (strchr(config_path, OSAL_DIR_SEPARATOR) != NULL) { PluginLoadTry(config_path, i); } else if (strcmp(config_path, "dummy") == 0) { use_dummy = 1; } else /* otherwise search through the plugin directory to find a match with this name */ { osal_lib_search *curr = lib_filelist; while (curr != NULL && g_PluginMap[i].handle == NULL) { if (strncmp(curr->filename, config_path, strlen(config_path)) == 0) PluginLoadTry(curr->filepath, i); curr = curr->next; } } } } /* As a last resort, search for any appropriate plugin in search directory */ if (!use_dummy && g_PluginMap[i].handle == NULL) { osal_lib_search *curr = lib_filelist; while (curr != NULL && g_PluginMap[i].handle == NULL) { PluginLoadTry(curr->filepath, i); curr = curr->next; } } /* print out the particular plugin used */ if (g_PluginMap[i].handle == NULL) { printf("UI-console: using %s plugin: <dummy>\n", g_PluginMap[i].name); } else { printf("UI-console: using %s plugin: '%s' v%i.%i.%i\n", g_PluginMap[i].name, g_PluginMap[i].libname, VERSION_PRINTF_SPLIT(g_PluginMap[i].libversion)); if (g_Verbose) printf("UI-console: %s plugin library: %s\n", g_PluginMap[i].name, g_PluginMap[i].filename); } } /* free up the list of library files in the plugin search directory */ osal_free_lib_list(lib_filelist); return M64ERR_SUCCESS; }