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