1 /* search.c
2
3 Free software by Richard W.E. Furse. Do with as you will. No
4 warranty. */
5
6 /*****************************************************************************/
7
8 #include <dirent.h>
9 #include <dlfcn.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15
16 /*****************************************************************************/
17
18 #include "ladspa.h"
19 #include "utils.h"
20
21 /*****************************************************************************/
22
23 /* Search just the one directory. */
24 static void
LADSPADirectoryPluginSearch(const char * pcDirectory,LADSPAPluginSearchCallbackFunction fCallbackFunction)25 LADSPADirectoryPluginSearch
26 (const char * pcDirectory,
27 LADSPAPluginSearchCallbackFunction fCallbackFunction) {
28
29 char * pcFilename;
30 DIR * psDirectory;
31 LADSPA_Descriptor_Function fDescriptorFunction;
32 long lDirLength;
33 long iNeedSlash;
34 struct dirent * psDirectoryEntry;
35 void * pvPluginHandle;
36
37 lDirLength = strlen(pcDirectory);
38 if (!lDirLength)
39 return;
40 if (pcDirectory[lDirLength - 1] == '/')
41 iNeedSlash = 0;
42 else
43 iNeedSlash = 1;
44
45 psDirectory = opendir(pcDirectory);
46 if (!psDirectory)
47 return;
48
49 while (1) {
50
51 psDirectoryEntry = readdir(psDirectory);
52 if (!psDirectoryEntry) {
53 closedir(psDirectory);
54 return;
55 }
56
57 pcFilename = malloc(lDirLength
58 + strlen(psDirectoryEntry->d_name)
59 + 1 + iNeedSlash);
60 strcpy(pcFilename, pcDirectory);
61 if (iNeedSlash)
62 strcat(pcFilename, "/");
63 strcat(pcFilename, psDirectoryEntry->d_name);
64
65 pvPluginHandle = dlopen(pcFilename, RTLD_LAZY);
66 if (pvPluginHandle) {
67 /* This is a file and the file is a shared library! */
68
69 dlerror();
70 fDescriptorFunction
71 = (LADSPA_Descriptor_Function)dlsym(pvPluginHandle,
72 "ladspa_descriptor");
73 if (dlerror() == NULL && fDescriptorFunction) {
74 /* We've successfully found a ladspa_descriptor function. Pass
75 it to the callback function. */
76 fCallbackFunction(pcFilename,
77 pvPluginHandle,
78 fDescriptorFunction);
79 free(pcFilename);
80 }
81 else {
82 /* It was a library, but not a LADSPA one. Unload it. */
83 dlclose(pvPluginHandle);
84 free(pcFilename);
85 }
86 }
87 }
88 }
89
90 /*****************************************************************************/
91
92 void
LADSPAPluginSearch(LADSPAPluginSearchCallbackFunction fCallbackFunction)93 LADSPAPluginSearch(LADSPAPluginSearchCallbackFunction fCallbackFunction) {
94
95 char * pcBuffer;
96 const char * pcEnd;
97 const char * pcLADSPAPath;
98 const char * pcStart;
99
100 pcLADSPAPath = getenv("LADSPA_PATH");
101 if (!pcLADSPAPath) {
102 fprintf(stderr,
103 "Warning: You do not have a LADSPA_PATH "
104 "environment variable set. Defaulting to "
105 EXPAND_AND_STRINGIFY(DEFAULT_LADSPA_PATH)
106 ".\n");
107 pcLADSPAPath = EXPAND_AND_STRINGIFY(DEFAULT_LADSPA_PATH);
108 }
109
110 pcStart = pcLADSPAPath;
111 while (*pcStart != '\0') {
112 pcEnd = pcStart;
113 while (*pcEnd != ':' && *pcEnd != '\0')
114 pcEnd++;
115
116 pcBuffer = malloc(1 + pcEnd - pcStart);
117 if (pcEnd > pcStart)
118 strncpy(pcBuffer, pcStart, pcEnd - pcStart);
119 pcBuffer[pcEnd - pcStart] = '\0';
120
121 LADSPADirectoryPluginSearch(pcBuffer, fCallbackFunction);
122 free(pcBuffer);
123
124 pcStart = pcEnd;
125 if (*pcStart == ':')
126 pcStart++;
127 }
128 }
129
130 /*****************************************************************************/
131
132 /* EOF */
133