@@ -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 */ |