#include "pbd/error.h"
+#include "ardour/filesystem_paths.h"
#include "ardour/linux_vst_support.h"
#include "ardour/vst_info_file.h"
}
static string
-vstfx_infofile_path (const char* dllpath, int personal)
+vstfx_blacklist_path (const char* dllpath, int personal)
{
string dir;
if (personal) {
- // TODO use XDG_CACHE_HOME
- dir = Glib::build_filename (Glib::get_home_dir (), ".fst");
+ dir = get_personal_vst_blacklist_dir();
+ } else {
+ dir = Glib::path_get_dirname (std::string(dllpath));
+ }
+
+ stringstream s;
+ s << "." << Glib::path_get_basename (dllpath) << ".fsb";
+ return Glib::build_filename (dir, s.str ());
+}
+
+/* return true if plugin is blacklisted or has an invalid file extension */
+static bool
+vstfx_blacklist_stat (const char *dllpath, int personal)
+{
+ if (strstr (dllpath, ".so" ) == 0 && strstr(dllpath, ".dll") == 0) {
+ return true;
+ }
+ string const path = vstfx_blacklist_path (dllpath, personal);
+
+ if (Glib::file_test (path, Glib::FileTest (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR))) {
+ struct stat dllstat;
+ struct stat fsbstat;
- /* If the directory doesn't exist, try to create it */
- if (!Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
- if (g_mkdir (dir.c_str (), 0700)) {
- return 0;
+ if (stat (dllpath, &dllstat) == 0 && stat (path.c_str(), &fsbstat) == 0) {
+ if (dllstat.st_mtime > fsbstat.st_mtime) {
+ /* plugin is newer than blacklist file */
+ return true;
}
}
+ /* stat failed or plugin is older than blacklist file */
+ return true;
+ }
+ /* blacklist file does not exist */
+ return false;
+}
+
+static bool
+vstfx_check_blacklist (const char *dllpath)
+{
+ if (vstfx_blacklist_stat(dllpath, 0)) return true;
+ if (vstfx_blacklist_stat(dllpath, 1)) return true;
+ return false;
+}
+
+static FILE *
+vstfx_blacklist_file (const char *dllpath)
+{
+ FILE *f;
+ if ((f = fopen (vstfx_blacklist_path (dllpath, 0).c_str(), "w"))) {
+ return f;
+ }
+ return fopen (vstfx_blacklist_path (dllpath, 1).c_str(), "w");
+}
+
+static bool
+vstfx_blacklist (const char *dllpath)
+{
+ FILE *f = vstfx_blacklist_file(dllpath);
+ if (f) {
+ fclose(f);
+ return true;
+ }
+ return false;
+}
+static bool
+vstfx_un_blacklist (const char *dllpath)
+{
+ ::g_unlink(vstfx_blacklist_path (dllpath, 0).c_str());
+ ::g_unlink(vstfx_blacklist_path (dllpath, 1).c_str());
+}
+
+static string
+vstfx_infofile_path (const char* dllpath, int personal)
+{
+ string dir;
+ if (personal) {
+ dir = get_personal_vst_info_cache_dir();
} else {
dir = Glib::path_get_dirname (std::string(dllpath));
}
if (Glib::file_test (path, Glib::FileTest (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR))) {
- /* info file exists in same location as the shared object, so
- check if its current and up to date
- */
-
-
struct stat dllstat;
if (stat (dllpath, &dllstat) == 0) {
VSTHandle* h;
VSTState* vstfx;
if(!(h = fst_load(dllpath))) {
- PBD::warning << "Cannot get VST information from " << dllpath << ": load failed." << endmsg;
+ PBD::warning << "Cannot get Windows VST information from " << dllpath << ": load failed." << endmsg;
return false;
}
if(!(vstfx = fst_instantiate(h, simple_master_callback, 0))) {
fst_unload(&h);
vstfx_current_loading_id = 0;
- PBD::warning << "Cannot get VST information from " << dllpath << ": instantiation failed." << endmsg;
+ PBD::warning << "Cannot get Windows VST information from " << dllpath << ": instantiation failed." << endmsg;
return false;
}
vstfx_current_loading_id = 0;
FILE* infofile;
vector<VSTInfo*> *infos = new vector<VSTInfo*>;
- // TODO check blacklist
- // TODO pre-check file extension ?
+ if (vstfx_check_blacklist(dllpath)) {
+ return infos;
+ }
if (vstfx_get_info_from_file(dllpath, infos)) {
- PBD::info << "using cache for VST plugin '" << dllpath << "'" << endmsg;
return infos;
}
bool ok;
- // TODO blacklist (in case instantiat fails)
+ /* blacklist in case instantiation fails */
+ vstfx_blacklist_file(dllpath);
+
switch (type) { // TODO use lib ardour's type
#ifdef WINDOWS_VST_SUPPORT
case 1: ok = vstfx_instantiate_and_get_info_fst(dllpath, infos, 0); break;
}
if (!ok) {
- PBD::warning << "Cannot get VST information for " << dllpath << "." << endmsg;
return infos;
}
- // TODO un-blacklist
+ /* remove from blacklist */
+ vstfx_un_blacklist(dllpath);
+ /* crate cache/whitelist */
infofile = vstfx_infofile_for_write (dllpath);
if (!infofile) {
PBD::warning << "Cannot cache VST information for " << dllpath << ": cannot create new FST info file." << endmsg;
delete infos;
}
+string
+get_personal_vst_blacklist_dir() {
+ string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_blacklist");
+ /* if the directory doesn't exist, try to create it */
+ if (!Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
+ if (g_mkdir (dir.c_str (), 0700)) {
+ PBD::error << "Cannt create VST cache folder '" << dir << "'" << endmsg;
+ //exit(1);
+ }
+ }
+ return dir;
+}
+
+string
+get_personal_vst_info_cache_dir() {
+ string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_info");
+ /* if the directory doesn't exist, try to create it */
+ if (!Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
+ if (g_mkdir (dir.c_str (), 0700)) {
+ PBD::error << "Cannt create VST info folder '" << dir << "'" << endmsg;
+ //exit(1);
+ }
+ }
+ return dir;
+}
+
#ifdef LXVST_SUPPORT
vector<VSTInfo *> *
vstfx_get_info_lx (char* dllpath)