diff options
Diffstat (limited to 'src/main/extractor_plugpath.c')
-rw-r--r-- | src/main/extractor_plugpath.c | 512 |
1 files changed, 314 insertions, 198 deletions
diff --git a/src/main/extractor_plugpath.c b/src/main/extractor_plugpath.c index a47cb6c..949e22a 100644 --- a/src/main/extractor_plugpath.c +++ b/src/main/extractor_plugpath.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of libextractor. | 2 | This file is part of libextractor. |
3 | (C) 2002, 2003, 2004, 2005, 2006, 2009 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 |
@@ -33,25 +33,36 @@ | |||
33 | #include "extractor_plugpath.h" | 33 | #include "extractor_plugpath.h" |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Remove a trailing '/bin' from in (if present). | 36 | * Remove a trailing '/bin/' from 'in' (if present). |
37 | * | ||
38 | * @param in input string, modified | ||
39 | * @return NULL if 'in' is NULL, otherwise 'in' with '/bin/' removed | ||
37 | */ | 40 | */ |
38 | static char * | 41 | static char * |
39 | cut_bin(char * in) { | 42 | cut_bin (char * in) |
43 | { | ||
40 | size_t p; | 44 | size_t p; |
41 | 45 | ||
42 | if (in == NULL) | 46 | if (NULL == in) |
43 | return NULL; | 47 | return NULL; |
44 | p = strlen(in); | 48 | p = strlen (in); |
45 | if (p > 4) { | 49 | if (p < 4) |
46 | if ( (in[p-1] == '/') || | 50 | return in; |
47 | (in[p-1] == '\\') ) | 51 | if ( ('/' == in[p-1]) || |
48 | in[--p] = '\0'; | 52 | ('\\' == in[p-1]) ) |
49 | if (0 == strcmp(&in[p-3], | 53 | in[--p] = '\0'; |
50 | "bin")) { | 54 | if (0 == strcmp (&in[p-4], |
51 | in[p-3] = '\0'; | 55 | "/bin")) |
52 | p -= 3; | 56 | { |
57 | in[p-4] = '\0'; | ||
58 | p -= 4; | ||
59 | } | ||
60 | else if (0 == strcmp (&in[p-4], | ||
61 | "\bin")) | ||
62 | { | ||
63 | in[p-4] = '\0'; | ||
64 | p -= 4; | ||
53 | } | 65 | } |
54 | } | ||
55 | return in; | 66 | return in; |
56 | } | 67 | } |
57 | 68 | ||
@@ -64,208 +75,269 @@ cut_bin(char * in) { | |||
64 | * and the binary linking against it sits elsewhere. | 75 | * and the binary linking against it sits elsewhere. |
65 | */ | 76 | */ |
66 | static char * | 77 | static char * |
67 | get_path_from_proc_exe() { | 78 | get_path_from_proc_exe () |
79 | { | ||
68 | char fn[64]; | 80 | char fn[64]; |
69 | char line[1024]; | 81 | char line[1024]; |
70 | char dir[1024]; | 82 | char dir[1024]; |
71 | char * lnk; | 83 | char *lnk; |
72 | char * ret; | 84 | char *ret; |
73 | char * lestr; | 85 | char *lestr; |
74 | ssize_t size; | 86 | ssize_t size; |
75 | FILE * f; | 87 | FILE *f; |
76 | 88 | ||
77 | snprintf(fn, | 89 | snprintf (fn, |
78 | sizeof (fn), | 90 | sizeof (fn), |
79 | "/proc/%u/maps", | 91 | "/proc/%u/maps", |
80 | getpid()); | 92 | getpid ()); |
81 | f = FOPEN(fn, "r"); | 93 | if (NULL != (f = FOPEN (fn, "r"))) |
82 | if (f != NULL) { | 94 | { |
83 | while (NULL != fgets(line, 1024, f)) { | 95 | while (NULL != fgets (line, 1024, f)) |
84 | if ( (1 == sscanf(line, | 96 | { |
85 | "%*x-%*x %*c%*c%*c%*c %*x %*2x:%*2x %*u%*[ ]%s", | 97 | if ( (1 == sscanf (line, |
86 | dir)) && | 98 | "%*x-%*x %*c%*c%*c%*c %*x %*2x:%*2x %*u%*[ ]%s", |
87 | (NULL != (lestr = strstr(dir, | 99 | dir)) && |
88 | "libextractor")) ) ) { | 100 | (NULL != (lestr = strstr (dir, |
89 | lestr[0] = '\0'; | 101 | "libextractor")) ) ) |
90 | fclose(f); | 102 | { |
91 | return strdup(dir); | 103 | lestr[0] = '\0'; |
92 | } | 104 | fclose (f); |
105 | return strdup (dir); | ||
106 | } | ||
107 | } | ||
108 | fclose (f); | ||
93 | } | 109 | } |
94 | fclose(f); | 110 | snprintf (fn, |
95 | } | 111 | sizeof (fn), |
96 | snprintf(fn, | 112 | "/proc/%u/exe", |
97 | sizeof (fn), | 113 | getpid ()); |
98 | "/proc/%u/exe", | 114 | if (NULL == (lnk = malloc (1029))) /* 1024 + 6 for "/lib/" catenation */ |
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; | 115 | return NULL; |
107 | } | 116 | size = readlink (fn, lnk, 1023); |
117 | if ( (size <= 0) || (size >= 1024) ) | ||
118 | { | ||
119 | free (lnk); | ||
120 | return NULL; | ||
121 | } | ||
108 | lnk[size] = '\0'; | 122 | lnk[size] = '\0'; |
109 | while ( (lnk[size] != '/') && | 123 | while ( ('/' != lnk[size]) && |
110 | (size > 0) ) | 124 | (size > 0) ) |
111 | size--; | 125 | size--; |
112 | if ( (size < 4) || | 126 | if ( (size < 4) || |
113 | (lnk[size-4] != '/') ) { | 127 | ('/' != lnk[size-4]) ) |
114 | /* not installed in "/bin/" -- binary path probably useless */ | 128 | { |
115 | free(lnk); | 129 | /* not installed in "/bin/" -- binary path probably useless */ |
116 | return NULL; | 130 | free (lnk); |
117 | } | 131 | return NULL; |
132 | } | ||
118 | lnk[size] = '\0'; | 133 | lnk[size] = '\0'; |
119 | lnk = cut_bin(lnk); | 134 | lnk = cut_bin (lnk); |
120 | ret = realloc(lnk, strlen(lnk) + 5); | 135 | if (NULL == (ret = realloc (lnk, strlen(lnk) + 6))) |
121 | if (ret == NULL) | ||
122 | { | 136 | { |
123 | free (lnk); | 137 | free (lnk); |
124 | return NULL; | 138 | return NULL; |
125 | } | 139 | } |
126 | strcat(ret, "lib/"); /* guess "lib/" as the library dir */ | 140 | strcat (ret, "/lib/"); /* guess "lib/" as the library dir */ |
127 | return ret; | 141 | return ret; |
128 | } | 142 | } |
129 | #endif | 143 | #endif |
130 | 144 | ||
145 | |||
131 | #if WINDOWS | 146 | #if WINDOWS |
132 | /** | 147 | /** |
133 | * Try to determine path with win32-specific function | 148 | * Try to determine path with win32-specific function |
134 | */ | 149 | */ |
135 | static char * | 150 | static char * |
136 | get_path_from_module_filename() { | 151 | get_path_from_module_filename () |
137 | char * path; | 152 | { |
138 | char * ret; | 153 | char *path; |
139 | char * idx; | 154 | char *ret; |
155 | char *idx; | ||
140 | 156 | ||
141 | path = malloc(4103); /* 4096+nil+6 for "/lib/" catenation */ | 157 | if (NULL == (path = malloc (4103))) /* 4096+nil+6 for "/lib/" catenation */ |
142 | if (path == NULL) | ||
143 | return NULL; | 158 | return NULL; |
144 | GetModuleFileName(NULL, path, 4096); | 159 | GetModuleFileName (NULL, path, 4096); |
145 | idx = path + strlen(path); | 160 | idx = path + strlen (path); |
146 | while ( (idx > path) && | 161 | while ( (idx > path) && |
147 | (*idx != '\\') && | 162 | ('\\' != *idx) && |
148 | (*idx != '/') ) | 163 | ('/' != *idx) ) |
149 | idx--; | 164 | idx--; |
150 | *idx = '\0'; | 165 | *idx = '\0'; |
151 | path = cut_bin(path); | 166 | path = cut_bin (path); |
152 | ret = realloc(path, strlen(path) + 6); | 167 | if (NULL == (ret = realloc (path, strlen(path) + 6))) |
153 | if (ret == NULL) | ||
154 | { | 168 | { |
155 | free (path); | 169 | free (path); |
156 | return NULL; | 170 | return NULL; |
157 | } | 171 | } |
158 | strcat(ret, "/lib/"); /* guess "lib/" as the library dir */ | 172 | strcat (ret, "/lib/"); /* guess "lib/" as the library dir */ |
159 | return ret; | 173 | return ret; |
160 | } | 174 | } |
161 | #endif | 175 | #endif |
162 | 176 | ||
177 | |||
163 | #if DARWIN | 178 | #if DARWIN |
164 | static char * get_path_from_dyld_image() { | 179 | /** |
165 | const char * path; | 180 | * Signature of the '_NSGetExecutablePath" function. |
166 | char * p, * s; | 181 | * |
167 | int i; | 182 | * @param buf where to write the path |
183 | * @param number of bytes available in 'buf' | ||
184 | * @return 0 on success, otherwise desired number of bytes is stored in 'bufsize' | ||
185 | */ | ||
186 | typedef int (*MyNSGetExecutablePathProto) (char *buf, | ||
187 | size_t *bufsize); | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Try to obtain the path of our executable using '_NSGetExecutablePath'. | ||
192 | * | ||
193 | * @return NULL on error | ||
194 | */ | ||
195 | static char * | ||
196 | get_path_from_NSGetExecutablePath () | ||
197 | { | ||
198 | static char zero; | ||
199 | char *path; | ||
200 | size_t len; | ||
201 | MyNSGetExecutablePathProto func; | ||
202 | |||
203 | path = NULL; | ||
204 | if (NULL == (func = | ||
205 | (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, | ||
206 | "_NSGetExecutablePath"))) | ||
207 | return NULL; | ||
208 | path = &zero; | ||
209 | len = 0; | ||
210 | /* get the path len, including the trailing \0 */ | ||
211 | (void) func (path, &len); | ||
212 | if (0 == len) | ||
213 | return NULL; | ||
214 | path = GNUNET_malloc (len); | ||
215 | if (0 != func (path, &len)) | ||
216 | { | ||
217 | GNUNET_free (path); | ||
218 | return NULL; | ||
219 | } | ||
220 | len = strlen (path); | ||
221 | while ((path[len] != '/') && (len > 0)) | ||
222 | len--; | ||
223 | path[len] = '\0'; | ||
224 | return path; | ||
225 | } | ||
226 | |||
227 | |||
228 | /** | ||
229 | * Try to obtain the path of our executable using '_dyld_image' API. | ||
230 | * | ||
231 | * @return NULL on error | ||
232 | */ | ||
233 | static char * | ||
234 | get_path_from_dyld_image () | ||
235 | { | ||
236 | const char *path; | ||
237 | char *s; | ||
238 | unsigned int i; | ||
168 | int c; | 239 | int c; |
169 | 240 | ||
170 | p = NULL; | 241 | c = _dyld_image_count (); |
171 | c = _dyld_image_count(); | 242 | for (i = 0; i < c; i++) |
172 | for (i = 0; i < c; i++) { | 243 | { |
173 | if (_dyld_get_image_header(i) == &_mh_dylib_header) { | 244 | if (_dyld_get_image_header (i) != &_mh_dylib_header) |
174 | path = _dyld_get_image_name(i); | 245 | continue; |
175 | if (path != NULL && strlen(path) > 0) { | 246 | path = _dyld_get_image_name (i); |
176 | p = strdup(path); | 247 | if ( (NULL == path) || (0 == strlen (path)) ) |
177 | if (p == NULL) | 248 | continue; |
178 | return NULL; | 249 | if (NULL == (p = strdup (path))) |
179 | s = p + strlen(p); | 250 | return NULL; |
180 | while ( (s > p) && (*s != '/') ) | 251 | s = p + strlen (p); |
181 | s--; | 252 | while ( (s > p) && ('/' != *s) ) |
182 | s++; | 253 | s--; |
183 | *s = '\0'; | 254 | s++; |
184 | } | 255 | *s = '\0'; |
185 | break; | 256 | return p; |
186 | } | 257 | } |
187 | } | 258 | return NULL; |
188 | return p; | ||
189 | } | 259 | } |
190 | #endif | 260 | #endif |
191 | 261 | ||
262 | |||
192 | /** | 263 | /** |
193 | * This may also fail -- for example, if extract | 264 | * Return the actual path to a file found in the current |
194 | * is not also installed. | 265 | * PATH environment variable. |
266 | * | ||
267 | * @return path to binary, NULL if not found | ||
195 | */ | 268 | */ |
196 | static char * | 269 | static char * |
197 | get_path_from_PATH() { | 270 | get_path_from_PATH() { |
198 | struct stat sbuf; | 271 | struct stat sbuf; |
199 | char * path; | 272 | char *path; |
200 | char * pos; | 273 | char *pos; |
201 | char * end; | 274 | char *end; |
202 | char * buf; | 275 | char *buf; |
203 | char * ret; | 276 | char *ret; |
204 | const char * p; | 277 | const char *p; |
205 | 278 | ||
206 | p = getenv("PATH"); | 279 | if (NULL == (p = getenv ("PATH"))) |
207 | if (p == NULL) | ||
208 | return NULL; | 280 | return NULL; |
209 | path = strdup(p); /* because we write on it */ | 281 | if (NULL == (path = strdup (p))) /* because we write on it */ |
210 | if (path == NULL) | ||
211 | return NULL; | 282 | return NULL; |
212 | buf = malloc(strlen(path) + 20); | 283 | if (NULL == (buf = malloc (strlen(path) + 20))) |
213 | if (buf == NULL) | ||
214 | { | 284 | { |
215 | free (path); | 285 | free (path); |
216 | return NULL; | 286 | return NULL; |
217 | } | 287 | } |
218 | pos = path; | 288 | pos = path; |
219 | 289 | while (NULL != (end = strchr(pos, ':'))) | |
220 | while (NULL != (end = strchr(pos, ':'))) { | 290 | { |
221 | *end = '\0'; | 291 | *end = '\0'; |
222 | sprintf(buf, "%s/%s", pos, "extract"); | 292 | sprintf(buf, "%s/%s", pos, "extract"); |
223 | if (0 == stat(buf, &sbuf)) { | 293 | if (0 == stat(buf, &sbuf)) |
224 | pos = strdup(pos); | 294 | { |
225 | free(buf); | 295 | pos = strdup(pos); |
226 | free(path); | 296 | free (buf); |
227 | if (pos == NULL) | 297 | free (path); |
298 | if (NULL == pos) | ||
299 | return NULL; | ||
300 | pos = cut_bin (pos); | ||
301 | if (NULL == (ret = realloc (pos, strlen(pos) + 5))) | ||
302 | { | ||
303 | free (pos); | ||
304 | return NULL; | ||
305 | } | ||
306 | strcat (ret, "lib/"); | ||
307 | return ret; | ||
308 | } | ||
309 | pos = end + 1; | ||
310 | } | ||
311 | sprintf(buf, "%s/%s", pos, "extract"); | ||
312 | if (0 == stat (buf, &sbuf)) | ||
313 | { | ||
314 | pos = strdup (pos); | ||
315 | free (buf); | ||
316 | free (path); | ||
317 | if (NULL == pos) | ||
228 | return NULL; | 318 | return NULL; |
229 | pos = cut_bin(pos); | 319 | pos = cut_bin (pos); |
230 | ret = realloc(pos, strlen(pos) + 5); | 320 | ret = realloc (pos, strlen(pos) + 5); |
231 | if (ret == NULL) | 321 | if (NULL == ret) |
232 | { | 322 | { |
233 | free (pos); | 323 | free (pos); |
234 | return NULL; | 324 | return NULL; |
235 | } | 325 | } |
236 | strcat(ret, "lib/"); | 326 | strcat (ret, "lib/"); |
237 | return ret; | 327 | return ret; |
238 | } | 328 | } |
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); | 329 | free(buf); |
259 | free(path); | 330 | free(path); |
260 | return NULL; | 331 | return NULL; |
261 | } | 332 | } |
262 | 333 | ||
334 | |||
263 | /** | 335 | /** |
264 | * Create a filename by appending 'fname' to 'path'. | 336 | * Create a filename by appending 'fname' to 'path'. |
265 | * | 337 | * |
266 | * @param path the base path | 338 | * @param path the base path |
267 | * @param fname the filename to append | 339 | * @param fname the filename to append |
268 | * @return '$path/$fname' | 340 | * @return '$path/$fname', NULL on error |
269 | */ | 341 | */ |
270 | static char * | 342 | static char * |
271 | append_to_dir (const char *path, | 343 | append_to_dir (const char *path, |
@@ -274,16 +346,15 @@ append_to_dir (const char *path, | |||
274 | char *ret; | 346 | char *ret; |
275 | size_t slen; | 347 | size_t slen; |
276 | 348 | ||
277 | slen = strlen (path); | 349 | if (0 == (slen = strlen (path))) |
278 | if (slen == 0) | ||
279 | return NULL; | 350 | return NULL; |
280 | if (fname[0] == DIR_SEPARATOR) | 351 | if (DIR_SEPARATOR == fname[0]) |
281 | fname++; | 352 | fname++; |
282 | ret = malloc (slen + strlen(fname) + 2); | 353 | ret = malloc (slen + strlen(fname) + 2); |
283 | if (ret == NULL) | 354 | if (NULL == ret) |
284 | return NULL; | 355 | return NULL; |
285 | #ifdef MINGW | 356 | #ifdef MINGW |
286 | if (path[slen-1] == '\\') | 357 | if ('\\' == path[slen-1]) |
287 | sprintf (ret, | 358 | sprintf (ret, |
288 | "%s%s", | 359 | "%s%s", |
289 | path, | 360 | path, |
@@ -294,16 +365,16 @@ append_to_dir (const char *path, | |||
294 | path, | 365 | path, |
295 | fname); | 366 | fname); |
296 | #else | 367 | #else |
297 | if (path[slen-1] == '/') | 368 | if ('/' == path[slen-1]) |
298 | sprintf (ret, | 369 | sprintf (ret, |
299 | "%s%s", | 370 | "%s%s", |
300 | path, | 371 | path, |
301 | fname); | 372 | fname); |
302 | else | 373 | else |
303 | sprintf (ret, | 374 | sprintf (ret, |
304 | "%s/%s", | 375 | "%s/%s", |
305 | path, | 376 | path, |
306 | fname); | 377 | fname); |
307 | #endif | 378 | #endif |
308 | return ret; | 379 | return ret; |
309 | } | 380 | } |
@@ -317,49 +388,47 @@ append_to_dir (const char *path, | |||
317 | * @param pp_cls cls argument for pp. | 388 | * @param pp_cls cls argument for pp. |
318 | */ | 389 | */ |
319 | void | 390 | void |
320 | get_installation_paths (PathProcessor pp, | 391 | EXTRACTOR_get_installation_paths_ (EXTRACTOR_PathProcessor pp, |
321 | void *pp_cls) | 392 | void *pp_cls) |
322 | { | 393 | { |
323 | const char *p; | 394 | const char *p; |
324 | char * path; | 395 | char *path; |
325 | char * prefix; | 396 | char *prefix; |
326 | char * d; | 397 | char *d; |
327 | 398 | ||
328 | prefix = NULL; | 399 | prefix = NULL; |
329 | p = getenv("LIBEXTRACTOR_PREFIX"); | 400 | if (NULL != (p = getenv ("LIBEXTRACTOR_PREFIX"))) |
330 | if (p != NULL) | ||
331 | { | 401 | { |
332 | d = strdup (p); | 402 | if (NULL == (d = strdup (p))) |
333 | if (d == NULL) | ||
334 | return; | 403 | return; |
335 | prefix = strtok (d, PATH_SEPARATOR_STR); | 404 | for (prefix = strtok (d, PATH_SEPARATOR_STR); |
336 | while (NULL != prefix) | 405 | NULL != prefix; |
337 | { | 406 | prefix = strtok (NULL, PATH_SEPARATOR_STR)) |
338 | pp (pp_cls, prefix); | 407 | pp (pp_cls, prefix); |
339 | prefix = strtok (NULL, PATH_SEPARATOR_STR); | ||
340 | } | ||
341 | free (d); | 408 | free (d); |
342 | return; | 409 | return; |
343 | } | 410 | } |
344 | #if LINUX | 411 | #if LINUX |
345 | if (prefix == NULL) | 412 | if (NULL == prefix) |
346 | prefix = get_path_from_proc_exe(); | 413 | prefix = get_path_from_proc_exe (); |
347 | #endif | 414 | #endif |
348 | #if WINDOWS | 415 | #if WINDOWS |
349 | if (prefix == NULL) | 416 | if (NULL == prefix) |
350 | prefix = get_path_from_module_filename(); | 417 | prefix = get_path_from_module_filename (); |
351 | #endif | 418 | #endif |
352 | #if DARWIN | 419 | #if DARWIN |
353 | if (prefix == NULL) | 420 | if (NULL == prefix) |
354 | prefix = get_path_from_dyld_image(); | 421 | prefix = get_path_from_NSGetExecutablePath (); |
422 | if (NULL == prefix) | ||
423 | prefix = get_path_from_dyld_image (); | ||
355 | #endif | 424 | #endif |
356 | if (prefix == NULL) | 425 | if (NULL == prefix) |
357 | prefix = get_path_from_PATH(); | 426 | prefix = get_path_from_PATH (); |
358 | pp (pp_cls, PLUGININSTDIR); | 427 | pp (pp_cls, PLUGININSTDIR); |
359 | if (prefix == NULL) | 428 | if (NULL == prefix) |
360 | return; | 429 | return; |
361 | path = append_to_dir (prefix, PLUGINDIR); | 430 | path = append_to_dir (prefix, PLUGINDIR); |
362 | if (path != NULL) | 431 | if (NULL != path) |
363 | { | 432 | { |
364 | if (0 != strcmp (path, | 433 | if (0 != strcmp (path, |
365 | PLUGININSTDIR)) | 434 | PLUGININSTDIR)) |
@@ -370,9 +439,19 @@ get_installation_paths (PathProcessor pp, | |||
370 | } | 439 | } |
371 | 440 | ||
372 | 441 | ||
442 | /** | ||
443 | * Closure for 'find_plugin_in_path'. | ||
444 | */ | ||
373 | struct SearchContext | 445 | struct SearchContext |
374 | { | 446 | { |
447 | /** | ||
448 | * Name of the plugin we are looking for. | ||
449 | */ | ||
375 | const char *short_name; | 450 | const char *short_name; |
451 | |||
452 | /** | ||
453 | * Location for storing the path to the plugin upon success. | ||
454 | */ | ||
376 | char *path; | 455 | char *path; |
377 | }; | 456 | }; |
378 | 457 | ||
@@ -395,30 +474,28 @@ find_plugin_in_path (void *cls, | |||
395 | char *sym; | 474 | char *sym; |
396 | char *dot; | 475 | char *dot; |
397 | 476 | ||
398 | if (sc->path != NULL) | 477 | if (NULL != sc->path) |
399 | return; | 478 | return; |
400 | dir = OPENDIR (path); | 479 | if (NULL == (dir = OPENDIR (path))) |
401 | if (NULL == dir) | ||
402 | return; | 480 | return; |
403 | while (NULL != (ent = READDIR (dir))) | 481 | while (NULL != (ent = READDIR (dir))) |
404 | { | 482 | { |
405 | if (ent->d_name[0] == '.') | 483 | if ('.' == ent->d_name[0]) |
406 | continue; | 484 | continue; |
407 | if ( (NULL != (la = strstr (ent->d_name, ".la"))) && | 485 | if ( (NULL != (la = strstr (ent->d_name, ".la"))) && |
408 | (la[3] == '\0') ) | 486 | ('\0' == la[3]) ) |
409 | continue; /* only load '.so' and '.dll' */ | 487 | continue; /* only load '.so' and '.dll' */ |
410 | sym_name = strrchr (ent->d_name, '_'); | 488 | if (NULL == (sym_name = strrchr (ent->d_name, '_'))) |
411 | if (sym_name == NULL) | ||
412 | continue; | 489 | continue; |
413 | sym_name++; | 490 | sym_name++; |
414 | sym = strdup (sym_name); | 491 | sym = strdup (sym_name); |
415 | if (sym == NULL) | 492 | if (NULL == sym) |
416 | { | 493 | { |
417 | CLOSEDIR (dir); | 494 | CLOSEDIR (dir); |
418 | return; | 495 | return; |
419 | } | 496 | } |
420 | dot = strchr (sym, '.'); | 497 | dot = strchr (sym, '.'); |
421 | if (dot != NULL) | 498 | if (NULL != dot) |
422 | *dot = '\0'; | 499 | *dot = '\0'; |
423 | if (0 == strcmp (sym, sc->short_name)) | 500 | if (0 == strcmp (sym, sc->short_name)) |
424 | { | 501 | { |
@@ -428,13 +505,6 @@ find_plugin_in_path (void *cls, | |||
428 | } | 505 | } |
429 | free (sym); | 506 | free (sym); |
430 | } | 507 | } |
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); | 508 | CLOSEDIR (dir); |
439 | } | 509 | } |
440 | 510 | ||
@@ -444,7 +514,7 @@ find_plugin_in_path (void *cls, | |||
444 | * the full path of the respective plugin. | 514 | * the full path of the respective plugin. |
445 | */ | 515 | */ |
446 | char * | 516 | char * |
447 | find_plugin (const char *short_name) | 517 | EXTRACTOR_find_plugin_ (const char *short_name) |
448 | { | 518 | { |
449 | struct SearchContext sc; | 519 | struct SearchContext sc; |
450 | 520 | ||
@@ -456,13 +526,30 @@ find_plugin (const char *short_name) | |||
456 | } | 526 | } |
457 | 527 | ||
458 | 528 | ||
529 | /** | ||
530 | * Closure for 'load_plugins_from_dir'. | ||
531 | */ | ||
532 | struct DefaultLoaderContext | ||
533 | { | ||
534 | /** | ||
535 | * Accumulated result list. | ||
536 | */ | ||
537 | struct EXTRACTOR_PluginList *res; | ||
538 | |||
539 | /** | ||
540 | * Flags to use for all plugins. | ||
541 | */ | ||
542 | enum EXTRACTOR_Options flags; | ||
543 | }; | ||
544 | |||
545 | |||
459 | /** | 546 | /** |
460 | * Load all plugins from the given directory. | 547 | * Load all plugins from the given directory. |
461 | * | 548 | * |
462 | * @param cls pointer to the "struct EXTRACTOR_PluginList*" to extend | 549 | * @param cls pointer to the "struct EXTRACTOR_PluginList*" to extend |
463 | * @param path path to a directory with plugins | 550 | * @param path path to a directory with plugins |
464 | */ | 551 | */ |
465 | void | 552 | static void |
466 | load_plugins_from_dir (void *cls, | 553 | load_plugins_from_dir (void *cls, |
467 | const char *path) | 554 | const char *path) |
468 | { | 555 | { |
@@ -514,3 +601,32 @@ load_plugins_from_dir (void *cls, | |||
514 | closedir (dir); | 601 | closedir (dir); |
515 | } | 602 | } |
516 | 603 | ||
604 | |||
605 | /** | ||
606 | * Load the default set of plugins. The default can be changed | ||
607 | * by setting the LIBEXTRACTOR_LIBRARIES environment variable. | ||
608 | * If it is set to "env", then this function will return | ||
609 | * EXTRACTOR_plugin_add_config (NULL, env, flags). Otherwise, | ||
610 | * it will load all of the installed plugins and return them. | ||
611 | * | ||
612 | * @param flags options for all of the plugins loaded | ||
613 | * @return the default set of plugins, NULL if no plugins were found | ||
614 | */ | ||
615 | struct EXTRACTOR_PluginList * | ||
616 | EXTRACTOR_plugin_add_defaults (enum EXTRACTOR_Options flags) | ||
617 | { | ||
618 | struct DefaultLoaderContext dlc; | ||
619 | char *env; | ||
620 | |||
621 | env = getenv ("LIBEXTRACTOR_LIBRARIES"); | ||
622 | if (NULL != env) | ||
623 | return EXTRACTOR_plugin_add_config (NULL, env, flags); | ||
624 | dlc.res = NULL; | ||
625 | dlc.flags = flags; | ||
626 | get_installation_paths (&load_plugins_from_dir, | ||
627 | &dlc); | ||
628 | return dlc.res; | ||
629 | } | ||
630 | |||
631 | |||
632 | /* end of extractor_plugpath.c */ | ||