aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-09-22 20:10:13 +0000
committerChristian Grothoff <christian@grothoff.org>2012-09-22 20:10:13 +0000
commit6bf8c4eb84101e24cb2cafbebf6aab8d3873de38 (patch)
treefd81f0505d462116b3597f2b9e8c0646c5324098
parent3a018e2d1b57cd25d7c64d4470dc14a26851a239 (diff)
downloadlibextractor-6bf8c4eb84101e24cb2cafbebf6aab8d3873de38.tar.gz
libextractor-6bf8c4eb84101e24cb2cafbebf6aab8d3873de38.zip
-dos2unix
-rw-r--r--src/main/extractor_plugpath.c1326
1 files changed, 663 insertions, 663 deletions
diff --git a/src/main/extractor_plugpath.c b/src/main/extractor_plugpath.c
index 157b59c..8bb9a2d 100644
--- a/src/main/extractor_plugpath.c
+++ b/src/main/extractor_plugpath.c
@@ -1,663 +1,663 @@
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_plugpath.c 21 * @file main/extractor_plugpath.c
22 * @brief determine path where plugins are installed 22 * @brief determine path where plugins are installed
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
25 25
26#include "platform.h" 26#include "platform.h"
27#include "plibc.h" 27#include "plibc.h"
28#include "extractor.h" 28#include "extractor.h"
29#include <dirent.h> 29#include <dirent.h>
30#include <sys/types.h> 30#include <sys/types.h>
31#include <signal.h> 31#include <signal.h>
32#include <ltdl.h> 32#include <ltdl.h>
33 33
34#include "extractor_plugpath.h" 34#include "extractor_plugpath.h"
35#include "extractor_logging.h" 35#include "extractor_logging.h"
36 36
37/** 37/**
38 * Function to call on paths. 38 * Function to call on paths.
39 * 39 *
40 * @param cls closure 40 * @param cls closure
41 * @param path a directory path 41 * @param path a directory path
42 */ 42 */
43typedef void (*EXTRACTOR_PathProcessor) (void *cls, 43typedef void (*EXTRACTOR_PathProcessor) (void *cls,
44 const char *path); 44 const char *path);
45 45
46 46
47/** 47/**
48 * Remove a trailing '/bin/' from 'in' (if present). 48 * Remove a trailing '/bin/' from 'in' (if present).
49 * 49 *
50 * @param in input string, modified 50 * @param in input string, modified
51 * @return NULL if 'in' is NULL, otherwise 'in' with '/bin/' removed 51 * @return NULL if 'in' is NULL, otherwise 'in' with '/bin/' removed
52 */ 52 */
53static char * 53static char *
54cut_bin (char * in) 54cut_bin (char * in)
55{ 55{
56 size_t p; 56 size_t p;
57 57
58 if (NULL == in) 58 if (NULL == in)
59 return NULL; 59 return NULL;
60 p = strlen (in); 60 p = strlen (in);
61 if (p < 4) 61 if (p < 4)
62 return in; 62 return in;
63 if ( ('/' == in[p-1]) || 63 if ( ('/' == in[p-1]) ||
64 ('\\' == in[p-1]) ) 64 ('\\' == in[p-1]) )
65 in[--p] = '\0'; 65 in[--p] = '\0';
66 if (0 == strcmp (&in[p-4], 66 if (0 == strcmp (&in[p-4],
67 "/bin")) 67 "/bin"))
68 { 68 {
69 in[p-4] = '\0'; 69 in[p-4] = '\0';
70 p -= 4; 70 p -= 4;
71 } 71 }
72 else if (0 == strcmp (&in[p-4], 72 else if (0 == strcmp (&in[p-4],
73 "\\bin")) 73 "\\bin"))
74 { 74 {
75 in[p-4] = '\0'; 75 in[p-4] = '\0';
76 p -= 4; 76 p -= 4;
77 } 77 }
78 return in; 78 return in;
79} 79}
80 80
81 81
82#if GNU_LINUX 82#if GNU_LINUX
83/** 83/**
84 * Try to determine path by reading /proc/PID/exe or 84 * Try to determine path by reading /proc/PID/exe or
85 * /proc/PID/maps. 85 * /proc/PID/maps.
86 * 86 *
87 * Note that this may fail if LE is installed in one directory 87 * Note that this may fail if LE is installed in one directory
88 * and the binary linking against it sits elsewhere. 88 * and the binary linking against it sits elsewhere.
89 */ 89 */
90static char * 90static char *
91get_path_from_proc_exe () 91get_path_from_proc_exe ()
92{ 92{
93 char fn[64]; 93 char fn[64];
94 char line[1024]; 94 char line[1024];
95 char dir[1024]; 95 char dir[1024];
96 char *lnk; 96 char *lnk;
97 char *ret; 97 char *ret;
98 char *lestr; 98 char *lestr;
99 ssize_t size; 99 ssize_t size;
100 FILE *f; 100 FILE *f;
101 101
102 snprintf (fn, 102 snprintf (fn,
103 sizeof (fn), 103 sizeof (fn),
104 "/proc/%u/maps", 104 "/proc/%u/maps",
105 getpid ()); 105 getpid ());
106 if (NULL != (f = FOPEN (fn, "r"))) 106 if (NULL != (f = FOPEN (fn, "r")))
107 { 107 {
108 while (NULL != fgets (line, 1024, f)) 108 while (NULL != fgets (line, 1024, f))
109 { 109 {
110 if ( (1 == sscanf (line, 110 if ( (1 == sscanf (line,
111 "%*x-%*x %*c%*c%*c%*c %*x %*2x:%*2x %*u%*[ ]%s", 111 "%*x-%*x %*c%*c%*c%*c %*x %*2x:%*2x %*u%*[ ]%s",
112 dir)) && 112 dir)) &&
113 (NULL != (lestr = strstr (dir, 113 (NULL != (lestr = strstr (dir,
114 "libextractor")) ) ) 114 "libextractor")) ) )
115 { 115 {
116 lestr[0] = '\0'; 116 lestr[0] = '\0';
117 fclose (f); 117 fclose (f);
118 return strdup (dir); 118 return strdup (dir);
119 } 119 }
120 } 120 }
121 fclose (f); 121 fclose (f);
122 } 122 }
123 snprintf (fn, 123 snprintf (fn,
124 sizeof (fn), 124 sizeof (fn),
125 "/proc/%u/exe", 125 "/proc/%u/exe",
126 getpid ()); 126 getpid ());
127 if (NULL == (lnk = malloc (1029))) /* 1024 + 6 for "/lib/" catenation */ 127 if (NULL == (lnk = malloc (1029))) /* 1024 + 6 for "/lib/" catenation */
128 return NULL; 128 return NULL;
129 size = readlink (fn, lnk, 1023); 129 size = readlink (fn, lnk, 1023);
130 if ( (size <= 0) || (size >= 1024) ) 130 if ( (size <= 0) || (size >= 1024) )
131 { 131 {
132 free (lnk); 132 free (lnk);
133 return NULL; 133 return NULL;
134 } 134 }
135 lnk[size] = '\0'; 135 lnk[size] = '\0';
136 while ( ('/' != lnk[size]) && 136 while ( ('/' != lnk[size]) &&
137 (size > 0) ) 137 (size > 0) )
138 size--; 138 size--;
139 if ( (size < 4) || 139 if ( (size < 4) ||
140 ('/' != lnk[size-4]) ) 140 ('/' != lnk[size-4]) )
141 { 141 {
142 /* not installed in "/bin/" -- binary path probably useless */ 142 /* not installed in "/bin/" -- binary path probably useless */
143 free (lnk); 143 free (lnk);
144 return NULL; 144 return NULL;
145 } 145 }
146 lnk[size] = '\0'; 146 lnk[size] = '\0';
147 lnk = cut_bin (lnk); 147 lnk = cut_bin (lnk);
148 if (NULL == (ret = realloc (lnk, strlen(lnk) + 6))) 148 if (NULL == (ret = realloc (lnk, strlen(lnk) + 6)))
149 { 149 {
150 LOG_STRERROR ("realloc"); 150 LOG_STRERROR ("realloc");
151 free (lnk); 151 free (lnk);
152 return NULL; 152 return NULL;
153 } 153 }
154 strcat (ret, "/lib/"); /* guess "lib/" as the library dir */ 154 strcat (ret, "/lib/"); /* guess "lib/" as the library dir */
155 return ret; 155 return ret;
156} 156}
157#endif 157#endif
158 158
159 159
160#if WINDOWS 160#if WINDOWS
161/** 161/**
162 * Try to determine path with win32-specific function 162 * Try to determine path with win32-specific function
163 */ 163 */
164static char * 164static char *
165get_path_from_module_filename () 165get_path_from_module_filename ()
166{ 166{
167 char *path; 167 char *path;
168 char *ret; 168 char *ret;
169 char *idx; 169 char *idx;
170 170
171 if (NULL == (path = malloc (4103))) /* 4096+nil+6 for "/lib/" catenation */ 171 if (NULL == (path = malloc (4103))) /* 4096+nil+6 for "/lib/" catenation */
172 return NULL; 172 return NULL;
173 GetModuleFileName (NULL, path, 4096); 173 GetModuleFileName (NULL, path, 4096);
174 idx = path + strlen (path); 174 idx = path + strlen (path);
175 while ( (idx > path) && 175 while ( (idx > path) &&
176 ('\\' != *idx) && 176 ('\\' != *idx) &&
177 ('/' != *idx) ) 177 ('/' != *idx) )
178 idx--; 178 idx--;
179 *idx = '\0'; 179 *idx = '\0';
180 path = cut_bin (path); 180 path = cut_bin (path);
181 if (NULL == (ret = realloc (path, strlen(path) + 6))) 181 if (NULL == (ret = realloc (path, strlen(path) + 6)))
182 { 182 {
183 LOG_STRERROR ("realloc"); 183 LOG_STRERROR ("realloc");
184 free (path); 184 free (path);
185 return NULL; 185 return NULL;
186 } 186 }
187 strcat (ret, "/lib/"); /* guess "lib/" as the library dir */ 187 strcat (ret, "/lib/"); /* guess "lib/" as the library dir */
188 return ret; 188 return ret;
189} 189}
190#endif 190#endif
191 191
192 192
193#if DARWIN 193#if DARWIN
194#include <dlfcn.h> 194#include <dlfcn.h>
195#include <mach-o/dyld.h> 195#include <mach-o/dyld.h>
196 196
197/** 197/**
198 * Signature of the '_NSGetExecutablePath" function. 198 * Signature of the '_NSGetExecutablePath" function.
199 * 199 *
200 * @param buf where to write the path 200 * @param buf where to write the path
201 * @param number of bytes available in 'buf' 201 * @param number of bytes available in 'buf'
202 * @return 0 on success, otherwise desired number of bytes is stored in 'bufsize' 202 * @return 0 on success, otherwise desired number of bytes is stored in 'bufsize'
203 */ 203 */
204typedef int (*MyNSGetExecutablePathProto) (char *buf, 204typedef int (*MyNSGetExecutablePathProto) (char *buf,
205 size_t *bufsize); 205 size_t *bufsize);
206 206
207 207
208/** 208/**
209 * Try to obtain the path of our executable using '_NSGetExecutablePath'. 209 * Try to obtain the path of our executable using '_NSGetExecutablePath'.
210 * 210 *
211 * @return NULL on error 211 * @return NULL on error
212 */ 212 */
213static char * 213static char *
214get_path_from_NSGetExecutablePath () 214get_path_from_NSGetExecutablePath ()
215{ 215{
216 static char zero; 216 static char zero;
217 char *path; 217 char *path;
218 size_t len; 218 size_t len;
219 MyNSGetExecutablePathProto func; 219 MyNSGetExecutablePathProto func;
220 220
221 path = NULL; 221 path = NULL;
222 if (NULL == (func = 222 if (NULL == (func =
223 (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, 223 (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT,
224 "_NSGetExecutablePath"))) 224 "_NSGetExecutablePath")))
225 return NULL; 225 return NULL;
226 path = &zero; 226 path = &zero;
227 len = 0; 227 len = 0;
228 /* get the path len, including the trailing \0 */ 228 /* get the path len, including the trailing \0 */
229 (void) func (path, &len); 229 (void) func (path, &len);
230 if (0 == len) 230 if (0 == len)
231 return NULL; 231 return NULL;
232 if (NULL == (path = malloc (len))) 232 if (NULL == (path = malloc (len)))
233 { 233 {
234 LOG_STRERROR ("malloc"); 234 LOG_STRERROR ("malloc");
235 return NULL; 235 return NULL;
236 } 236 }
237 if (0 != func (path, &len)) 237 if (0 != func (path, &len))
238 { 238 {
239 GNUNET_free (path); 239 free (path);
240 return NULL; 240 return NULL;
241 } 241 }
242 len = strlen (path); 242 len = strlen (path);
243 while ((path[len] != '/') && (len > 0)) 243 while ((path[len] != '/') && (len > 0))
244 len--; 244 len--;
245 path[len] = '\0'; 245 path[len] = '\0';
246 return path; 246 return path;
247} 247}
248 248
249 249
250/** 250/**
251 * Try to obtain the path of our executable using '_dyld_image' API. 251 * Try to obtain the path of our executable using '_dyld_image' API.
252 * 252 *
253 * @return NULL on error 253 * @return NULL on error
254 */ 254 */
255static char * 255static char *
256get_path_from_dyld_image () 256get_path_from_dyld_image ()
257{ 257{
258 const char *path; 258 const char *path;
259 char *s; 259 char *s;
260 char *p; 260 char *p;
261 unsigned int i; 261 unsigned int i;
262 int c; 262 int c;
263 263
264 c = _dyld_image_count (); 264 c = _dyld_image_count ();
265 for (i = 0; i < c; i++) 265 for (i = 0; i < c; i++)
266 { 266 {
267 if (((void *) _dyld_get_image_header (i)) != (void *) &_mh_dylib_header) 267 if (((void *) _dyld_get_image_header (i)) != (void *) &_mh_dylib_header)
268 continue; 268 continue;
269 path = _dyld_get_image_name (i); 269 path = _dyld_get_image_name (i);
270 if ( (NULL == path) || (0 == strlen (path)) ) 270 if ( (NULL == path) || (0 == strlen (path)) )
271 continue; 271 continue;
272 if (NULL == (p = strdup (path))) 272 if (NULL == (p = strdup (path)))
273 { 273 {
274 LOG_STRERROR ("strdup"); 274 LOG_STRERROR ("strdup");
275 return NULL; 275 return NULL;
276 } 276 }
277 s = p + strlen (p); 277 s = p + strlen (p);
278 while ( (s > p) && ('/' != *s) ) 278 while ( (s > p) && ('/' != *s) )
279 s--; 279 s--;
280 s++; 280 s++;
281 *s = '\0'; 281 *s = '\0';
282 return p; 282 return p;
283 } 283 }
284 return NULL; 284 return NULL;
285} 285}
286#endif 286#endif
287 287
288 288
289/** 289/**
290 * Return the actual path to a file found in the current 290 * Return the actual path to a file found in the current
291 * PATH environment variable. 291 * PATH environment variable.
292 * 292 *
293 * @return path to binary, NULL if not found 293 * @return path to binary, NULL if not found
294 */ 294 */
295static char * 295static char *
296get_path_from_PATH() { 296get_path_from_PATH() {
297 struct stat sbuf; 297 struct stat sbuf;
298 char *path; 298 char *path;
299 char *pos; 299 char *pos;
300 char *end; 300 char *end;
301 char *buf; 301 char *buf;
302 char *ret; 302 char *ret;
303 const char *p; 303 const char *p;
304 304
305 if (NULL == (p = getenv ("PATH"))) 305 if (NULL == (p = getenv ("PATH")))
306 return NULL; 306 return NULL;
307 if (NULL == (path = strdup (p))) /* because we write on it */ 307 if (NULL == (path = strdup (p))) /* because we write on it */
308 { 308 {
309 LOG_STRERROR ("strdup"); 309 LOG_STRERROR ("strdup");
310 return NULL; 310 return NULL;
311 } 311 }
312 if (NULL == (buf = malloc (strlen (path) + 20))) 312 if (NULL == (buf = malloc (strlen (path) + 20)))
313 { 313 {
314 LOG_STRERROR ("malloc"); 314 LOG_STRERROR ("malloc");
315 free (path); 315 free (path);
316 return NULL; 316 return NULL;
317 } 317 }
318 pos = path; 318 pos = path;
319 while (NULL != (end = strchr(pos, ':'))) 319 while (NULL != (end = strchr(pos, ':')))
320 { 320 {
321 *end = '\0'; 321 *end = '\0';
322 sprintf (buf, "%s/%s", pos, "extract"); 322 sprintf (buf, "%s/%s", pos, "extract");
323 if (0 == stat(buf, &sbuf)) 323 if (0 == stat(buf, &sbuf))
324 { 324 {
325 free (buf); 325 free (buf);
326 if (NULL == (pos = strdup (pos))) 326 if (NULL == (pos = strdup (pos)))
327 { 327 {
328 LOG_STRERROR ("strdup"); 328 LOG_STRERROR ("strdup");
329 free (path); 329 free (path);
330 return NULL; 330 return NULL;
331 } 331 }
332 free (path); 332 free (path);
333 pos = cut_bin (pos); 333 pos = cut_bin (pos);
334 if (NULL == (ret = realloc (pos, strlen (pos) + 5))) 334 if (NULL == (ret = realloc (pos, strlen (pos) + 5)))
335 { 335 {
336 LOG_STRERROR ("realloc"); 336 LOG_STRERROR ("realloc");
337 free (pos); 337 free (pos);
338 return NULL; 338 return NULL;
339 } 339 }
340 strcat (ret, "lib/"); 340 strcat (ret, "lib/");
341 return ret; 341 return ret;
342 } 342 }
343 pos = end + 1; 343 pos = end + 1;
344 } 344 }
345 sprintf (buf, "%s/%s", pos, "extract"); 345 sprintf (buf, "%s/%s", pos, "extract");
346 if (0 == stat (buf, &sbuf)) 346 if (0 == stat (buf, &sbuf))
347 { 347 {
348 pos = strdup (pos); 348 pos = strdup (pos);
349 free (buf); 349 free (buf);
350 free (path); 350 free (path);
351 if (NULL == pos) 351 if (NULL == pos)
352 return NULL; 352 return NULL;
353 pos = cut_bin (pos); 353 pos = cut_bin (pos);
354 if (NULL == (ret = realloc (pos, strlen (pos) + 5))) 354 if (NULL == (ret = realloc (pos, strlen (pos) + 5)))
355 { 355 {
356 LOG_STRERROR ("realloc"); 356 LOG_STRERROR ("realloc");
357 free (pos); 357 free (pos);
358 return NULL; 358 return NULL;
359 } 359 }
360 strcat (ret, "lib/"); 360 strcat (ret, "lib/");
361 return ret; 361 return ret;
362 } 362 }
363 free (buf); 363 free (buf);
364 free (path); 364 free (path);
365 return NULL; 365 return NULL;
366} 366}
367 367
368 368
369/** 369/**
370 * Create a filename by appending 'fname' to 'path'. 370 * Create a filename by appending 'fname' to 'path'.
371 * 371 *
372 * @param path the base path 372 * @param path the base path
373 * @param fname the filename to append 373 * @param fname the filename to append
374 * @return '$path/$fname', NULL on error 374 * @return '$path/$fname', NULL on error
375 */ 375 */
376static char * 376static char *
377append_to_dir (const char *path, 377append_to_dir (const char *path,
378 const char *fname) 378 const char *fname)
379{ 379{
380 char *ret; 380 char *ret;
381 size_t slen; 381 size_t slen;
382 382
383 if (0 == (slen = strlen (path))) 383 if (0 == (slen = strlen (path)))
384 return NULL; 384 return NULL;
385 if (DIR_SEPARATOR == fname[0]) 385 if (DIR_SEPARATOR == fname[0])
386 fname++; 386 fname++;
387 ret = malloc (slen + strlen(fname) + 2); 387 ret = malloc (slen + strlen(fname) + 2);
388 if (NULL == ret) 388 if (NULL == ret)
389 return NULL; 389 return NULL;
390#ifdef MINGW 390#ifdef MINGW
391 if ('\\' == path[slen-1]) 391 if ('\\' == path[slen-1])
392 sprintf (ret, 392 sprintf (ret,
393 "%s%s", 393 "%s%s",
394 path, 394 path,
395 fname); 395 fname);
396 else 396 else
397 sprintf (ret, 397 sprintf (ret,
398 "%s\\%s", 398 "%s\\%s",
399 path, 399 path,
400 fname); 400 fname);
401#else 401#else
402 if ('/' == path[slen-1]) 402 if ('/' == path[slen-1])
403 sprintf (ret, 403 sprintf (ret,
404 "%s%s", 404 "%s%s",
405 path, 405 path,
406 fname); 406 fname);
407 else 407 else
408 sprintf (ret, 408 sprintf (ret,
409 "%s/%s", 409 "%s/%s",
410 path, 410 path,
411 fname); 411 fname);
412#endif 412#endif
413 return ret; 413 return ret;
414} 414}
415 415
416 416
417/** 417/**
418 * Iterate over all paths where we expect to find GNU libextractor 418 * Iterate over all paths where we expect to find GNU libextractor
419 * plugins. 419 * plugins.
420 * 420 *
421 * @param pp function to call for each path 421 * @param pp function to call for each path
422 * @param pp_cls cls argument for pp. 422 * @param pp_cls cls argument for pp.
423 */ 423 */
424static void 424static void
425get_installation_paths (EXTRACTOR_PathProcessor pp, 425get_installation_paths (EXTRACTOR_PathProcessor pp,
426 void *pp_cls) 426 void *pp_cls)
427{ 427{
428 const char *p; 428 const char *p;
429 char *path; 429 char *path;
430 char *prefix; 430 char *prefix;
431 char *d; 431 char *d;
432 char *saveptr; 432 char *saveptr;
433 433
434 prefix = NULL; 434 prefix = NULL;
435 if (NULL != (p = getenv ("LIBEXTRACTOR_PREFIX"))) 435 if (NULL != (p = getenv ("LIBEXTRACTOR_PREFIX")))
436 { 436 {
437 if (NULL == (d = strdup (p))) 437 if (NULL == (d = strdup (p)))
438 { 438 {
439 LOG_STRERROR ("strdup"); 439 LOG_STRERROR ("strdup");
440 return; 440 return;
441 } 441 }
442 for (prefix = strtok_r (d, PATH_SEPARATOR_STR, &saveptr); 442 for (prefix = strtok_r (d, PATH_SEPARATOR_STR, &saveptr);
443 NULL != prefix; 443 NULL != prefix;
444 prefix = strtok_r (NULL, PATH_SEPARATOR_STR, &saveptr)) 444 prefix = strtok_r (NULL, PATH_SEPARATOR_STR, &saveptr))
445 pp (pp_cls, prefix); 445 pp (pp_cls, prefix);
446 free (d); 446 free (d);
447 return; 447 return;
448 } 448 }
449#if GNU_LINUX 449#if GNU_LINUX
450 if (NULL == prefix) 450 if (NULL == prefix)
451 prefix = get_path_from_proc_exe (); 451 prefix = get_path_from_proc_exe ();
452#endif 452#endif
453#if WINDOWS 453#if WINDOWS
454 if (NULL == prefix) 454 if (NULL == prefix)
455 prefix = get_path_from_module_filename (); 455 prefix = get_path_from_module_filename ();
456#endif 456#endif
457#if DARWIN 457#if DARWIN
458 if (NULL == prefix) 458 if (NULL == prefix)
459 prefix = get_path_from_NSGetExecutablePath (); 459 prefix = get_path_from_NSGetExecutablePath ();
460 if (NULL == prefix) 460 if (NULL == prefix)
461 prefix = get_path_from_dyld_image (); 461 prefix = get_path_from_dyld_image ();
462#endif 462#endif
463 if (NULL == prefix) 463 if (NULL == prefix)
464 prefix = get_path_from_PATH (); 464 prefix = get_path_from_PATH ();
465 pp (pp_cls, PLUGININSTDIR); 465 pp (pp_cls, PLUGININSTDIR);
466 if (NULL == prefix) 466 if (NULL == prefix)
467 return; 467 return;
468 path = append_to_dir (prefix, PLUGINDIR); 468 path = append_to_dir (prefix, PLUGINDIR);
469 if (NULL != path) 469 if (NULL != path)
470 { 470 {
471 if (0 != strcmp (path, 471 if (0 != strcmp (path,
472 PLUGININSTDIR)) 472 PLUGININSTDIR))
473 pp (pp_cls, path); 473 pp (pp_cls, path);
474 free (path); 474 free (path);
475 } 475 }
476 free (prefix); 476 free (prefix);
477} 477}
478 478
479 479
480/** 480/**
481 * Closure for 'find_plugin_in_path'. 481 * Closure for 'find_plugin_in_path'.
482 */ 482 */
483struct SearchContext 483struct SearchContext
484{ 484{
485 /** 485 /**
486 * Name of the plugin we are looking for. 486 * Name of the plugin we are looking for.
487 */ 487 */
488 const char *short_name; 488 const char *short_name;
489 489
490 /** 490 /**
491 * Location for storing the path to the plugin upon success. 491 * Location for storing the path to the plugin upon success.
492 */ 492 */
493 char *path; 493 char *path;
494}; 494};
495 495
496 496
497/** 497/**
498 * Load all plugins from the given directory. 498 * Load all plugins from the given directory.
499 * 499 *
500 * @param cls pointer to the "struct EXTRACTOR_PluginList*" to extend 500 * @param cls pointer to the "struct EXTRACTOR_PluginList*" to extend
501 * @param path path to a directory with plugins 501 * @param path path to a directory with plugins
502 */ 502 */
503static void 503static void
504find_plugin_in_path (void *cls, 504find_plugin_in_path (void *cls,
505 const char *path) 505 const char *path)
506{ 506{
507 struct SearchContext *sc = cls; 507 struct SearchContext *sc = cls;
508 DIR *dir; 508 DIR *dir;
509 struct dirent *ent; 509 struct dirent *ent;
510 const char *sym_name; 510 const char *sym_name;
511 char *sym; 511 char *sym;
512 char *dot; 512 char *dot;
513 size_t dlen; 513 size_t dlen;
514 514
515 if (NULL != sc->path) 515 if (NULL != sc->path)
516 return; 516 return;
517 if (NULL == (dir = OPENDIR (path))) 517 if (NULL == (dir = OPENDIR (path)))
518 return; 518 return;
519 while (NULL != (ent = READDIR (dir))) 519 while (NULL != (ent = READDIR (dir)))
520 { 520 {
521 if ('.' == ent->d_name[0]) 521 if ('.' == ent->d_name[0])
522 continue; 522 continue;
523 dlen = strlen (ent->d_name); 523 dlen = strlen (ent->d_name);
524 if ( (dlen < 4) || 524 if ( (dlen < 4) ||
525 ( (0 != strcmp (&ent->d_name[dlen-3], ".so")) && 525 ( (0 != strcmp (&ent->d_name[dlen-3], ".so")) &&
526 (0 != strcasecmp (&ent->d_name[dlen-4], ".dll")) ) ) 526 (0 != strcasecmp (&ent->d_name[dlen-4], ".dll")) ) )
527 continue; /* only load '.so' and '.dll' */ 527 continue; /* only load '.so' and '.dll' */
528 if (NULL == (sym_name = strrchr (ent->d_name, '_'))) 528 if (NULL == (sym_name = strrchr (ent->d_name, '_')))
529 continue; 529 continue;
530 sym_name++; 530 sym_name++;
531 if (NULL == (sym = strdup (sym_name))) 531 if (NULL == (sym = strdup (sym_name)))
532 { 532 {
533 LOG_STRERROR ("strdup"); 533 LOG_STRERROR ("strdup");
534 CLOSEDIR (dir); 534 CLOSEDIR (dir);
535 return; 535 return;
536 } 536 }
537 dot = strchr (sym, '.'); 537 dot = strchr (sym, '.');
538 if (NULL != dot) 538 if (NULL != dot)
539 *dot = '\0'; 539 *dot = '\0';
540 if (0 == strcmp (sym, sc->short_name)) 540 if (0 == strcmp (sym, sc->short_name))
541 { 541 {
542 sc->path = append_to_dir (path, ent->d_name); 542 sc->path = append_to_dir (path, ent->d_name);
543 free (sym); 543 free (sym);
544 break; 544 break;
545 } 545 }
546 free (sym); 546 free (sym);
547 } 547 }
548 CLOSEDIR (dir); 548 CLOSEDIR (dir);
549} 549}
550 550
551 551
552/** 552/**
553 * Given a short name of a library (i.e. "mime"), find 553 * Given a short name of a library (i.e. "mime"), find
554 * the full path of the respective plugin. 554 * the full path of the respective plugin.
555 */ 555 */
556char * 556char *
557EXTRACTOR_find_plugin_ (const char *short_name) 557EXTRACTOR_find_plugin_ (const char *short_name)
558{ 558{
559 struct SearchContext sc; 559 struct SearchContext sc;
560 560
561 sc.path = NULL; 561 sc.path = NULL;
562 sc.short_name = short_name; 562 sc.short_name = short_name;
563 get_installation_paths (&find_plugin_in_path, 563 get_installation_paths (&find_plugin_in_path,
564 &sc); 564 &sc);
565 return sc.path; 565 return sc.path;
566} 566}
567 567
568 568
569/** 569/**
570 * Closure for 'load_plugins_from_dir'. 570 * Closure for 'load_plugins_from_dir'.
571 */ 571 */
572struct DefaultLoaderContext 572struct DefaultLoaderContext
573{ 573{
574 /** 574 /**
575 * Accumulated result list. 575 * Accumulated result list.
576 */ 576 */
577 struct EXTRACTOR_PluginList *res; 577 struct EXTRACTOR_PluginList *res;
578 578
579 /** 579 /**
580 * Flags to use for all plugins. 580 * Flags to use for all plugins.
581 */ 581 */
582 enum EXTRACTOR_Options flags; 582 enum EXTRACTOR_Options flags;
583}; 583};
584 584
585 585
586/** 586/**
587 * Load all plugins from the given directory. 587 * Load all plugins from the given directory.
588 * 588 *
589 * @param cls pointer to the "struct EXTRACTOR_PluginList*" to extend 589 * @param cls pointer to the "struct EXTRACTOR_PluginList*" to extend
590 * @param path path to a directory with plugins 590 * @param path path to a directory with plugins
591 */ 591 */
592static void 592static void
593load_plugins_from_dir (void *cls, 593load_plugins_from_dir (void *cls,
594 const char *path) 594 const char *path)
595{ 595{
596 struct DefaultLoaderContext *dlc = cls; 596 struct DefaultLoaderContext *dlc = cls;
597 DIR *dir; 597 DIR *dir;
598 struct dirent *ent; 598 struct dirent *ent;
599 const char *sym_name; 599 const char *sym_name;
600 char *sym; 600 char *sym;
601 char *dot; 601 char *dot;
602 size_t dlen; 602 size_t dlen;
603 603
604 if (NULL == (dir = opendir (path))) 604 if (NULL == (dir = opendir (path)))
605 return; 605 return;
606 while (NULL != (ent = readdir (dir))) 606 while (NULL != (ent = readdir (dir)))
607 { 607 {
608 if (ent->d_name[0] == '.') 608 if (ent->d_name[0] == '.')
609 continue; 609 continue;
610 dlen = strlen (ent->d_name); 610 dlen = strlen (ent->d_name);
611 if ( (dlen < 4) || 611 if ( (dlen < 4) ||
612 ( (0 != strcmp (&ent->d_name[dlen-3], ".so")) && 612 ( (0 != strcmp (&ent->d_name[dlen-3], ".so")) &&
613 (0 != strcasecmp (&ent->d_name[dlen-4], ".dll")) ) ) 613 (0 != strcasecmp (&ent->d_name[dlen-4], ".dll")) ) )
614 continue; /* only load '.so' and '.dll' */ 614 continue; /* only load '.so' and '.dll' */
615 if (NULL == (sym_name = strrchr (ent->d_name, '_'))) 615 if (NULL == (sym_name = strrchr (ent->d_name, '_')))
616 continue; 616 continue;
617 sym_name++; 617 sym_name++;
618 if (NULL == (sym = strdup (sym_name))) 618 if (NULL == (sym = strdup (sym_name)))
619 { 619 {
620 LOG_STRERROR ("strdup"); 620 LOG_STRERROR ("strdup");
621 closedir (dir); 621 closedir (dir);
622 return; 622 return;
623 } 623 }
624 if (NULL != (dot = strchr (sym, '.'))) 624 if (NULL != (dot = strchr (sym, '.')))
625 *dot = '\0'; 625 *dot = '\0';
626 dlc->res = EXTRACTOR_plugin_add (dlc->res, 626 dlc->res = EXTRACTOR_plugin_add (dlc->res,
627 sym, 627 sym,
628 NULL, 628 NULL,
629 dlc->flags); 629 dlc->flags);
630 free (sym); 630 free (sym);
631 } 631 }
632 closedir (dir); 632 closedir (dir);
633} 633}
634 634
635 635
636/** 636/**
637 * Load the default set of plugins. The default can be changed 637 * Load the default set of plugins. The default can be changed
638 * by setting the LIBEXTRACTOR_LIBRARIES environment variable. 638 * by setting the LIBEXTRACTOR_LIBRARIES environment variable.
639 * If it is set to "env", then this function will return 639 * If it is set to "env", then this function will return
640 * EXTRACTOR_plugin_add_config (NULL, env, flags). Otherwise, 640 * EXTRACTOR_plugin_add_config (NULL, env, flags). Otherwise,
641 * it will load all of the installed plugins and return them. 641 * it will load all of the installed plugins and return them.
642 * 642 *
643 * @param flags options for all of the plugins loaded 643 * @param flags options for all of the plugins loaded
644 * @return the default set of plugins, NULL if no plugins were found 644 * @return the default set of plugins, NULL if no plugins were found
645 */ 645 */
646struct EXTRACTOR_PluginList * 646struct EXTRACTOR_PluginList *
647EXTRACTOR_plugin_add_defaults (enum EXTRACTOR_Options flags) 647EXTRACTOR_plugin_add_defaults (enum EXTRACTOR_Options flags)
648{ 648{
649 struct DefaultLoaderContext dlc; 649 struct DefaultLoaderContext dlc;
650 char *env; 650 char *env;
651 651
652 env = getenv ("LIBEXTRACTOR_LIBRARIES"); 652 env = getenv ("LIBEXTRACTOR_LIBRARIES");
653 if (NULL != env) 653 if (NULL != env)
654 return EXTRACTOR_plugin_add_config (NULL, env, flags); 654 return EXTRACTOR_plugin_add_config (NULL, env, flags);
655 dlc.res = NULL; 655 dlc.res = NULL;
656 dlc.flags = flags; 656 dlc.flags = flags;
657 get_installation_paths (&load_plugins_from_dir, 657 get_installation_paths (&load_plugins_from_dir,
658 &dlc); 658 &dlc);
659 return dlc.res; 659 return dlc.res;
660} 660}
661 661
662 662
663/* end of extractor_plugpath.c */ 663/* end of extractor_plugpath.c */