aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/extractor_plugins.c350
-rw-r--r--src/main/extractor_plugins.h118
-rw-r--r--src/main/extractor_plugpath.c520
-rw-r--r--src/main/extractor_plugpath.h47
4 files changed, 1035 insertions, 0 deletions
diff --git a/src/main/extractor_plugins.c b/src/main/extractor_plugins.c
new file mode 100644
index 0000000..026e86b
--- /dev/null
+++ b/src/main/extractor_plugins.c
@@ -0,0 +1,350 @@
1/*
2 This file is part of libextractor.
3 (C) 2002, 2003, 2004, 2005, 2006, 2009 Vidyut Samanta and Christian Grothoff
4
5 libextractor is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libextractor is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libextractor; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21#include "extractor_plugins.h"
22#include "extractor_plugpath.h"
23
24
25/**
26 * Load the default set of plugins. The default can be changed
27 * by setting the LIBEXTRACTOR_LIBRARIES environment variable.
28 * If it is set to "env", then this function will return
29 * EXTRACTOR_plugin_add_config (NULL, env, flags). Otherwise,
30 * it will load all of the installed plugins and return them.
31 *
32 * @param flags options for all of the plugins loaded
33 * @return the default set of plugins, NULL if no plugins were found
34 */
35struct EXTRACTOR_PluginList *
36EXTRACTOR_plugin_add_defaults(enum EXTRACTOR_Options flags)
37{
38 struct DefaultLoaderContext dlc;
39 char *env;
40
41 env = getenv ("LIBEXTRACTOR_LIBRARIES");
42 if (env != NULL)
43 return EXTRACTOR_plugin_add_config (NULL, env, flags);
44 dlc.res = NULL;
45 dlc.flags = flags;
46 get_installation_paths (&load_plugins_from_dir,
47 &dlc);
48 return dlc.res;
49}
50
51/**
52 * Try to resolve a plugin function.
53 *
54 * @param lib_handle library to search for the symbol
55 * @param prefix prefix to add
56 * @param sym_name base name for the symbol
57 * @param options set to special options requested by the plugin
58 * @return NULL on error, otherwise pointer to the symbol
59 */
60static void *
61get_symbol_with_prefix(void *lib_handle,
62 const char *template,
63 const char *prefix,
64 const char **options)
65{
66 char *name;
67 void *symbol;
68 const char *sym_name;
69 char *sym;
70 char *dot;
71 const char *(*opt_fun)(void);
72
73 if (NULL != options) *options = NULL;
74 sym_name = strstr (prefix, "_");
75 if (sym_name == NULL)
76 return NULL;
77 sym_name++;
78 sym = strdup (sym_name);
79 if (sym == NULL)
80 return NULL;
81 dot = strstr (sym, ".");
82 if (dot != NULL)
83 *dot = '\0';
84 name = malloc(strlen(sym) + strlen(template) + 1);
85 if (name == NULL)
86 {
87 free (sym);
88 return NULL;
89 }
90 sprintf(name,
91 template,
92 sym);
93 /* try without '_' first */
94 symbol = lt_dlsym(lib_handle, name + 1);
95 if (symbol==NULL)
96 {
97 /* now try with the '_' */
98#if DEBUG
99 char *first_error = strdup (lt_dlerror());
100#endif
101 symbol = lt_dlsym(lib_handle, name);
102#if DEBUG
103 if (NULL == symbol)
104 {
105 fprintf(stderr,
106 "Resolving symbol `%s' failed, "
107 "so I tried `%s', but that failed also. Errors are: "
108 "`%s' and `%s'.\n",
109 name+1,
110 name,
111 first_error == NULL ? "out of memory" : first_error,
112 lt_dlerror());
113 }
114 if (first_error != NULL)
115 free(first_error);
116#endif
117 }
118
119 if ( (symbol != NULL) &&
120 (NULL != options) )
121 {
122 /* get special options */
123 sprintf(name,
124 "_EXTRACTOR_%s_options",
125 sym);
126 /* try without '_' first */
127 opt_fun = lt_dlsym(lib_handle, name + 1);
128 if (opt_fun == NULL)
129 opt_fun = lt_dlsym(lib_handle, name);
130 if (opt_fun != NULL)
131 *options = opt_fun ();
132 }
133 free (sym);
134 free(name);
135
136 return symbol;
137}
138
139
140/**
141 * Load a plugin.
142 *
143 * @param plugin plugin to load
144 * @return 0 on success, -1 on error
145 */
146int
147plugin_load (struct EXTRACTOR_PluginList *plugin)
148{
149#if WINDOWS
150 wchar_t wlibname[4097];
151 char llibname[4097];
152#endif
153 lt_dladvise advise;
154
155 if (plugin->libname == NULL)
156 plugin->libname = find_plugin (plugin->short_libname);
157 if (plugin->libname == NULL)
158 {
159#if DEBUG
160 fprintf (stderr,
161 "Failed to find plugin `%s'\n",
162 plugin->short_libname);
163#endif
164 plugin->flags = EXTRACTOR_OPTION_DISABLED;
165 return -1;
166 }
167 lt_dladvise_init (&advise);
168 lt_dladvise_ext (&advise);
169 lt_dladvise_local (&advise);
170#if WINDOWS
171 wlibname[0] = L'\0';
172 llibname[0] = '\0';
173 if (MultiByteToWideChar (CP_UTF8, 0, plugin->libname, -1, wlibname, 4097) <= 0
174 || WideCharToMultiByte (CP_ACP, 0, wlibname, -1, llibname, 4097, NULL, NULL) < 0)
175 {
176#if DEBUG
177 fprintf (stderr,
178 "Loading `%s' plugin failed: %s\n",
179 plugin->short_libname,
180 "can't convert plugin name to local encoding");
181 free (plugin->libname);
182 plugin->libname = NULL;
183 plugin->flags = EXTRACTOR_OPTION_DISABLED;
184 return -1;
185#endif
186 }
187 plugin->libraryHandle = lt_dlopenadvise (llibname,
188 advise);
189#else
190 plugin->libraryHandle = lt_dlopenadvise (plugin->libname,
191 advise);
192#endif
193 lt_dladvise_destroy(&advise);
194 if (plugin->libraryHandle == NULL)
195 {
196#if DEBUG
197 fprintf (stderr,
198 "Loading `%s' plugin failed: %s\n",
199 plugin->short_libname,
200 lt_dlerror ());
201#endif
202 free (plugin->libname);
203 plugin->libname = NULL;
204 plugin->flags = EXTRACTOR_OPTION_DISABLED;
205 return -1;
206 }
207 plugin->extractMethod = get_symbol_with_prefix (plugin->libraryHandle,
208 "_EXTRACTOR_%s_extract",
209 plugin->libname,
210 &plugin->specials);
211 if (plugin->extractMethod == NULL)
212 {
213#if DEBUG
214 fprintf (stderr,
215 "Resolving `extract' method of plugin `%s' failed: %s\n",
216 plugin->short_libname,
217 lt_dlerror ());
218#endif
219 lt_dlclose (plugin->libraryHandle);
220 free (plugin->libname);
221 plugin->libname = NULL;
222 plugin->flags = EXTRACTOR_OPTION_DISABLED;
223 return -1;
224 }
225 return 0;
226}
227
228
229
230
231/**
232 * Add a library for keyword extraction.
233 *
234 * @param prev the previous list of libraries, may be NULL
235 * @param library the name of the library
236 * @param flags options to use
237 * @return the new list of libraries, equal to prev iff an error occured
238 */
239struct EXTRACTOR_PluginList *
240EXTRACTOR_plugin_add (struct EXTRACTOR_PluginList * prev,
241 const char *library,
242 const char *options,
243 enum EXTRACTOR_Options flags)
244{
245 struct EXTRACTOR_PluginList *result;
246 char *libname;
247
248 libname = find_plugin (library);
249 if (libname == NULL)
250 {
251 fprintf (stderr,
252 "Could not load `%s'\n",
253 library);
254 return prev;
255 }
256 result = calloc (1, sizeof (struct EXTRACTOR_PluginList));
257 if (result == NULL)
258 return prev;
259 result->next = prev;
260 result->short_libname = strdup (library);
261 if (result->short_libname == NULL)
262 {
263 free (result);
264 return NULL;
265 }
266 result->libname = libname;
267 result->flags = flags;
268 if (NULL != options)
269 result->plugin_options = strdup (options);
270 else
271 result->plugin_options = NULL;
272 return result;
273}
274
275
276/**
277 * Load multiple libraries as specified by the user.
278 *
279 * @param config a string given by the user that defines which
280 * libraries should be loaded. Has the format
281 * "[[-]LIBRARYNAME[(options)][:[-]LIBRARYNAME[(options)]]]*".
282 * For example, 'mp3:ogg.so' loads the
283 * mp3 and the ogg library. The '-' before the LIBRARYNAME
284 * indicates that the library should be removed from
285 * the library list.
286 * @param prev the previous list of libraries, may be NULL
287 * @param flags options to use
288 * @return the new list of libraries, equal to prev iff an error occured
289 * or if config was empty (or NULL).
290 */
291struct EXTRACTOR_PluginList *
292EXTRACTOR_plugin_add_config (struct EXTRACTOR_PluginList * prev,
293 const char *config,
294 enum EXTRACTOR_Options flags)
295{
296 char *cpy;
297 size_t pos;
298 size_t last;
299 ssize_t lastconf;
300 size_t len;
301
302 if (config == NULL)
303 return prev;
304 len = strlen(config);
305 cpy = strdup(config);
306 if (cpy == NULL)
307 return prev;
308 pos = 0;
309 last = 0;
310 lastconf = 0;
311 while (pos < len)
312 {
313 while ((cpy[pos] != ':') && (cpy[pos] != '\0') &&
314 (cpy[pos] != '('))
315 pos++;
316 if( cpy[pos] == '(' ) {
317 cpy[pos++] = '\0'; /* replace '(' by termination */
318 lastconf = pos; /* start config from here, after (. */
319 while ((cpy[pos] != '\0') && (cpy[pos] != ')'))
320 pos++; /* config until ) or EOS. */
321 if( cpy[pos] == ')' ) {
322 cpy[pos++] = '\0'; /* write end of config here. */
323 while ((cpy[pos] != ':') && (cpy[pos] != '\0'))
324 pos++; /* forward until real end of string found. */
325 cpy[pos++] = '\0';
326 } else {
327 cpy[pos++] = '\0'; /* end of string. */
328 }
329 } else {
330 lastconf = -1; /* NULL config when no (). */
331 cpy[pos++] = '\0'; /* replace ':' by termination */
332 }
333 if (cpy[last] == '-')
334 {
335 last++;
336 prev = EXTRACTOR_plugin_remove (prev,
337 &cpy[last]);
338 }
339 else
340 {
341 prev = EXTRACTOR_plugin_add (prev,
342 &cpy[last],
343 (lastconf != -1) ? &cpy[lastconf] : NULL,
344 flags);
345 }
346 last = pos;
347 }
348 free (cpy);
349 return prev;
350}
diff --git a/src/main/extractor_plugins.h b/src/main/extractor_plugins.h
new file mode 100644
index 0000000..ea0eabb
--- /dev/null
+++ b/src/main/extractor_plugins.h
@@ -0,0 +1,118 @@
1/*
2 This file is part of libextractor.
3 (C) 2002, 2003, 2004, 2005, 2006, 2009 Vidyut Samanta and Christian Grothoff
4
5 libextractor is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libextractor is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libextractor; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21#if !defined (EXTRACTOR_PLUGINS_H)
22#define EXTRACTOR_PLUGINS_H
23
24#include "platform.h"
25#include "plibc.h"
26#include "extractor.h"
27//#include <dirent.h>
28//#include <sys/types.h>
29#ifndef WINDOWS
30#include <sys/wait.h>
31#include <sys/shm.h>
32#endif
33#include <signal.h>
34#include <ltdl.h>
35
36/**
37 * Linked list of extractor plugins. An application builds this list
38 * by telling libextractor to load various keyword-extraction
39 * plugins. Libraries can also be unloaded (removed from this list,
40 * see EXTRACTOR_plugin_remove).
41 */
42struct EXTRACTOR_PluginList
43{
44 /**
45 * This is a linked list.
46 */
47 struct EXTRACTOR_PluginList *next;
48
49 /**
50 * Pointer to the plugin (as returned by lt_dlopen).
51 */
52 void * libraryHandle;
53
54 /**
55 * Name of the library (i.e., 'libextractor_foo.so')
56 */
57 char *libname;
58
59 /**
60 * Name of the library (i.e., 'libextractor_foo.so')
61 */
62 char *short_libname;
63
64 /**
65 * Pointer to the function used for meta data extraction.
66 */
67 EXTRACTOR_ExtractMethod extractMethod;
68
69 /**
70 * Options for the plugin.
71 */
72 char * plugin_options;
73
74 /**
75 * Special options for the plugin
76 * (as returned by the plugin's "options" method;
77 * typically NULL).
78 */
79 const char *specials;
80
81 /**
82 * Flags to control how the plugin is executed.
83 */
84 enum EXTRACTOR_Options flags;
85
86 /**
87 * Process ID of the child process for this plugin. 0 for
88 * none.
89 */
90#ifndef WINDOWS
91 int cpid;
92#else
93 HANDLE hProcess;
94#endif
95
96 /**
97 * Pipe used to send information about shared memory segments to
98 * the child process. NULL if not initialized.
99 */
100 FILE *cpipe_in;
101
102 /**
103 * Pipe used to read information about extracted meta data from
104 * the child process. -1 if not initialized.
105 */
106 int cpipe_out;
107};
108
109/**
110 * Load a plugin.
111 *
112 * @param plugin plugin to load
113 * @return 0 on success, -1 on error
114 */
115int
116plugin_load (struct EXTRACTOR_PluginList *plugin);
117
118#endif /* EXTRACTOR_PLUGINS_H */
diff --git a/src/main/extractor_plugpath.c b/src/main/extractor_plugpath.c
new file mode 100644
index 0000000..1cc5858
--- /dev/null
+++ b/src/main/extractor_plugpath.c
@@ -0,0 +1,520 @@
1/*
2 This file is part of libextractor.
3 (C) 2002, 2003, 2004, 2005, 2006, 2009 Vidyut Samanta and Christian Grothoff
4
5 libextractor is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libextractor is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libextractor; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21#include "platform.h"
22#include "plibc.h"
23#include "extractor.h"
24#include <dirent.h>
25#include <sys/types.h>
26#ifndef WINDOWS
27#include <sys/wait.h>
28#include <sys/shm.h>
29#endif
30#include <signal.h>
31#include <ltdl.h>
32
33#include "extractor_plugpath.h"
34
35/**
36 * Remove a trailing '/bin' from in (if present).
37 */
38static char *
39cut_bin(char * in) {
40 size_t p;
41
42 if (in == NULL)
43 return NULL;
44 p = strlen(in);
45 if (p > 4) {
46 if ( (in[p-1] == '/') ||
47 (in[p-1] == '\\') )
48 in[--p] = '\0';
49 if (0 == strcmp(&in[p-3],
50 "bin")) {
51 in[p-3] = '\0';
52 p -= 3;
53 }
54 }
55 return in;
56}
57
58#if LINUX
59/**
60 * Try to determine path by reading /proc/PID/exe or
61 * /proc/PID/maps.
62 *
63 * Note that this may fail if LE is installed in one directory
64 * and the binary linking against it sits elsewhere.
65 */
66static char *
67get_path_from_proc_exe() {
68 char fn[64];
69 char line[1024];
70 char dir[1024];
71 char * lnk;
72 char * ret;
73 char * lestr;
74 ssize_t size;
75 FILE * f;
76
77 snprintf(fn,
78 sizeof (fn),
79 "/proc/%u/maps",
80 getpid());
81 f = FOPEN(fn, "r");
82 if (f != NULL) {
83 while (NULL != fgets(line, 1024, f)) {
84 if ( (1 == sscanf(line,
85 "%*x-%*x %*c%*c%*c%*c %*x %*2x:%*2x %*u%*[ ]%s",
86 dir)) &&
87 (NULL != (lestr = strstr(dir,
88 "libextractor")) ) ) {
89 lestr[0] = '\0';
90 fclose(f);
91 return strdup(dir);
92 }
93 }
94 fclose(f);
95 }
96 snprintf(fn,
97 sizeof (fn),
98 "/proc/%u/exe",
99 getpid());
100 lnk = malloc(1029); /* 1024 + 5 for "lib/" catenation */
101 if (lnk == NULL)
102 return NULL;
103 size = readlink(fn, lnk, 1023);
104 if ( (size <= 0) || (size >= 1024) ) {
105 free(lnk);
106 return NULL;
107 }
108 lnk[size] = '\0';
109 while ( (lnk[size] != '/') &&
110 (size > 0) )
111 size--;
112 if ( (size < 4) ||
113 (lnk[size-4] != '/') ) {
114 /* not installed in "/bin/" -- binary path probably useless */
115 free(lnk);
116 return NULL;
117 }
118 lnk[size] = '\0';
119 lnk = cut_bin(lnk);
120 ret = realloc(lnk, strlen(lnk) + 5);
121 if (ret == NULL)
122 {
123 free (lnk);
124 return NULL;
125 }
126 strcat(ret, "lib/"); /* guess "lib/" as the library dir */
127 return ret;
128}
129#endif
130
131#if WINDOWS
132/**
133 * Try to determine path with win32-specific function
134 */
135static char *
136get_path_from_module_filename() {
137 char * path;
138 char * ret;
139 char * idx;
140
141 path = malloc(4103); /* 4096+nil+6 for "/lib/" catenation */
142 if (path == NULL)
143 return NULL;
144 GetModuleFileName(NULL, path, 4096);
145 idx = path + strlen(path);
146 while ( (idx > path) &&
147 (*idx != '\\') &&
148 (*idx != '/') )
149 idx--;
150 *idx = '\0';
151 path = cut_bin(path);
152 ret = realloc(path, strlen(path) + 6);
153 if (ret == NULL)
154 {
155 free (path);
156 return NULL;
157 }
158 strcat(ret, "/lib/"); /* guess "lib/" as the library dir */
159 return ret;
160}
161#endif
162
163#if DARWIN
164static char * get_path_from_dyld_image() {
165 const char * path;
166 char * p, * s;
167 int i;
168 int c;
169
170 p = NULL;
171 c = _dyld_image_count();
172 for (i = 0; i < c; i++) {
173 if (_dyld_get_image_header(i) == &_mh_dylib_header) {
174 path = _dyld_get_image_name(i);
175 if (path != NULL && strlen(path) > 0) {
176 p = strdup(path);
177 if (p == NULL)
178 return NULL;
179 s = p + strlen(p);
180 while ( (s > p) && (*s != '/') )
181 s--;
182 s++;
183 *s = '\0';
184 }
185 break;
186 }
187 }
188 return p;
189}
190#endif
191
192/**
193 * This may also fail -- for example, if extract
194 * is not also installed.
195 */
196static char *
197get_path_from_PATH() {
198 struct stat sbuf;
199 char * path;
200 char * pos;
201 char * end;
202 char * buf;
203 char * ret;
204 const char * p;
205
206 p = getenv("PATH");
207 if (p == NULL)
208 return NULL;
209 path = strdup(p); /* because we write on it */
210 if (path == NULL)
211 return NULL;
212 buf = malloc(strlen(path) + 20);
213 if (buf == NULL)
214 {
215 free (path);
216 return NULL;
217 }
218 pos = path;
219
220 while (NULL != (end = strchr(pos, ':'))) {
221 *end = '\0';
222 sprintf(buf, "%s/%s", pos, "extract");
223 if (0 == stat(buf, &sbuf)) {
224 pos = strdup(pos);
225 free(buf);
226 free(path);
227 if (pos == NULL)
228 return NULL;
229 pos = cut_bin(pos);
230 ret = realloc(pos, strlen(pos) + 5);
231 if (ret == NULL)
232 {
233 free (pos);
234 return NULL;
235 }
236 strcat(ret, "lib/");
237 return ret;
238 }
239 pos = end + 1;
240 }
241 sprintf(buf, "%s/%s", pos, "extract");
242 if (0 == stat(buf, &sbuf)) {
243 pos = strdup(pos);
244 free(buf);
245 free(path);
246 if (pos == NULL)
247 return NULL;
248 pos = cut_bin(pos);
249 ret = realloc(pos, strlen(pos) + 5);
250 if (ret == NULL)
251 {
252 free (pos);
253 return NULL;
254 }
255 strcat(ret, "lib/");
256 return ret;
257 }
258 free(buf);
259 free(path);
260 return NULL;
261}
262
263/**
264 * Create a filename by appending 'fname' to 'path'.
265 *
266 * @param path the base path
267 * @param fname the filename to append
268 * @return '$path/$fname'
269 */
270static char *
271append_to_dir (const char *path,
272 const char *fname)
273{
274 char *ret;
275 size_t slen;
276
277 slen = strlen (path);
278 if (slen == 0)
279 return NULL;
280 if (fname[0] == DIR_SEPARATOR)
281 fname++;
282 ret = malloc (slen + strlen(fname) + 2);
283 if (ret == NULL)
284 return NULL;
285#ifdef MINGW
286 if (path[slen-1] == '\\')
287 sprintf (ret,
288 "%s%s",
289 path,
290 fname);
291 else
292 sprintf (ret,
293 "%s\\%s",
294 path,
295 fname);
296#else
297 if (path[slen-1] == '/')
298 sprintf (ret,
299 "%s%s",
300 path,
301 fname);
302 else
303 sprintf (ret,
304 "%s/%s",
305 path,
306 fname);
307#endif
308 return ret;
309}
310
311
312/**
313 * Iterate over all paths where we expect to find GNU libextractor
314 * plugins.
315 *
316 * @param pp function to call for each path
317 * @param pp_cls cls argument for pp.
318 */
319void
320get_installation_paths (PathProcessor pp,
321 void *pp_cls)
322{
323 const char *p;
324 char * path;
325 char * prefix;
326 char * d;
327
328 prefix = NULL;
329 p = getenv("LIBEXTRACTOR_PREFIX");
330 if (p != NULL)
331 {
332 d = strdup (p);
333 if (d == NULL)
334 return;
335 prefix = strtok (d, PATH_SEPARATOR_STR);
336 while (NULL != prefix)
337 {
338 pp (pp_cls, prefix);
339 prefix = strtok (NULL, PATH_SEPARATOR_STR);
340 }
341 free (d);
342 return;
343 }
344#if LINUX
345 if (prefix == NULL)
346 prefix = get_path_from_proc_exe();
347#endif
348#if WINDOWS
349 if (prefix == NULL)
350 prefix = get_path_from_module_filename();
351#endif
352#if DARWIN
353 if (prefix == NULL)
354 prefix = get_path_from_dyld_image();
355#endif
356 if (prefix == NULL)
357 prefix = get_path_from_PATH();
358 pp (pp_cls, PLUGININSTDIR);
359 if (prefix == NULL)
360 return;
361 path = append_to_dir (prefix, PLUGINDIR);
362 if (path != NULL)
363 {
364 if (0 != strcmp (path,
365 PLUGININSTDIR))
366 pp (pp_cls, path);
367 free (path);
368 }
369 free (prefix);
370}
371
372
373struct SearchContext
374{
375 const char *short_name;
376 char *path;
377};
378
379
380/**
381 * Load all plugins from the given directory.
382 *
383 * @param cls pointer to the "struct EXTRACTOR_PluginList*" to extend
384 * @param path path to a directory with plugins
385 */
386static void
387find_plugin_in_path (void *cls,
388 const char *path)
389{
390 struct SearchContext *sc = cls;
391 DIR *dir;
392 struct dirent *ent;
393 const char *la;
394 const char *sym_name;
395 char *sym;
396 char *dot;
397
398 if (sc->path != NULL)
399 return;
400 dir = OPENDIR (path);
401 if (NULL == dir)
402 return;
403 while (NULL != (ent = READDIR (dir)))
404 {
405 if (ent->d_name[0] == '.')
406 continue;
407 if ( (NULL != (la = strstr (ent->d_name, ".la"))) &&
408 (la[3] == '\0') )
409 continue; /* only load '.so' and '.dll' */
410 sym_name = strstr (ent->d_name, "_");
411 if (sym_name == NULL)
412 continue;
413 sym_name++;
414 sym = strdup (sym_name);
415 if (sym == NULL)
416 {
417 CLOSEDIR (dir);
418 return;
419 }
420 dot = strstr (sym, ".");
421 if (dot != NULL)
422 *dot = '\0';
423 if (0 == strcmp (sym, sc->short_name))
424 {
425 sc->path = append_to_dir (path, ent->d_name);
426 free (sym);
427 break;
428 }
429 free (sym);
430 }
431#if DEBUG
432 if (sc->path == NULL)
433 fprintf (stderr,
434 "Failed to find plugin `%s' in `%s'\n",
435 sc->short_name,
436 path);
437#endif
438 CLOSEDIR (dir);
439}
440
441
442
443/**
444 * Given a short name of a library (i.e. "mime"), find
445 * the full path of the respective plugin.
446 */
447char *
448find_plugin (const char *short_name)
449{
450 struct SearchContext sc;
451
452 sc.path = NULL;
453 sc.short_name = short_name;
454 get_installation_paths (&find_plugin_in_path,
455 &sc);
456 return sc.path;
457}
458
459
460
461
462
463/**
464 * Load all plugins from the given directory.
465 *
466 * @param cls pointer to the "struct EXTRACTOR_PluginList*" to extend
467 * @param path path to a directory with plugins
468 */
469void
470load_plugins_from_dir (void *cls,
471 const char *path)
472{
473 struct DefaultLoaderContext *dlc = cls;
474 DIR *dir;
475 struct dirent *ent;
476 const char *la;
477 const char *sym_name;
478 char *sym;
479 char *dot;
480
481 dir = opendir (path);
482 if (NULL == dir)
483 return;
484 while (NULL != (ent = readdir (dir)))
485 {
486 if (ent->d_name[0] == '.')
487 continue;
488 if ( ( (NULL != (la = strstr (ent->d_name, ".la"))) &&
489 (la[3] == '\0') ) ||
490 ( (NULL != (la = strstr (ent->d_name, ".a"))) &&
491 (la[2] == '\0')) )
492 continue; /* only load '.so' and '.dll' */
493
494 sym_name = strstr (ent->d_name, "_");
495 if (sym_name == NULL)
496 continue;
497 sym_name++;
498 sym = strdup (sym_name);
499 if (NULL == sym)
500 {
501 closedir (dir);
502 return;
503 }
504 dot = strstr (sym, ".");
505 if (dot != NULL)
506 *dot = '\0';
507#if DEBUG > 1
508 fprintf (stderr,
509 "Adding default plugin `%s'\n",
510 sym);
511#endif
512 dlc->res = EXTRACTOR_plugin_add (dlc->res,
513 sym,
514 NULL,
515 dlc->flags);
516 free (sym);
517 }
518 closedir (dir);
519}
520
diff --git a/src/main/extractor_plugpath.h b/src/main/extractor_plugpath.h
new file mode 100644
index 0000000..33bc29f
--- /dev/null
+++ b/src/main/extractor_plugpath.h
@@ -0,0 +1,47 @@
1#if !defined(EXTRACTOR_PLUGPATH_H)
2#define EXTRACTOR_PLUGPATH_H
3
4struct DefaultLoaderContext
5{
6 struct EXTRACTOR_PluginList *res;
7 enum EXTRACTOR_Options flags;
8};
9
10/**
11 * Function to call on paths.
12 *
13 * @param cls closure
14 * @param path a directory path
15 */
16typedef void (*PathProcessor)(void *cls,
17 const char *path);
18
19/**
20 * Iterate over all paths where we expect to find GNU libextractor
21 * plugins.
22 *
23 * @param pp function to call for each path
24 * @param pp_cls cls argument for pp.
25 */
26void
27get_installation_paths (PathProcessor pp,
28 void *pp_cls);
29
30/**
31 * Given a short name of a library (i.e. "mime"), find
32 * the full path of the respective plugin.
33 */
34char *
35find_plugin (const char *short_name);
36
37/**
38 * Load all plugins from the given directory.
39 *
40 * @param cls pointer to the "struct EXTRACTOR_PluginList*" to extend
41 * @param path path to a directory with plugins
42 */
43void
44load_plugins_from_dir (void *cls,
45 const char *path);
46
47#endif /* EXTRACTOR_PLUGPATH_H */