@@ -1,186 +0,0 @@ | |||
/* load.c | |||
Free software by Richard W.E. Furse. Do with as you will. No | |||
warranty. */ | |||
/*****************************************************************************/ | |||
#include <dlfcn.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
/*****************************************************************************/ | |||
#include "ladspa.h" | |||
#include "utils.h" | |||
/*****************************************************************************/ | |||
/* This function provides a wrapping of dlopen(). When the filename is | |||
not an absolute path (i.e. does not begin with / character), this | |||
routine will search the LADSPA_PATH for the file. */ | |||
static void * | |||
dlopenLADSPA(const char * pcFilename, int iFlag) { | |||
char * pcBuffer; | |||
const char * pcEnd; | |||
const char * pcLADSPAPath; | |||
const char * pcStart; | |||
int iEndsInSO; | |||
int iNeedSlash; | |||
size_t iFilenameLength; | |||
void * pvResult; | |||
iFilenameLength = strlen(pcFilename); | |||
pvResult = NULL; | |||
if (pcFilename[0] == '/') { | |||
/* The filename is absolute. Assume the user knows what he/she is | |||
doing and simply dlopen() it. */ | |||
pvResult = dlopen(pcFilename, iFlag); | |||
if (pvResult != NULL) | |||
return pvResult; | |||
} | |||
else { | |||
/* If the filename is not absolute then we wish to check along the | |||
LADSPA_PATH path to see if we can find the file there. We do | |||
NOT call dlopen() directly as this would find plugins on the | |||
LD_LIBRARY_PATH, whereas the LADSPA_PATH is the correct place | |||
to search. */ | |||
pcLADSPAPath = getenv("LADSPA_PATH"); | |||
if (pcLADSPAPath) { | |||
pcStart = pcLADSPAPath; | |||
while (*pcStart != '\0') { | |||
pcEnd = pcStart; | |||
while (*pcEnd != ':' && *pcEnd != '\0') | |||
pcEnd++; | |||
pcBuffer = malloc(iFilenameLength + 2 + (pcEnd - pcStart)); | |||
if (pcEnd > pcStart) | |||
strncpy(pcBuffer, pcStart, pcEnd - pcStart); | |||
iNeedSlash = 0; | |||
if (pcEnd > pcStart) | |||
if (*(pcEnd - 1) != '/') { | |||
iNeedSlash = 1; | |||
pcBuffer[pcEnd - pcStart] = '/'; | |||
} | |||
strcpy(pcBuffer + iNeedSlash + (pcEnd - pcStart), pcFilename); | |||
pvResult = dlopen(pcBuffer, iFlag); | |||
free (pcBuffer); | |||
if (pvResult != NULL) | |||
return pvResult; | |||
pcStart = pcEnd; | |||
if (*pcStart == ':') | |||
pcStart++; | |||
} | |||
} | |||
} | |||
/* As a last ditch effort, check if filename does not end with | |||
".so". In this case, add this suffix and recurse. */ | |||
iEndsInSO = 0; | |||
if (iFilenameLength > 3) | |||
iEndsInSO = (strcmp(pcFilename + iFilenameLength - 3, ".so") == 0); | |||
if (!iEndsInSO) { | |||
pcBuffer = malloc(iFilenameLength + 4); | |||
strcpy(pcBuffer, pcFilename); | |||
strcat(pcBuffer, ".so"); | |||
pvResult = dlopenLADSPA(pcBuffer, iFlag); | |||
free(pcBuffer); | |||
} | |||
if (pvResult != NULL) | |||
return pvResult; | |||
/* If nothing has worked, then at least we can make sure we set the | |||
correct error message - and this should correspond to a call to | |||
dlopen() with the actual filename requested. The dlopen() manual | |||
page does not specify whether the first or last error message | |||
will be kept when multiple calls are made to dlopen(). We've | |||
covered the former case - now we can handle the latter by calling | |||
dlopen() again here. */ | |||
return dlopen(pcFilename, iFlag); | |||
} | |||
/*****************************************************************************/ | |||
void * | |||
loadLADSPAPluginLibrary(const char * pcPluginFilename) { | |||
void * pvPluginHandle; | |||
pvPluginHandle = dlopenLADSPA(pcPluginFilename, RTLD_NOW); | |||
if (!pvPluginHandle) { | |||
fprintf(stderr, | |||
"Failed to load plugin \"%s\": %s\n", | |||
pcPluginFilename, | |||
dlerror()); | |||
return NULL; | |||
} | |||
return pvPluginHandle; | |||
} | |||
/*****************************************************************************/ | |||
void | |||
unloadLADSPAPluginLibrary(void * pvLADSPAPluginLibrary) { | |||
dlclose(pvLADSPAPluginLibrary); | |||
} | |||
/*****************************************************************************/ | |||
const LADSPA_Descriptor * | |||
findLADSPAPluginDescriptor(void * pvLADSPAPluginLibrary, | |||
const char * pcPluginLibraryFilename, | |||
const char * pcPluginLabel) { | |||
const LADSPA_Descriptor * psDescriptor; | |||
LADSPA_Descriptor_Function pfDescriptorFunction; | |||
unsigned long lPluginIndex; | |||
dlerror(); | |||
pfDescriptorFunction | |||
= (LADSPA_Descriptor_Function)dlsym(pvLADSPAPluginLibrary, | |||
"ladspa_descriptor"); | |||
if (!pfDescriptorFunction) { | |||
const char * pcError = dlerror(); | |||
if (pcError) { | |||
fprintf(stderr, | |||
"Unable to find ladspa_descriptor() function in plugin " | |||
"library file \"%s\": %s.\n" | |||
"Are you sure this is a LADSPA plugin file?\n", | |||
pcPluginLibraryFilename, | |||
pcError); | |||
return NULL; | |||
} | |||
} | |||
for (lPluginIndex = 0;; lPluginIndex++) { | |||
psDescriptor = pfDescriptorFunction(lPluginIndex); | |||
if (psDescriptor == NULL) { | |||
fprintf(stderr, | |||
"Unable to find label \"%s\" in plugin library file \"%s\".\n", | |||
pcPluginLabel, | |||
pcPluginLibraryFilename); | |||
return NULL; | |||
} | |||
if (strcmp(psDescriptor->Label, pcPluginLabel) == 0) | |||
return psDescriptor; | |||
} | |||
} | |||
/*****************************************************************************/ | |||
/* EOF */ |
@@ -1,32 +0,0 @@ | |||
/* misc.c | |||
Free software by Richard W.E. Furse. Do with as you will. No | |||
warranty. */ | |||
/*****************************************************************************/ | |||
#include <dlfcn.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
/*****************************************************************************/ | |||
#include "ladspa.h" | |||
#include "utils.h" | |||
/*****************************************************************************/ | |||
unsigned long | |||
getPortCountByType(const LADSPA_Descriptor * psDescriptor, | |||
const LADSPA_PortDescriptor iType) { | |||
unsigned long lCount; | |||
unsigned long lIndex; | |||
lCount = 0; | |||
for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++) | |||
if ((psDescriptor->PortDescriptors[lIndex] & iType) == iType) | |||
lCount++; | |||
return lCount; | |||
} |
@@ -1,127 +0,0 @@ | |||
/* search.c | |||
Free software by Richard W.E. Furse. Do with as you will. No | |||
warranty. */ | |||
/*****************************************************************************/ | |||
#include <dirent.h> | |||
#include <dlfcn.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <sys/types.h> | |||
#include <unistd.h> | |||
/*****************************************************************************/ | |||
#include "ladspa.h" | |||
#include "utils.h" | |||
/*****************************************************************************/ | |||
/* Search just the one directory. */ | |||
static void | |||
LADSPADirectoryPluginSearch | |||
(const char * pcDirectory, | |||
LADSPAPluginSearchCallbackFunction fCallbackFunction) { | |||
char * pcFilename; | |||
DIR * psDirectory; | |||
LADSPA_Descriptor_Function fDescriptorFunction; | |||
long lDirLength; | |||
long iNeedSlash; | |||
struct dirent * psDirectoryEntry; | |||
void * pvPluginHandle; | |||
lDirLength = strlen(pcDirectory); | |||
if (!lDirLength) | |||
return; | |||
if (pcDirectory[lDirLength - 1] == '/') | |||
iNeedSlash = 0; | |||
else | |||
iNeedSlash = 1; | |||
psDirectory = opendir(pcDirectory); | |||
if (!psDirectory) | |||
return; | |||
while (1) { | |||
psDirectoryEntry = readdir(psDirectory); | |||
if (!psDirectoryEntry) { | |||
closedir(psDirectory); | |||
return; | |||
} | |||
pcFilename = malloc(lDirLength | |||
+ strlen(psDirectoryEntry->d_name) | |||
+ 1 + iNeedSlash); | |||
strcpy(pcFilename, pcDirectory); | |||
if (iNeedSlash) | |||
strcat(pcFilename, "/"); | |||
strcat(pcFilename, psDirectoryEntry->d_name); | |||
pvPluginHandle = dlopen(pcFilename, RTLD_LAZY); | |||
if (pvPluginHandle) { | |||
/* This is a file and the file is a shared library! */ | |||
dlerror(); | |||
fDescriptorFunction | |||
= (LADSPA_Descriptor_Function)dlsym(pvPluginHandle, | |||
"ladspa_descriptor"); | |||
if (dlerror() == NULL && fDescriptorFunction) { | |||
/* We've successfully found a ladspa_descriptor function. Pass | |||
it to the callback function. */ | |||
fCallbackFunction(pcFilename, | |||
pvPluginHandle, | |||
fDescriptorFunction); | |||
} | |||
else { | |||
/* It was a library, but not a LADSPA one. Unload it. */ | |||
dlclose(pcFilename); | |||
} | |||
} | |||
} | |||
} | |||
/*****************************************************************************/ | |||
void | |||
LADSPAPluginSearch(LADSPAPluginSearchCallbackFunction fCallbackFunction) { | |||
char * pcBuffer; | |||
const char * pcEnd; | |||
const char * pcLADSPAPath; | |||
const char * pcStart; | |||
pcLADSPAPath = getenv("LADSPA_PATH"); | |||
if (!pcLADSPAPath) { | |||
fprintf(stderr, | |||
"Warning: You do not have a LADSPA_PATH " | |||
"environment variable set.\n"); | |||
return; | |||
} | |||
pcStart = pcLADSPAPath; | |||
while (*pcStart != '\0') { | |||
pcEnd = pcStart; | |||
while (*pcEnd != ':' && *pcEnd != '\0') | |||
pcEnd++; | |||
pcBuffer = malloc(1 + pcEnd - pcStart); | |||
if (pcEnd > pcStart) | |||
strncpy(pcBuffer, pcStart, pcEnd - pcStart); | |||
pcBuffer[pcEnd - pcStart] = '\0'; | |||
LADSPADirectoryPluginSearch(pcBuffer, fCallbackFunction); | |||
pcStart = pcEnd; | |||
if (*pcStart == ':') | |||
pcStart++; | |||
} | |||
} | |||
/*****************************************************************************/ | |||
/* EOF */ |
@@ -1,80 +0,0 @@ | |||
/* utils.h | |||
Free software by Richard W.E. Furse. Do with as you will. No | |||
warranty. */ | |||
#ifndef LADSPA_SDK_LOAD_PLUGIN_LIB | |||
#define LADSPA_SDK_LOAD_PLUGIN_LIB | |||
/*****************************************************************************/ | |||
#include "ladspa.h" | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/*****************************************************************************/ | |||
/* Functions in load.c: */ | |||
/* This function call takes a plugin library filename, searches for | |||
the library along the LADSPA_PATH, loads it with dlopen() and | |||
returns a plugin handle for use with findPluginDescriptor() or | |||
unloadLADSPAPluginLibrary(). Errors are handled by writing a | |||
message to stderr and calling exit(1). It is alright (although | |||
inefficient) to call this more than once for the same file. */ | |||
void * loadLADSPAPluginLibrary(const char * pcPluginFilename); | |||
/* This function unloads a LADSPA plugin library. */ | |||
void unloadLADSPAPluginLibrary(void * pvLADSPAPluginLibrary); | |||
/* This function locates a LADSPA plugin within a plugin library | |||
loaded with loadLADSPAPluginLibrary(). Errors are handled by | |||
writing a message to stderr and calling exit(1). Note that the | |||
plugin library filename is only included to help provide | |||
informative error messages. */ | |||
const LADSPA_Descriptor * | |||
findLADSPAPluginDescriptor(void * pvLADSPAPluginLibrary, | |||
const char * pcPluginLibraryFilename, | |||
const char * pcPluginLabel); | |||
/*****************************************************************************/ | |||
/* Functions in search.c: */ | |||
/* Callback function for use with LADSPAPluginSearch(). The callback | |||
function passes the filename (full path), a plugin handle (dlopen() | |||
style) and a LADSPA_DescriptorFunction (from which | |||
LADSPA_Descriptors can be acquired). */ | |||
typedef void LADSPAPluginSearchCallbackFunction | |||
(const char * pcFullFilename, | |||
void * pvPluginHandle, | |||
LADSPA_Descriptor_Function fDescriptorFunction); | |||
/* Search through the $(LADSPA_PATH) (or a default path) for any | |||
LADSPA plugin libraries. Each plugin library is tested using | |||
dlopen() and dlsym(,"ladspa_descriptor"). After loading each | |||
library, the callback function is called to process it. This | |||
function leaves items passed to the callback function open. */ | |||
void LADSPAPluginSearch(LADSPAPluginSearchCallbackFunction fCallbackFunction); | |||
/*****************************************************************************/ | |||
/* Functions in misc.c: */ | |||
/* Count the ports of a plugin matching a given type */ | |||
unsigned long | |||
getPortCountByType(const LADSPA_Descriptor * psDescriptor, | |||
const LADSPA_PortDescriptor iType); | |||
/*****************************************************************************/ | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif | |||
/* EOF */ |