diff options
Diffstat (limited to 'src/main/extractor_plugins.c')
-rw-r--r-- | src/main/extractor_plugins.c | 313 |
1 files changed, 157 insertions, 156 deletions
diff --git a/src/main/extractor_plugins.c b/src/main/extractor_plugins.c index 0fa10d6..1ab777b 100644 --- a/src/main/extractor_plugins.c +++ b/src/main/extractor_plugins.c | |||
@@ -39,9 +39,9 @@ | |||
39 | */ | 39 | */ |
40 | static void * | 40 | static void * |
41 | get_symbol_with_prefix (void *lib_handle, | 41 | get_symbol_with_prefix (void *lib_handle, |
42 | const char *template, | 42 | const char *template, |
43 | const char *prefix, | 43 | const char *prefix, |
44 | const char **options) | 44 | const char **options) |
45 | { | 45 | { |
46 | char *name; | 46 | char *name; |
47 | void *symbol; | 47 | void *symbol; |
@@ -56,55 +56,55 @@ get_symbol_with_prefix (void *lib_handle, | |||
56 | return NULL; | 56 | return NULL; |
57 | sym_name++; | 57 | sym_name++; |
58 | if (NULL == (sym = strdup (sym_name))) | 58 | if (NULL == (sym = strdup (sym_name))) |
59 | { | 59 | { |
60 | LOG_STRERROR ("strdup"); | 60 | LOG_STRERROR ("strdup"); |
61 | return NULL; | 61 | return NULL; |
62 | } | 62 | } |
63 | if (NULL != (dot = strchr (sym, '.'))) | 63 | if (NULL != (dot = strchr (sym, '.'))) |
64 | *dot = '\0'; | 64 | *dot = '\0'; |
65 | if (NULL == (name = malloc(strlen(sym) + strlen(template) + 1))) | 65 | if (NULL == (name = malloc (strlen (sym) + strlen (template) + 1))) |
66 | { | 66 | { |
67 | free (sym); | 67 | free (sym); |
68 | return NULL; | 68 | return NULL; |
69 | } | 69 | } |
70 | sprintf(name, | 70 | sprintf (name, |
71 | template, | 71 | template, |
72 | sym); | 72 | sym); |
73 | /* try without '_' first */ | 73 | /* try without '_' first */ |
74 | symbol = lt_dlsym (lib_handle, name + 1); | 74 | symbol = lt_dlsym (lib_handle, name + 1); |
75 | if (NULL == symbol) | 75 | if (NULL == symbol) |
76 | { | ||
77 | /* now try with the '_' */ | ||
78 | char *first_error = strdup (lt_dlerror ()); | ||
79 | symbol = lt_dlsym (lib_handle, name); | ||
80 | if (NULL == symbol) | ||
76 | { | 81 | { |
77 | /* now try with the '_' */ | 82 | LOG ("Resolving symbol `%s' failed, " |
78 | char *first_error = strdup (lt_dlerror ()); | 83 | "so I tried `%s', but that failed also. Errors are: " |
79 | symbol = lt_dlsym (lib_handle, name); | 84 | "`%s' and `%s'.\n", |
80 | if (NULL == symbol) | 85 | name + 1, |
81 | { | 86 | name, |
82 | LOG ("Resolving symbol `%s' failed, " | 87 | first_error == NULL ? "out of memory" : first_error, |
83 | "so I tried `%s', but that failed also. Errors are: " | 88 | lt_dlerror ()); |
84 | "`%s' and `%s'.\n", | ||
85 | name+1, | ||
86 | name, | ||
87 | first_error == NULL ? "out of memory" : first_error, | ||
88 | lt_dlerror ()); | ||
89 | } | ||
90 | if (NULL != first_error) | ||
91 | free (first_error); | ||
92 | } | 89 | } |
90 | if (NULL != first_error) | ||
91 | free (first_error); | ||
92 | } | ||
93 | 93 | ||
94 | if ( (NULL != symbol) && | 94 | if ( (NULL != symbol) && |
95 | (NULL != options) ) | 95 | (NULL != options) ) |
96 | { | 96 | { |
97 | /* get special options */ | 97 | /* get special options */ |
98 | sprintf (name, | 98 | sprintf (name, |
99 | "_EXTRACTOR_%s_options", | 99 | "_EXTRACTOR_%s_options", |
100 | sym); | 100 | sym); |
101 | /* try without '_' first */ | 101 | /* try without '_' first */ |
102 | opt_fun = lt_dlsym (lib_handle, name + 1); | 102 | opt_fun = lt_dlsym (lib_handle, name + 1); |
103 | if (NULL == opt_fun) | 103 | if (NULL == opt_fun) |
104 | opt_fun = lt_dlsym (lib_handle, name); | 104 | opt_fun = lt_dlsym (lib_handle, name); |
105 | if (NULL != opt_fun) | 105 | if (NULL != opt_fun) |
106 | *options = opt_fun (); | 106 | *options = opt_fun (); |
107 | } | 107 | } |
108 | free (sym); | 108 | free (sym); |
109 | free (name); | 109 | free (name); |
110 | return symbol; | 110 | return symbol; |
@@ -131,12 +131,12 @@ EXTRACTOR_plugin_load_ (struct EXTRACTOR_PluginList *plugin) | |||
131 | if (NULL == plugin->libname) | 131 | if (NULL == plugin->libname) |
132 | plugin->libname = EXTRACTOR_find_plugin_ (plugin->short_libname); | 132 | plugin->libname = EXTRACTOR_find_plugin_ (plugin->short_libname); |
133 | if (NULL == plugin->libname) | 133 | if (NULL == plugin->libname) |
134 | { | 134 | { |
135 | LOG ("Failed to find plugin `%s'\n", | 135 | LOG ("Failed to find plugin `%s'\n", |
136 | plugin->short_libname); | 136 | plugin->short_libname); |
137 | plugin->flags = EXTRACTOR_OPTION_DISABLED; | 137 | plugin->flags = EXTRACTOR_OPTION_DISABLED; |
138 | return -1; | 138 | return -1; |
139 | } | 139 | } |
140 | lt_dladvise_init (&advise); | 140 | lt_dladvise_init (&advise); |
141 | lt_dladvise_ext (&advise); | 141 | lt_dladvise_ext (&advise); |
142 | lt_dladvise_local (&advise); | 142 | lt_dladvise_local (&advise); |
@@ -144,51 +144,51 @@ EXTRACTOR_plugin_load_ (struct EXTRACTOR_PluginList *plugin) | |||
144 | wlibname[0] = L'\0'; | 144 | wlibname[0] = L'\0'; |
145 | llibname[0] = '\0'; | 145 | llibname[0] = '\0'; |
146 | if ( (MultiByteToWideChar (CP_UTF8, 0, plugin->libname, -1, | 146 | if ( (MultiByteToWideChar (CP_UTF8, 0, plugin->libname, -1, |
147 | wlibname, sizeof (wlibname)) <= 0) || | 147 | wlibname, sizeof (wlibname)) <= 0) || |
148 | (WideCharToMultiByte (CP_ACP, 0, wlibname, -1, | 148 | (WideCharToMultiByte (CP_ACP, 0, wlibname, -1, |
149 | llibname, sizeof (llibname), NULL, NULL) < 0) ) | 149 | llibname, sizeof (llibname), NULL, NULL) < 0) ) |
150 | { | 150 | { |
151 | LOG ("Loading `%s' plugin failed: %s\n", | 151 | LOG ("Loading `%s' plugin failed: %s\n", |
152 | plugin->short_libname, | 152 | plugin->short_libname, |
153 | "can't convert plugin name to local encoding"); | 153 | "can't convert plugin name to local encoding"); |
154 | free (plugin->libname); | 154 | free (plugin->libname); |
155 | plugin->libname = NULL; | 155 | plugin->libname = NULL; |
156 | plugin->flags = EXTRACTOR_OPTION_DISABLED; | 156 | plugin->flags = EXTRACTOR_OPTION_DISABLED; |
157 | return -1; | 157 | return -1; |
158 | } | 158 | } |
159 | plugin->libraryHandle = lt_dlopenadvise (llibname, | 159 | plugin->libraryHandle = lt_dlopenadvise (llibname, |
160 | advise); | 160 | advise); |
161 | #else | 161 | #else |
162 | plugin->libraryHandle = lt_dlopenadvise (plugin->libname, | 162 | plugin->libraryHandle = lt_dlopenadvise (plugin->libname, |
163 | advise); | 163 | advise); |
164 | #endif | 164 | #endif |
165 | lt_dladvise_destroy (&advise); | 165 | lt_dladvise_destroy (&advise); |
166 | if (NULL == plugin->libraryHandle) | 166 | if (NULL == plugin->libraryHandle) |
167 | { | 167 | { |
168 | LOG ("Loading `%s' plugin failed (using name `%s'): %s\n", | 168 | LOG ("Loading `%s' plugin failed (using name `%s'): %s\n", |
169 | plugin->short_libname, | 169 | plugin->short_libname, |
170 | plugin->libname, | 170 | plugin->libname, |
171 | lt_dlerror ()); | 171 | lt_dlerror ()); |
172 | free (plugin->libname); | 172 | free (plugin->libname); |
173 | plugin->libname = NULL; | 173 | plugin->libname = NULL; |
174 | plugin->flags = EXTRACTOR_OPTION_DISABLED; | 174 | plugin->flags = EXTRACTOR_OPTION_DISABLED; |
175 | return -1; | 175 | return -1; |
176 | } | 176 | } |
177 | plugin->extract_method = get_symbol_with_prefix (plugin->libraryHandle, | 177 | plugin->extract_method = get_symbol_with_prefix (plugin->libraryHandle, |
178 | "_EXTRACTOR_%s_extract_method", | 178 | "_EXTRACTOR_%s_extract_method", |
179 | plugin->libname, | 179 | plugin->libname, |
180 | &plugin->specials); | 180 | &plugin->specials); |
181 | if (NULL == plugin->extract_method) | 181 | if (NULL == plugin->extract_method) |
182 | { | 182 | { |
183 | LOG ("Resolving `extract' method of plugin `%s' failed: %s\n", | 183 | LOG ("Resolving `extract' method of plugin `%s' failed: %s\n", |
184 | plugin->short_libname, | 184 | plugin->short_libname, |
185 | lt_dlerror ()); | 185 | lt_dlerror ()); |
186 | lt_dlclose (plugin->libraryHandle); | 186 | lt_dlclose (plugin->libraryHandle); |
187 | free (plugin->libname); | 187 | free (plugin->libname); |
188 | plugin->libname = NULL; | 188 | plugin->libname = NULL; |
189 | plugin->flags = EXTRACTOR_OPTION_DISABLED; | 189 | plugin->flags = EXTRACTOR_OPTION_DISABLED; |
190 | return -1; | 190 | return -1; |
191 | } | 191 | } |
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
@@ -204,9 +204,9 @@ EXTRACTOR_plugin_load_ (struct EXTRACTOR_PluginList *plugin) | |||
204 | */ | 204 | */ |
205 | struct EXTRACTOR_PluginList * | 205 | struct EXTRACTOR_PluginList * |
206 | EXTRACTOR_plugin_add (struct EXTRACTOR_PluginList *prev, | 206 | EXTRACTOR_plugin_add (struct EXTRACTOR_PluginList *prev, |
207 | const char *library, | 207 | const char *library, |
208 | const char *options, | 208 | const char *options, |
209 | enum EXTRACTOR_Options flags) | 209 | enum EXTRACTOR_Options flags) |
210 | { | 210 | { |
211 | struct EXTRACTOR_PluginList *plugin; | 211 | struct EXTRACTOR_PluginList *plugin; |
212 | struct EXTRACTOR_PluginList *pos; | 212 | struct EXTRACTOR_PluginList *pos; |
@@ -214,22 +214,23 @@ EXTRACTOR_plugin_add (struct EXTRACTOR_PluginList *prev, | |||
214 | 214 | ||
215 | for (pos = prev; NULL != pos; pos = pos->next) | 215 | for (pos = prev; NULL != pos; pos = pos->next) |
216 | if (0 == strcmp (pos->short_libname, library)) | 216 | if (0 == strcmp (pos->short_libname, library)) |
217 | return prev; /* no change, library already loaded */ | ||
218 | if (NULL == (libname = EXTRACTOR_find_plugin_ (library))) | ||
219 | { | ||
220 | LOG ("Could not load plugin `%s'\n", | ||
221 | library); | ||
222 | return prev; | 217 | return prev; |
223 | } | 218 | /* no change, library already loaded */ |
219 | if (NULL == (libname = EXTRACTOR_find_plugin_ (library))) | ||
220 | { | ||
221 | LOG ("Could not load plugin `%s'\n", | ||
222 | library); | ||
223 | return prev; | ||
224 | } | ||
224 | if (NULL == (plugin = malloc (sizeof (struct EXTRACTOR_PluginList)))) | 225 | if (NULL == (plugin = malloc (sizeof (struct EXTRACTOR_PluginList)))) |
225 | return prev; | 226 | return prev; |
226 | memset (plugin, 0, sizeof (struct EXTRACTOR_PluginList)); | 227 | memset (plugin, 0, sizeof (struct EXTRACTOR_PluginList)); |
227 | plugin->next = prev; | 228 | plugin->next = prev; |
228 | if (NULL == (plugin->short_libname = strdup (library))) | 229 | if (NULL == (plugin->short_libname = strdup (library))) |
229 | { | 230 | { |
230 | free (plugin); | 231 | free (plugin); |
231 | return NULL; | 232 | return NULL; |
232 | } | 233 | } |
233 | plugin->libname = libname; | 234 | plugin->libname = libname; |
234 | plugin->flags = flags; | 235 | plugin->flags = flags; |
235 | if (NULL != options) | 236 | if (NULL != options) |
@@ -258,8 +259,8 @@ EXTRACTOR_plugin_add (struct EXTRACTOR_PluginList *prev, | |||
258 | */ | 259 | */ |
259 | struct EXTRACTOR_PluginList * | 260 | struct EXTRACTOR_PluginList * |
260 | EXTRACTOR_plugin_add_config (struct EXTRACTOR_PluginList *prev, | 261 | EXTRACTOR_plugin_add_config (struct EXTRACTOR_PluginList *prev, |
261 | const char *config, | 262 | const char *config, |
262 | enum EXTRACTOR_Options flags) | 263 | enum EXTRACTOR_Options flags) |
263 | { | 264 | { |
264 | char *cpy; | 265 | char *cpy; |
265 | size_t pos; | 266 | size_t pos; |
@@ -276,55 +277,55 @@ EXTRACTOR_plugin_add_config (struct EXTRACTOR_PluginList *prev, | |||
276 | last = 0; | 277 | last = 0; |
277 | lastconf = 0; | 278 | lastconf = 0; |
278 | while (pos < len) | 279 | while (pos < len) |
280 | { | ||
281 | while ( (':' != cpy[pos]) && | ||
282 | ('\0' != cpy[pos]) && | ||
283 | ('(' != cpy[pos]) ) | ||
284 | pos++; | ||
285 | switch (cpy[pos]) | ||
279 | { | 286 | { |
280 | while ( (':' != cpy[pos]) && | 287 | case '(': |
281 | ('\0' != cpy[pos]) && | 288 | cpy[pos++] = '\0'; /* replace '(' by termination */ |
282 | ('(' != cpy[pos]) ) | 289 | lastconf = pos; /* start config from here, after (. */ |
283 | pos++; | 290 | while ( ('\0' != cpy[pos]) && |
284 | switch (cpy[pos]) | 291 | (')' != cpy[pos])) |
285 | { | 292 | pos++; /* config until ) or EOS. */ |
286 | case '(': | 293 | if (')' == cpy[pos]) |
287 | cpy[pos++] = '\0'; /* replace '(' by termination */ | 294 | { |
288 | lastconf = pos; /* start config from here, after (. */ | 295 | cpy[pos++] = '\0'; /* write end of config here. */ |
289 | while ( ('\0' != cpy[pos]) && | 296 | while ( (':' != cpy[pos]) && |
290 | (')' != cpy[pos])) | 297 | ('\0' != cpy[pos]) ) |
291 | pos++; /* config until ) or EOS. */ | 298 | pos++; /* forward until real end of string found. */ |
292 | if (')' == cpy[pos]) | 299 | cpy[pos++] = '\0'; |
293 | { | 300 | } |
294 | cpy[pos++] = '\0'; /* write end of config here. */ | ||
295 | while ( (':' != cpy[pos]) && | ||
296 | ('\0' != cpy[pos]) ) | ||
297 | pos++; /* forward until real end of string found. */ | ||
298 | cpy[pos++] = '\0'; | ||
299 | } | ||
300 | else | ||
301 | { | ||
302 | cpy[pos++] = '\0'; /* end of string. */ | ||
303 | } | ||
304 | break; | ||
305 | case ':': | ||
306 | case '\0': | ||
307 | lastconf = -1; /* NULL config when no (). */ | ||
308 | cpy[pos++] = '\0'; /* replace ':' by termination */ | ||
309 | break; | ||
310 | default: | ||
311 | ABORT (); | ||
312 | } | ||
313 | if ('-' == cpy[last]) | ||
314 | { | ||
315 | last++; | ||
316 | prev = EXTRACTOR_plugin_remove (prev, | ||
317 | &cpy[last]); | ||
318 | } | ||
319 | else | 301 | else |
320 | { | 302 | { |
321 | prev = EXTRACTOR_plugin_add (prev, | 303 | cpy[pos++] = '\0'; /* end of string. */ |
322 | &cpy[last], | 304 | } |
323 | (-1 != lastconf) ? &cpy[lastconf] : NULL, | 305 | break; |
324 | flags); | 306 | case ':': |
325 | } | 307 | case '\0': |
326 | last = pos; | 308 | lastconf = -1; /* NULL config when no (). */ |
309 | cpy[pos++] = '\0'; /* replace ':' by termination */ | ||
310 | break; | ||
311 | default: | ||
312 | ABORT (); | ||
327 | } | 313 | } |
314 | if ('-' == cpy[last]) | ||
315 | { | ||
316 | last++; | ||
317 | prev = EXTRACTOR_plugin_remove (prev, | ||
318 | &cpy[last]); | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | prev = EXTRACTOR_plugin_add (prev, | ||
323 | &cpy[last], | ||
324 | (-1 != lastconf) ? &cpy[lastconf] : NULL, | ||
325 | flags); | ||
326 | } | ||
327 | last = pos; | ||
328 | } | ||
328 | free (cpy); | 329 | free (cpy); |
329 | return prev; | 330 | return prev; |
330 | } | 331 | } |
@@ -339,7 +340,7 @@ EXTRACTOR_plugin_add_config (struct EXTRACTOR_PluginList *prev, | |||
339 | */ | 340 | */ |
340 | struct EXTRACTOR_PluginList * | 341 | struct EXTRACTOR_PluginList * |
341 | EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *prev, | 342 | EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *prev, |
342 | const char *library) | 343 | const char *library) |
343 | { | 344 | { |
344 | struct EXTRACTOR_PluginList *pos; | 345 | struct EXTRACTOR_PluginList *pos; |
345 | struct EXTRACTOR_PluginList *first; | 346 | struct EXTRACTOR_PluginList *first; |
@@ -347,17 +348,17 @@ EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *prev, | |||
347 | pos = prev; | 348 | pos = prev; |
348 | first = prev; | 349 | first = prev; |
349 | while ( (NULL != pos) && | 350 | while ( (NULL != pos) && |
350 | (0 != strcmp (pos->short_libname, library)) ) | 351 | (0 != strcmp (pos->short_libname, library)) ) |
351 | { | 352 | { |
352 | prev = pos; | 353 | prev = pos; |
353 | pos = pos->next; | 354 | pos = pos->next; |
354 | } | 355 | } |
355 | if (NULL == pos) | 356 | if (NULL == pos) |
356 | { | 357 | { |
357 | LOG ("Unloading plugin `%s' failed!\n", | 358 | LOG ("Unloading plugin `%s' failed!\n", |
358 | library); | 359 | library); |
359 | return first; | 360 | return first; |
360 | } | 361 | } |
361 | /* found, close library */ | 362 | /* found, close library */ |
362 | if (first == pos) | 363 | if (first == pos) |
363 | first = pos->next; | 364 | first = pos->next; |
@@ -374,7 +375,7 @@ EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *prev, | |||
374 | free (pos->libname); | 375 | free (pos->libname); |
375 | free (pos->plugin_options); | 376 | free (pos->plugin_options); |
376 | if (NULL != pos->libraryHandle) | 377 | if (NULL != pos->libraryHandle) |
377 | lt_dlclose (pos->libraryHandle); | 378 | lt_dlclose (pos->libraryHandle); |
378 | free (pos); | 379 | free (pos); |
379 | return first; | 380 | return first; |
380 | } | 381 | } |