aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-08-16 22:04:44 +0000
committerChristian Grothoff <christian@grothoff.org>2012-08-16 22:04:44 +0000
commit4d061ce2f83a899fbf149db1e8006a535368d081 (patch)
tree7f833aa06a773a754d57becf40305a8564ac2cc6
parentc23496d863e051ca42fdda5e4719ef173518d3f0 (diff)
downloadlibextractor-4d061ce2f83a899fbf149db1e8006a535368d081.tar.gz
libextractor-4d061ce2f83a899fbf149db1e8006a535368d081.zip
dos2unix
-rw-r--r--src/main/extractor_plugins.c788
1 files changed, 394 insertions, 394 deletions
diff --git a/src/main/extractor_plugins.c b/src/main/extractor_plugins.c
index 094c336..290d511 100644
--- a/src/main/extractor_plugins.c
+++ b/src/main/extractor_plugins.c
@@ -1,394 +1,394 @@
1/* 1/*
2 This file is part of libextractor. 2 This file is part of libextractor.
3 (C) 2002, 2003, 2004, 2005, 2006, 2009, 2012 Vidyut Samanta and Christian Grothoff 3 (C) 2002, 2003, 2004, 2005, 2006, 2009, 2012 Vidyut Samanta and Christian Grothoff
4 4
5 libextractor is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version. 8 option) any later version.
9 9
10 libextractor is distributed in the hope that it will be useful, but 10 libextractor is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 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 16 along with libextractor; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19 */ 19 */
20/** 20/**
21 * @file main/extractor_plugins.c 21 * @file main/extractor_plugins.c
22 * @brief code to load plugins 22 * @brief code to load plugins
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
25#include "extractor_plugins.h" 25#include "extractor_plugins.h"
26#include "extractor_plugpath.h" 26#include "extractor_plugpath.h"
27#include "extractor_ipc.h" 27#include "extractor_ipc.h"
28#include "extractor_logging.h" 28#include "extractor_logging.h"
29 29
30 30
31/** 31/**
32 * Try to resolve a plugin function. 32 * Try to resolve a plugin function.
33 * 33 *
34 * @param lib_handle library to search for the symbol 34 * @param lib_handle library to search for the symbol
35 * @param prefix prefix to add 35 * @param prefix prefix to add
36 * @param sym_name base name for the symbol 36 * @param sym_name base name for the symbol
37 * @param options set to special options requested by the plugin 37 * @param options set to special options requested by the plugin
38 * @return NULL on error, otherwise pointer to the symbol 38 * @return NULL on error, otherwise pointer to the symbol
39 */ 39 */
40static void * 40static void *
41get_symbol_with_prefix (void *lib_handle, 41get_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;
48 const char *sym_name; 48 const char *sym_name;
49 char *sym; 49 char *sym;
50 char *dot; 50 char *dot;
51 const char *(*opt_fun)(void); 51 const char *(*opt_fun)(void);
52 52
53 if (NULL != options) 53 if (NULL != options)
54 *options = NULL; 54 *options = NULL;
55 if (NULL == (sym_name = strrchr (prefix, '_'))) 55 if (NULL == (sym_name = strrchr (prefix, '_')))
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 { 76 {
77 /* now try with the '_' */ 77 /* now try with the '_' */
78 char *first_error = strdup (lt_dlerror ()); 78 char *first_error = strdup (lt_dlerror ());
79 symbol = lt_dlsym (lib_handle, name); 79 symbol = lt_dlsym (lib_handle, name);
80 if (NULL == symbol) 80 if (NULL == symbol)
81 { 81 {
82 LOG ("Resolving symbol `%s' failed, " 82 LOG ("Resolving symbol `%s' failed, "
83 "so I tried `%s', but that failed also. Errors are: " 83 "so I tried `%s', but that failed also. Errors are: "
84 "`%s' and `%s'.\n", 84 "`%s' and `%s'.\n",
85 name+1, 85 name+1,
86 name, 86 name,
87 first_error == NULL ? "out of memory" : first_error, 87 first_error == NULL ? "out of memory" : first_error,
88 lt_dlerror ()); 88 lt_dlerror ());
89 } 89 }
90 if (NULL != first_error) 90 if (NULL != first_error)
91 free (first_error); 91 free (first_error);
92 } 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;
111} 111}
112 112
113 113
114/** 114/**
115 * Load a plugin. 115 * Load a plugin.
116 * 116 *
117 * @param plugin plugin to load 117 * @param plugin plugin to load
118 * @return 0 on success, -1 on error 118 * @return 0 on success, -1 on error
119 */ 119 */
120int 120int
121EXTRACTOR_plugin_load_ (struct EXTRACTOR_PluginList *plugin) 121EXTRACTOR_plugin_load_ (struct EXTRACTOR_PluginList *plugin)
122{ 122{
123#if WINDOWS 123#if WINDOWS
124 wchar_t wlibname[4097]; 124 wchar_t wlibname[4097];
125 char llibname[4097]; 125 char llibname[4097];
126#endif 126#endif
127 lt_dladvise advise; 127 lt_dladvise advise;
128 128
129 if (EXTRACTOR_OPTION_DISABLED == plugin->flags) 129 if (EXTRACTOR_OPTION_DISABLED == plugin->flags)
130 return -1; 130 return -1;
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);
143#if WINDOWS 143#if WINDOWS
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
195 195
196/** 196/**
197 * Add a library for keyword extraction. 197 * Add a library for keyword extraction.
198 * 198 *
199 * @param prev the previous list of libraries, may be NULL 199 * @param prev the previous list of libraries, may be NULL
200 * @param library the name of the library 200 * @param library the name of the library
201 * @param options options to pass to the plugin 201 * @param options options to pass to the plugin
202 * @param flags options to use 202 * @param flags options to use
203 * @return the new list of libraries, equal to prev iff an error occured 203 * @return the new list of libraries, equal to prev iff an error occured
204 */ 204 */
205struct EXTRACTOR_PluginList * 205struct EXTRACTOR_PluginList *
206EXTRACTOR_plugin_add (struct EXTRACTOR_PluginList *prev, 206EXTRACTOR_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;
213 char *libname; 213 char *libname;
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 */ 217 return prev; /* no change, library already loaded */
218 if (NULL == (libname = EXTRACTOR_find_plugin_ (library))) 218 if (NULL == (libname = EXTRACTOR_find_plugin_ (library)))
219 { 219 {
220 LOG ("Could not load plugin `%s'\n", 220 LOG ("Could not load plugin `%s'\n",
221 library); 221 library);
222 return prev; 222 return prev;
223 } 223 }
224 if (NULL == (plugin = malloc (sizeof (struct EXTRACTOR_PluginList)))) 224 if (NULL == (plugin = malloc (sizeof (struct EXTRACTOR_PluginList))))
225 return prev; 225 return prev;
226 memset (plugin, 0, sizeof (struct EXTRACTOR_PluginList)); 226 memset (plugin, 0, sizeof (struct EXTRACTOR_PluginList));
227 plugin->next = prev; 227 plugin->next = prev;
228 if (NULL == (plugin->short_libname = strdup (library))) 228 if (NULL == (plugin->short_libname = strdup (library)))
229 { 229 {
230 free (plugin); 230 free (plugin);
231 return NULL; 231 return NULL;
232 } 232 }
233 plugin->libname = libname; 233 plugin->libname = libname;
234 plugin->flags = flags; 234 plugin->flags = flags;
235 if (NULL != options) 235 if (NULL != options)
236 plugin->plugin_options = strdup (options); 236 plugin->plugin_options = strdup (options);
237 else 237 else
238 plugin->plugin_options = NULL; 238 plugin->plugin_options = NULL;
239 plugin->seek_request = -1; 239 plugin->seek_request = -1;
240 return plugin; 240 return plugin;
241} 241}
242 242
243 243
244/** 244/**
245 * Load multiple libraries as specified by the user. 245 * Load multiple libraries as specified by the user.
246 * 246 *
247 * @param config a string given by the user that defines which 247 * @param config a string given by the user that defines which
248 * libraries should be loaded. Has the format 248 * libraries should be loaded. Has the format
249 * "[[-]LIBRARYNAME[(options)][:[-]LIBRARYNAME[(options)]]]*". 249 * "[[-]LIBRARYNAME[(options)][:[-]LIBRARYNAME[(options)]]]*".
250 * For example, 'mp3:ogg.so' loads the 250 * For example, 'mp3:ogg.so' loads the
251 * mp3 and the ogg library. The '-' before the LIBRARYNAME 251 * mp3 and the ogg library. The '-' before the LIBRARYNAME
252 * indicates that the library should be removed from 252 * indicates that the library should be removed from
253 * the library list. 253 * the library list.
254 * @param prev the previous list of libraries, may be NULL 254 * @param prev the previous list of libraries, may be NULL
255 * @param flags options to use 255 * @param flags options to use
256 * @return the new list of libraries, equal to prev iff an error occured 256 * @return the new list of libraries, equal to prev iff an error occured
257 * or if config was empty (or NULL). 257 * or if config was empty (or NULL).
258 */ 258 */
259struct EXTRACTOR_PluginList * 259struct EXTRACTOR_PluginList *
260EXTRACTOR_plugin_add_config (struct EXTRACTOR_PluginList *prev, 260EXTRACTOR_plugin_add_config (struct EXTRACTOR_PluginList *prev,
261 const char *config, 261 const char *config,
262 enum EXTRACTOR_Options flags) 262 enum EXTRACTOR_Options flags)
263{ 263{
264 char *cpy; 264 char *cpy;
265 size_t pos; 265 size_t pos;
266 size_t last; 266 size_t last;
267 ssize_t lastconf; 267 ssize_t lastconf;
268 size_t len; 268 size_t len;
269 269
270 if (NULL == config) 270 if (NULL == config)
271 return prev; 271 return prev;
272 if (NULL == (cpy = strdup (config))) 272 if (NULL == (cpy = strdup (config)))
273 return prev; 273 return prev;
274 len = strlen (config); 274 len = strlen (config);
275 pos = 0; 275 pos = 0;
276 last = 0; 276 last = 0;
277 lastconf = 0; 277 lastconf = 0;
278 while (pos < len) 278 while (pos < len)
279 { 279 {
280 while ( (':' != cpy[pos]) && 280 while ( (':' != cpy[pos]) &&
281 ('\0' != cpy[pos]) && 281 ('\0' != cpy[pos]) &&
282 ('(' != cpy[pos]) ) 282 ('(' != cpy[pos]) )
283 pos++; 283 pos++;
284 switch (cpy[pos]) 284 switch (cpy[pos])
285 { 285 {
286 case '(': 286 case '(':
287 cpy[pos++] = '\0'; /* replace '(' by termination */ 287 cpy[pos++] = '\0'; /* replace '(' by termination */
288 lastconf = pos; /* start config from here, after (. */ 288 lastconf = pos; /* start config from here, after (. */
289 while ( ('\0' != cpy[pos]) && 289 while ( ('\0' != cpy[pos]) &&
290 (')' != cpy[pos])) 290 (')' != cpy[pos]))
291 pos++; /* config until ) or EOS. */ 291 pos++; /* config until ) or EOS. */
292 if (')' == cpy[pos]) 292 if (')' == cpy[pos])
293 { 293 {
294 cpy[pos++] = '\0'; /* write end of config here. */ 294 cpy[pos++] = '\0'; /* write end of config here. */
295 while ( (':' != cpy[pos]) && 295 while ( (':' != cpy[pos]) &&
296 ('\0' != cpy[pos]) ) 296 ('\0' != cpy[pos]) )
297 pos++; /* forward until real end of string found. */ 297 pos++; /* forward until real end of string found. */
298 cpy[pos++] = '\0'; 298 cpy[pos++] = '\0';
299 } 299 }
300 else 300 else
301 { 301 {
302 cpy[pos++] = '\0'; /* end of string. */ 302 cpy[pos++] = '\0'; /* end of string. */
303 } 303 }
304 break; 304 break;
305 case ':': 305 case ':':
306 case '\0': 306 case '\0':
307 lastconf = -1; /* NULL config when no (). */ 307 lastconf = -1; /* NULL config when no (). */
308 cpy[pos++] = '\0'; /* replace ':' by termination */ 308 cpy[pos++] = '\0'; /* replace ':' by termination */
309 break; 309 break;
310 default: 310 default:
311 ABORT (); 311 ABORT ();
312 } 312 }
313 if ('-' == cpy[last]) 313 if ('-' == cpy[last])
314 { 314 {
315 last++; 315 last++;
316 prev = EXTRACTOR_plugin_remove (prev, 316 prev = EXTRACTOR_plugin_remove (prev,
317 &cpy[last]); 317 &cpy[last]);
318 } 318 }
319 else 319 else
320 { 320 {
321 prev = EXTRACTOR_plugin_add (prev, 321 prev = EXTRACTOR_plugin_add (prev,
322 &cpy[last], 322 &cpy[last],
323 (-1 != lastconf) ? &cpy[lastconf] : NULL, 323 (-1 != lastconf) ? &cpy[lastconf] : NULL,
324 flags); 324 flags);
325 } 325 }
326 last = pos; 326 last = pos;
327 } 327 }
328 free (cpy); 328 free (cpy);
329 return prev; 329 return prev;
330} 330}
331 331
332 332
333/** 333/**
334 * Remove a plugin from a list. 334 * Remove a plugin from a list.
335 * 335 *
336 * @param prev the current list of plugins 336 * @param prev the current list of plugins
337 * @param library the name of the plugin to remove 337 * @param library the name of the plugin to remove
338 * @return the reduced list, unchanged if the plugin was not loaded 338 * @return the reduced list, unchanged if the plugin was not loaded
339 */ 339 */
340struct EXTRACTOR_PluginList * 340struct EXTRACTOR_PluginList *
341EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *prev, 341EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *prev,
342 const char *library) 342 const char *library)
343{ 343{
344 struct EXTRACTOR_PluginList *pos; 344 struct EXTRACTOR_PluginList *pos;
345 struct EXTRACTOR_PluginList *first; 345 struct EXTRACTOR_PluginList *first;
346 346
347 pos = prev; 347 pos = prev;
348 first = prev; 348 first = prev;
349 while ( (NULL != pos) && 349 while ( (NULL != pos) &&
350 (0 != strcmp (pos->short_libname, library)) ) 350 (0 != strcmp (pos->short_libname, library)) )
351 { 351 {
352 prev = pos; 352 prev = pos;
353 pos = pos->next; 353 pos = pos->next;
354 } 354 }
355 if (NULL == pos) 355 if (NULL == pos)
356 { 356 {
357 LOG ("Unloading plugin `%s' failed!\n", 357 LOG ("Unloading plugin `%s' failed!\n",
358 library); 358 library);
359 return first; 359 return first;
360 } 360 }
361 /* found, close library */ 361 /* found, close library */
362 if (first == pos) 362 if (first == pos)
363 first = pos->next; 363 first = pos->next;
364 else 364 else
365 prev->next = pos->next; 365 prev->next = pos->next;
366 if (NULL != pos->channel) 366 if (NULL != pos->channel)
367 EXTRACTOR_IPC_channel_destroy_ (pos->channel); 367 EXTRACTOR_IPC_channel_destroy_ (pos->channel);
368 if ( (NULL != pos->shm) && 368 if ( (NULL != pos->shm) &&
369 (0 == EXTRACTOR_IPC_shared_memory_change_rc_ (pos->shm, -1)) ) 369 (0 == EXTRACTOR_IPC_shared_memory_change_rc_ (pos->shm, -1)) )
370 EXTRACTOR_IPC_shared_memory_destroy_ (pos->shm); 370 EXTRACTOR_IPC_shared_memory_destroy_ (pos->shm);
371 free (pos->short_libname); 371 free (pos->short_libname);
372 free (pos->libname); 372 free (pos->libname);
373 free (pos->plugin_options); 373 free (pos->plugin_options);
374 if (NULL != pos->libraryHandle) 374 if (NULL != pos->libraryHandle)
375 lt_dlclose (pos->libraryHandle); 375 lt_dlclose (pos->libraryHandle);
376 free (pos); 376 free (pos);
377 return first; 377 return first;
378} 378}
379 379
380 380
381/** 381/**
382 * Remove all plugins from the given list (destroys the list). 382 * Remove all plugins from the given list (destroys the list).
383 * 383 *
384 * @param plugin the list of plugins 384 * @param plugin the list of plugins
385 */ 385 */
386void 386void
387EXTRACTOR_plugin_remove_all (struct EXTRACTOR_PluginList *plugins) 387EXTRACTOR_plugin_remove_all (struct EXTRACTOR_PluginList *plugins)
388{ 388{
389 while (NULL != plugins) 389 while (NULL != plugins)
390 plugins = EXTRACTOR_plugin_remove (plugins, plugins->short_libname); 390 plugins = EXTRACTOR_plugin_remove (plugins, plugins->short_libname);
391} 391}
392 392
393 393
394/* end of extractor_plugins.c */ 394/* end of extractor_plugins.c */