diff options
Diffstat (limited to 'src/main')
33 files changed, 3786 insertions, 3647 deletions
diff --git a/src/main/extract.c b/src/main/extract.c index 2492fa9..144f2c3 100644 --- a/src/main/extract.c +++ b/src/main/extract.c | |||
@@ -73,6 +73,8 @@ ignore_sigpipe () | |||
73 | FPRINTF (stderr, | 73 | FPRINTF (stderr, |
74 | "Failed to install SIGPIPE handler: %s\n", strerror (errno)); | 74 | "Failed to install SIGPIPE handler: %s\n", strerror (errno)); |
75 | } | 75 | } |
76 | |||
77 | |||
76 | #endif | 78 | #endif |
77 | 79 | ||
78 | 80 | ||
@@ -89,17 +91,17 @@ struct Help | |||
89 | /** | 91 | /** |
90 | * Long name of the option. | 92 | * Long name of the option. |
91 | */ | 93 | */ |
92 | const char * longArg; | 94 | const char *longArg; |
93 | 95 | ||
94 | /** | 96 | /** |
95 | * Name of the mandatory argument, NULL for no argument. | 97 | * Name of the mandatory argument, NULL for no argument. |
96 | */ | 98 | */ |
97 | const char * mandatoryArg; | 99 | const char *mandatoryArg; |
98 | 100 | ||
99 | /** | 101 | /** |
100 | * Help text for the option. | 102 | * Help text for the option. |
101 | */ | 103 | */ |
102 | const char * description; | 104 | const char *description; |
103 | }; | 105 | }; |
104 | 106 | ||
105 | 107 | ||
@@ -118,8 +120,8 @@ struct Help | |||
118 | */ | 120 | */ |
119 | static void | 121 | static void |
120 | format_help (const char *general, | 122 | format_help (const char *general, |
121 | const char *description, | 123 | const char *description, |
122 | const struct Help *opt) | 124 | const struct Help *opt) |
123 | { | 125 | { |
124 | size_t slen; | 126 | size_t slen; |
125 | unsigned int i; | 127 | unsigned int i; |
@@ -129,79 +131,80 @@ format_help (const char *general, | |||
129 | char scp[80]; | 131 | char scp[80]; |
130 | const char *trans; | 132 | const char *trans; |
131 | 133 | ||
132 | printf (_("Usage: %s\n%s\n\n"), | 134 | printf (_ ("Usage: %s\n%s\n\n"), |
133 | gettext(general), | 135 | gettext (general), |
134 | gettext(description)); | 136 | gettext (description)); |
135 | printf (_("Arguments mandatory for long options are also mandatory for short options.\n")); | 137 | printf (_ ( |
138 | "Arguments mandatory for long options are also mandatory for short options.\n")); | ||
136 | slen = 0; | 139 | slen = 0; |
137 | i = 0; | 140 | i = 0; |
138 | while (NULL != opt[i].description) | 141 | while (NULL != opt[i].description) |
142 | { | ||
143 | if (0 == opt[i].shortArg) | ||
144 | printf (" "); | ||
145 | else | ||
146 | printf (" -%c, ", | ||
147 | opt[i].shortArg); | ||
148 | printf ("--%s", | ||
149 | opt[i].longArg); | ||
150 | slen = 8 + strlen (opt[i].longArg); | ||
151 | if (NULL != opt[i].mandatoryArg) | ||
139 | { | 152 | { |
140 | if (0 == opt[i].shortArg) | 153 | printf ("=%s", |
141 | printf (" "); | 154 | opt[i].mandatoryArg); |
142 | else | 155 | slen += 1 + strlen (opt[i].mandatoryArg); |
143 | printf (" -%c, ", | 156 | } |
144 | opt[i].shortArg); | 157 | if (slen > BORDER) |
145 | printf ("--%s", | 158 | { |
146 | opt[i].longArg); | 159 | printf ("\n%*s", BORDER, ""); |
147 | slen = 8 + strlen(opt[i].longArg); | 160 | slen = BORDER; |
148 | if (NULL != opt[i].mandatoryArg) | 161 | } |
149 | { | 162 | if (slen < BORDER) |
150 | printf ("=%s", | 163 | { |
151 | opt[i].mandatoryArg); | 164 | printf ("%*s", (int) (BORDER - slen), ""); |
152 | slen += 1+strlen(opt[i].mandatoryArg); | 165 | slen = BORDER; |
153 | } | 166 | } |
154 | if (slen > BORDER) | 167 | trans = gettext (opt[i].description); |
155 | { | 168 | ml = strlen (trans); |
156 | printf ("\n%*s", BORDER, ""); | 169 | p = 0; |
157 | slen = BORDER; | 170 | OUTER: |
158 | } | 171 | while (ml - p > 78 - slen) |
159 | if (slen < BORDER) | 172 | { |
160 | { | 173 | for (j = p + 78 - slen; j>p; j--) |
161 | printf ("%*s", (int) (BORDER - slen), ""); | 174 | { |
162 | slen = BORDER; | 175 | if (isspace ( (unsigned char) trans[j])) |
163 | } | 176 | { |
164 | trans = gettext(opt[i].description); | 177 | memcpy (scp, |
165 | ml = strlen(trans); | 178 | &trans[p], |
166 | p = 0; | 179 | j - p); |
167 | OUTER: | 180 | scp[j - p] = '\0'; |
168 | while (ml - p > 78 - slen) | 181 | printf ("%s\n%*s", |
169 | { | 182 | scp, |
170 | for (j=p+78-slen;j>p;j--) | 183 | BORDER + 2, |
171 | { | 184 | ""); |
172 | if (isspace( (unsigned char) trans[j])) | 185 | p = j + 1; |
173 | { | 186 | slen = BORDER + 2; |
174 | memcpy(scp, | 187 | goto OUTER; |
175 | &trans[p], | 188 | } |
176 | j-p); | 189 | } |
177 | scp[j-p] = '\0'; | 190 | /* could not find space to break line */ |
178 | printf ("%s\n%*s", | 191 | memcpy (scp, |
179 | scp, | 192 | &trans[p], |
180 | BORDER + 2, | 193 | 78 - slen); |
181 | ""); | 194 | scp[78 - slen] = '\0'; |
182 | p = j+1; | 195 | printf ("%s\n%*s", |
183 | slen = BORDER + 2; | 196 | scp, |
184 | goto OUTER; | 197 | BORDER + 2, |
185 | } | 198 | ""); |
186 | } | 199 | slen = BORDER + 2; |
187 | /* could not find space to break line */ | 200 | p = p + 78 - slen; |
188 | memcpy (scp, | ||
189 | &trans[p], | ||
190 | 78 - slen); | ||
191 | scp[78 - slen] = '\0'; | ||
192 | printf ("%s\n%*s", | ||
193 | scp, | ||
194 | BORDER+2, | ||
195 | ""); | ||
196 | slen = BORDER+2; | ||
197 | p = p + 78 - slen; | ||
198 | } | ||
199 | /* print rest */ | ||
200 | if (p < ml) | ||
201 | printf("%s\n", | ||
202 | &trans[p]); | ||
203 | i++; | ||
204 | } | 201 | } |
202 | /* print rest */ | ||
203 | if (p < ml) | ||
204 | printf ("%s\n", | ||
205 | &trans[p]); | ||
206 | i++; | ||
207 | } | ||
205 | } | 208 | } |
206 | 209 | ||
207 | 210 | ||
@@ -211,40 +214,43 @@ format_help (const char *general, | |||
211 | static void | 214 | static void |
212 | print_help () | 215 | print_help () |
213 | { | 216 | { |
214 | static struct Help help[] = | 217 | static struct Help help[] = { |
215 | { | 218 | { 'b', "bibtex", NULL, |
216 | { 'b', "bibtex", NULL, | 219 | gettext_noop ("print output in bibtex format") }, |
217 | gettext_noop("print output in bibtex format") }, | 220 | { 'g', "grep-friendly", NULL, |
218 | { 'g', "grep-friendly", NULL, | 221 | gettext_noop ( |
219 | gettext_noop("produce grep-friendly output (all results on one line per file)") }, | 222 | "produce grep-friendly output (all results on one line per file)") }, |
220 | { 'h', "help", NULL, | 223 | { 'h', "help", NULL, |
221 | gettext_noop("print this help") }, | 224 | gettext_noop ("print this help") }, |
222 | { 'i', "in-process", NULL, | 225 | { 'i', "in-process", NULL, |
223 | gettext_noop("run plugins in-process (simplifies debugging)") }, | 226 | gettext_noop ("run plugins in-process (simplifies debugging)") }, |
224 | { 'm', "from-memory", NULL, | 227 | { 'm', "from-memory", NULL, |
225 | gettext_noop("read data from file into memory and extract from memory") }, | 228 | gettext_noop ( |
226 | { 'l', "library", "LIBRARY", | 229 | "read data from file into memory and extract from memory") }, |
227 | gettext_noop("load an extractor plugin named LIBRARY") }, | 230 | { 'l', "library", "LIBRARY", |
228 | { 'L', "list", NULL, | 231 | gettext_noop ("load an extractor plugin named LIBRARY") }, |
229 | gettext_noop("list all keyword types") }, | 232 | { 'L', "list", NULL, |
230 | { 'n', "nodefault", NULL, | 233 | gettext_noop ("list all keyword types") }, |
231 | gettext_noop("do not use the default set of extractor plugins") }, | 234 | { 'n', "nodefault", NULL, |
232 | { 'p', "print", "TYPE", | 235 | gettext_noop ("do not use the default set of extractor plugins") }, |
233 | gettext_noop("print only keywords of the given TYPE (use -L to get a list)") }, | 236 | { 'p', "print", "TYPE", |
234 | { 'v', "version", NULL, | 237 | gettext_noop ( |
235 | gettext_noop("print the version number") }, | 238 | "print only keywords of the given TYPE (use -L to get a list)") }, |
236 | { 'V', "verbose", NULL, | 239 | { 'v', "version", NULL, |
237 | gettext_noop("be verbose") }, | 240 | gettext_noop ("print the version number") }, |
238 | { 'x', "exclude", "TYPE", | 241 | { 'V', "verbose", NULL, |
239 | gettext_noop("do not print keywords of the given TYPE") }, | 242 | gettext_noop ("be verbose") }, |
240 | { 0, NULL, NULL, NULL }, | 243 | { 'x', "exclude", "TYPE", |
241 | }; | 244 | gettext_noop ("do not print keywords of the given TYPE") }, |
242 | format_help (_("extract [OPTIONS] [FILENAME]*"), | 245 | { 0, NULL, NULL, NULL }, |
243 | _("Extract metadata from files."), | 246 | }; |
244 | help); | 247 | format_help (_ ("extract [OPTIONS] [FILENAME]*"), |
248 | _ ("Extract metadata from files."), | ||
249 | help); | ||
245 | 250 | ||
246 | } | 251 | } |
247 | 252 | ||
253 | |||
248 | #if HAVE_ICONV | 254 | #if HAVE_ICONV |
249 | #include "iconv.c" | 255 | #include "iconv.c" |
250 | #endif | 256 | #endif |
@@ -267,12 +273,12 @@ print_help () | |||
267 | */ | 273 | */ |
268 | static int | 274 | static int |
269 | print_selected_keywords (void *cls, | 275 | print_selected_keywords (void *cls, |
270 | const char *plugin_name, | 276 | const char *plugin_name, |
271 | enum EXTRACTOR_MetaType type, | 277 | enum EXTRACTOR_MetaType type, |
272 | enum EXTRACTOR_MetaFormat format, | 278 | enum EXTRACTOR_MetaFormat format, |
273 | const char *data_mime_type, | 279 | const char *data_mime_type, |
274 | const char *data, | 280 | const char *data, |
275 | size_t data_len) | 281 | size_t data_len) |
276 | { | 282 | { |
277 | char *keyword; | 283 | char *keyword; |
278 | #if HAVE_ICONV | 284 | #if HAVE_ICONV |
@@ -285,59 +291,59 @@ print_selected_keywords (void *cls, | |||
285 | return 0; | 291 | return 0; |
286 | if (verbose > 3) | 292 | if (verbose > 3) |
287 | FPRINTF (stdout, | 293 | FPRINTF (stdout, |
288 | _("Found by `%s' plugin:\n"), | 294 | _ ("Found by `%s' plugin:\n"), |
289 | plugin_name); | 295 | plugin_name); |
290 | mt = EXTRACTOR_metatype_to_string (type); | 296 | mt = EXTRACTOR_metatype_to_string (type); |
291 | stype = (NULL == mt) ? _("unknown") : gettext(mt); | 297 | stype = (NULL == mt) ? _ ("unknown") : gettext (mt); |
292 | switch (format) | 298 | switch (format) |
293 | { | 299 | { |
294 | case EXTRACTOR_METAFORMAT_UNKNOWN: | 300 | case EXTRACTOR_METAFORMAT_UNKNOWN: |
295 | FPRINTF (stdout, | 301 | FPRINTF (stdout, |
296 | _("%s - (unknown, %u bytes)\n"), | 302 | _ ("%s - (unknown, %u bytes)\n"), |
297 | stype, | 303 | stype, |
298 | (unsigned int) data_len); | 304 | (unsigned int) data_len); |
305 | break; | ||
306 | case EXTRACTOR_METAFORMAT_UTF8: | ||
307 | if (0 == data_len) | ||
299 | break; | 308 | break; |
300 | case EXTRACTOR_METAFORMAT_UTF8: | ||
301 | if (0 == data_len) | ||
302 | break; | ||
303 | #if HAVE_ICONV | ||
304 | cd = iconv_open (nl_langinfo(CODESET), "UTF-8"); | ||
305 | if (((iconv_t) -1) != cd) | ||
306 | keyword = iconv_helper (cd, | ||
307 | data, | ||
308 | data_len); | ||
309 | else | ||
310 | #endif | ||
311 | keyword = strdup (data); | ||
312 | if (NULL != keyword) | ||
313 | { | ||
314 | FPRINTF (stdout, | ||
315 | "%s - %s\n", | ||
316 | stype, | ||
317 | keyword); | ||
318 | free (keyword); | ||
319 | } | ||
320 | #if HAVE_ICONV | 309 | #if HAVE_ICONV |
321 | if (((iconv_t) -1) != cd) | 310 | cd = iconv_open (nl_langinfo (CODESET), "UTF-8"); |
322 | iconv_close (cd); | 311 | if (((iconv_t) -1) != cd) |
312 | keyword = iconv_helper (cd, | ||
313 | data, | ||
314 | data_len); | ||
315 | else | ||
323 | #endif | 316 | #endif |
324 | break; | 317 | keyword = strdup (data); |
325 | case EXTRACTOR_METAFORMAT_BINARY: | 318 | if (NULL != keyword) |
326 | FPRINTF (stdout, | 319 | { |
327 | _("%s - (binary, %u bytes)\n"), | ||
328 | stype, | ||
329 | (unsigned int) data_len); | ||
330 | break; | ||
331 | case EXTRACTOR_METAFORMAT_C_STRING: | ||
332 | FPRINTF (stdout, | 320 | FPRINTF (stdout, |
333 | "%s - %.*s\n", | 321 | "%s - %s\n", |
334 | stype, | 322 | stype, |
335 | (int) data_len, | 323 | keyword); |
336 | data); | 324 | free (keyword); |
337 | break; | ||
338 | default: | ||
339 | break; | ||
340 | } | 325 | } |
326 | #if HAVE_ICONV | ||
327 | if (((iconv_t) -1) != cd) | ||
328 | iconv_close (cd); | ||
329 | #endif | ||
330 | break; | ||
331 | case EXTRACTOR_METAFORMAT_BINARY: | ||
332 | FPRINTF (stdout, | ||
333 | _ ("%s - (binary, %u bytes)\n"), | ||
334 | stype, | ||
335 | (unsigned int) data_len); | ||
336 | break; | ||
337 | case EXTRACTOR_METAFORMAT_C_STRING: | ||
338 | FPRINTF (stdout, | ||
339 | "%s - %.*s\n", | ||
340 | stype, | ||
341 | (int) data_len, | ||
342 | data); | ||
343 | break; | ||
344 | default: | ||
345 | break; | ||
346 | } | ||
341 | return 0; | 347 | return 0; |
342 | } | 348 | } |
343 | 349 | ||
@@ -360,12 +366,12 @@ print_selected_keywords (void *cls, | |||
360 | */ | 366 | */ |
361 | static int | 367 | static int |
362 | print_selected_keywords_grep_friendly (void *cls, | 368 | print_selected_keywords_grep_friendly (void *cls, |
363 | const char *plugin_name, | 369 | const char *plugin_name, |
364 | enum EXTRACTOR_MetaType type, | 370 | enum EXTRACTOR_MetaType type, |
365 | enum EXTRACTOR_MetaFormat format, | 371 | enum EXTRACTOR_MetaFormat format, |
366 | const char *data_mime_type, | 372 | const char *data_mime_type, |
367 | const char *data, | 373 | const char *data, |
368 | size_t data_len) | 374 | size_t data_len) |
369 | { | 375 | { |
370 | char *keyword; | 376 | char *keyword; |
371 | #if HAVE_ICONV | 377 | #if HAVE_ICONV |
@@ -379,51 +385,51 @@ print_selected_keywords_grep_friendly (void *cls, | |||
379 | if (NULL == mt) | 385 | if (NULL == mt) |
380 | mt = gettext_noop ("unknown"); | 386 | mt = gettext_noop ("unknown"); |
381 | switch (format) | 387 | switch (format) |
382 | { | 388 | { |
383 | case EXTRACTOR_METAFORMAT_UNKNOWN: | 389 | case EXTRACTOR_METAFORMAT_UNKNOWN: |
384 | break; | 390 | break; |
385 | case EXTRACTOR_METAFORMAT_UTF8: | 391 | case EXTRACTOR_METAFORMAT_UTF8: |
386 | if (0 == data_len) | 392 | if (0 == data_len) |
387 | return 0; | 393 | return 0; |
388 | if (verbose > 1) | 394 | if (verbose > 1) |
389 | FPRINTF (stdout, | 395 | FPRINTF (stdout, |
390 | "%s: ", | 396 | "%s: ", |
391 | gettext(mt)); | 397 | gettext (mt)); |
392 | #if HAVE_ICONV | 398 | #if HAVE_ICONV |
393 | cd = iconv_open (nl_langinfo (CODESET), "UTF-8"); | 399 | cd = iconv_open (nl_langinfo (CODESET), "UTF-8"); |
394 | if (((iconv_t) -1) != cd) | 400 | if (((iconv_t) -1) != cd) |
395 | keyword = iconv_helper (cd, | 401 | keyword = iconv_helper (cd, |
396 | data, | 402 | data, |
397 | data_len); | 403 | data_len); |
398 | else | 404 | else |
399 | #endif | 405 | #endif |
400 | keyword = strdup (data); | 406 | keyword = strdup (data); |
401 | if (NULL != keyword) | 407 | if (NULL != keyword) |
402 | { | 408 | { |
403 | FPRINTF (stdout, | 409 | FPRINTF (stdout, |
404 | "`%s' ", | 410 | "`%s' ", |
405 | keyword); | 411 | keyword); |
406 | free (keyword); | 412 | free (keyword); |
407 | } | 413 | } |
408 | #if HAVE_ICONV | 414 | #if HAVE_ICONV |
409 | if (((iconv_t) -1) != cd) | 415 | if (((iconv_t) -1) != cd) |
410 | iconv_close (cd); | 416 | iconv_close (cd); |
411 | #endif | 417 | #endif |
412 | break; | 418 | break; |
413 | case EXTRACTOR_METAFORMAT_BINARY: | 419 | case EXTRACTOR_METAFORMAT_BINARY: |
414 | break; | 420 | break; |
415 | case EXTRACTOR_METAFORMAT_C_STRING: | 421 | case EXTRACTOR_METAFORMAT_C_STRING: |
416 | if (verbose > 1) | 422 | if (verbose > 1) |
417 | FPRINTF (stdout, | ||
418 | "%s ", | ||
419 | gettext(mt)); | ||
420 | FPRINTF (stdout, | 423 | FPRINTF (stdout, |
421 | "`%s'", | 424 | "%s ", |
422 | data); | 425 | gettext (mt)); |
423 | break; | 426 | FPRINTF (stdout, |
424 | default: | 427 | "`%s'", |
425 | break; | 428 | data); |
426 | } | 429 | break; |
430 | default: | ||
431 | break; | ||
432 | } | ||
427 | return 0; | 433 | return 0; |
428 | } | 434 | } |
429 | 435 | ||
@@ -459,31 +465,30 @@ static char *entry_type; | |||
459 | * Mapping between bibTeX strings, libextractor | 465 | * Mapping between bibTeX strings, libextractor |
460 | * meta data types and values for the current document. | 466 | * meta data types and values for the current document. |
461 | */ | 467 | */ |
462 | static struct BibTexMap btm[] = | 468 | static struct BibTexMap btm[] = { |
463 | { | 469 | { "title", EXTRACTOR_METATYPE_TITLE, NULL}, |
464 | { "title", EXTRACTOR_METATYPE_TITLE, NULL}, | 470 | { "year", EXTRACTOR_METATYPE_PUBLICATION_YEAR, NULL }, |
465 | { "year", EXTRACTOR_METATYPE_PUBLICATION_YEAR, NULL }, | 471 | { "author", EXTRACTOR_METATYPE_AUTHOR_NAME, NULL }, |
466 | { "author", EXTRACTOR_METATYPE_AUTHOR_NAME, NULL }, | 472 | { "book", EXTRACTOR_METATYPE_BOOK_TITLE, NULL}, |
467 | { "book", EXTRACTOR_METATYPE_BOOK_TITLE, NULL}, | 473 | { "edition", EXTRACTOR_METATYPE_BOOK_EDITION, NULL}, |
468 | { "edition", EXTRACTOR_METATYPE_BOOK_EDITION, NULL}, | 474 | { "chapter", EXTRACTOR_METATYPE_BOOK_CHAPTER_NUMBER, NULL}, |
469 | { "chapter", EXTRACTOR_METATYPE_BOOK_CHAPTER_NUMBER, NULL}, | 475 | { "journal", EXTRACTOR_METATYPE_JOURNAL_NAME, NULL}, |
470 | { "journal", EXTRACTOR_METATYPE_JOURNAL_NAME, NULL}, | 476 | { "volume", EXTRACTOR_METATYPE_JOURNAL_VOLUME, NULL}, |
471 | { "volume", EXTRACTOR_METATYPE_JOURNAL_VOLUME, NULL}, | 477 | { "number", EXTRACTOR_METATYPE_JOURNAL_NUMBER, NULL}, |
472 | { "number", EXTRACTOR_METATYPE_JOURNAL_NUMBER, NULL}, | 478 | { "pages", EXTRACTOR_METATYPE_PAGE_COUNT, NULL }, |
473 | { "pages", EXTRACTOR_METATYPE_PAGE_COUNT, NULL }, | 479 | { "pages", EXTRACTOR_METATYPE_PAGE_RANGE, NULL }, |
474 | { "pages", EXTRACTOR_METATYPE_PAGE_RANGE, NULL }, | 480 | { "school", EXTRACTOR_METATYPE_AUTHOR_INSTITUTION, NULL}, |
475 | { "school", EXTRACTOR_METATYPE_AUTHOR_INSTITUTION, NULL}, | 481 | { "publisher", EXTRACTOR_METATYPE_PUBLISHER, NULL }, |
476 | { "publisher", EXTRACTOR_METATYPE_PUBLISHER, NULL }, | 482 | { "address", EXTRACTOR_METATYPE_PUBLISHER_ADDRESS, NULL }, |
477 | { "address", EXTRACTOR_METATYPE_PUBLISHER_ADDRESS, NULL }, | 483 | { "institution", EXTRACTOR_METATYPE_PUBLISHER_INSTITUTION, NULL }, |
478 | { "institution", EXTRACTOR_METATYPE_PUBLISHER_INSTITUTION, NULL }, | 484 | { "series", EXTRACTOR_METATYPE_PUBLISHER_SERIES, NULL}, |
479 | { "series", EXTRACTOR_METATYPE_PUBLISHER_SERIES, NULL}, | 485 | { "month", EXTRACTOR_METATYPE_PUBLICATION_MONTH, NULL }, |
480 | { "month", EXTRACTOR_METATYPE_PUBLICATION_MONTH, NULL }, | 486 | { "url", EXTRACTOR_METATYPE_URL, NULL}, |
481 | { "url", EXTRACTOR_METATYPE_URL, NULL}, | 487 | { "note", EXTRACTOR_METATYPE_COMMENT, NULL}, |
482 | { "note", EXTRACTOR_METATYPE_COMMENT, NULL}, | 488 | { "eprint", EXTRACTOR_METATYPE_BIBTEX_EPRINT, NULL }, |
483 | { "eprint", EXTRACTOR_METATYPE_BIBTEX_EPRINT, NULL }, | 489 | { "type", EXTRACTOR_METATYPE_PUBLICATION_TYPE, NULL }, |
484 | { "type", EXTRACTOR_METATYPE_PUBLICATION_TYPE, NULL }, | 490 | { NULL, 0, NULL } |
485 | { NULL, 0, NULL } | 491 | }; |
486 | }; | ||
487 | 492 | ||
488 | 493 | ||
489 | /** | 494 | /** |
@@ -495,10 +500,10 @@ cleanup_bibtex () | |||
495 | unsigned int i; | 500 | unsigned int i; |
496 | 501 | ||
497 | for (i = 0; NULL != btm[i].bibTexName; i++) | 502 | for (i = 0; NULL != btm[i].bibTexName; i++) |
498 | { | 503 | { |
499 | free (btm[i].value); | 504 | free (btm[i].value); |
500 | btm[i].value = NULL; | 505 | btm[i].value = NULL; |
501 | } | 506 | } |
502 | free (entry_type); | 507 | free (entry_type); |
503 | entry_type = NULL; | 508 | entry_type = NULL; |
504 | } | 509 | } |
@@ -522,12 +527,12 @@ cleanup_bibtex () | |||
522 | */ | 527 | */ |
523 | static int | 528 | static int |
524 | print_bibtex (void *cls, | 529 | print_bibtex (void *cls, |
525 | const char *plugin_name, | 530 | const char *plugin_name, |
526 | enum EXTRACTOR_MetaType type, | 531 | enum EXTRACTOR_MetaType type, |
527 | enum EXTRACTOR_MetaFormat format, | 532 | enum EXTRACTOR_MetaFormat format, |
528 | const char *data_mime_type, | 533 | const char *data_mime_type, |
529 | const char *data, | 534 | const char *data, |
530 | size_t data_len) | 535 | size_t data_len) |
531 | { | 536 | { |
532 | unsigned int i; | 537 | unsigned int i; |
533 | 538 | ||
@@ -538,13 +543,13 @@ print_bibtex (void *cls, | |||
538 | if (EXTRACTOR_METAFORMAT_UTF8 != format) | 543 | if (EXTRACTOR_METAFORMAT_UTF8 != format) |
539 | return 0; | 544 | return 0; |
540 | if (EXTRACTOR_METATYPE_BIBTEX_ENTRY_TYPE == type) | 545 | if (EXTRACTOR_METATYPE_BIBTEX_ENTRY_TYPE == type) |
541 | { | 546 | { |
542 | entry_type = strdup (data); | 547 | entry_type = strdup (data); |
543 | return 0; | 548 | return 0; |
544 | } | 549 | } |
545 | for (i = 0; NULL != btm[i].bibTexName; i++) | 550 | for (i = 0; NULL != btm[i].bibTexName; i++) |
546 | if ( (NULL == btm[i].value) && | 551 | if ( (NULL == btm[i].value) && |
547 | (btm[i].le_type == type) ) | 552 | (btm[i].le_type == type) ) |
548 | btm[i].value = strdup (data); | 553 | btm[i].value = strdup (data); |
549 | return 0; | 554 | return 0; |
550 | } | 555 | } |
@@ -571,33 +576,33 @@ finish_bibtex (const char *fn) | |||
571 | (NULL == btm[1].value) || | 576 | (NULL == btm[1].value) || |
572 | (NULL == btm[2].value) ) | 577 | (NULL == btm[2].value) ) |
573 | FPRINTF (stdout, | 578 | FPRINTF (stdout, |
574 | "@%s %s { ", | 579 | "@%s %s { ", |
575 | et, | 580 | et, |
576 | fn); | 581 | fn); |
577 | else | 582 | else |
578 | { | 583 | { |
579 | snprintf (temp, | 584 | snprintf (temp, |
580 | sizeof (temp), | 585 | sizeof (temp), |
581 | "%.5s%.5s%.5s", | 586 | "%.5s%.5s%.5s", |
582 | btm[2].value, | 587 | btm[2].value, |
583 | btm[1].value, | 588 | btm[1].value, |
584 | btm[0].value); | 589 | btm[0].value); |
585 | for (n=strlen (temp)-1;n>=0;n-- ) | 590 | for (n = strlen (temp) - 1; n>=0; n--) |
586 | if (! isalnum ( (unsigned char) temp[n]) ) | 591 | if (! isalnum ( (unsigned char) temp[n]) ) |
587 | temp[n] = '_'; | 592 | temp[n] = '_'; |
588 | else | 593 | else |
589 | temp[n] = tolower ( (unsigned char) temp[n]); | 594 | temp[n] = tolower ( (unsigned char) temp[n]); |
590 | FPRINTF (stdout, | 595 | FPRINTF (stdout, |
591 | "@%s %s { ", | 596 | "@%s %s { ", |
592 | et, | 597 | et, |
593 | temp); | 598 | temp); |
594 | } | 599 | } |
595 | for (i=0; NULL != btm[i].bibTexName; i++) | 600 | for (i = 0; NULL != btm[i].bibTexName; i++) |
596 | if (NULL != btm[i].value) | 601 | if (NULL != btm[i].value) |
597 | FPRINTF (stdout, | 602 | FPRINTF (stdout, |
598 | "\t%s = {%s},\n", | 603 | "\t%s = {%s},\n", |
599 | btm[i].bibTexName, | 604 | btm[i].bibTexName, |
600 | btm[i].value); | 605 | btm[i].value); |
601 | FPRINTF (stdout, "%s", "}\n\n"); | 606 | FPRINTF (stdout, "%s", "}\n\n"); |
602 | } | 607 | } |
603 | 608 | ||
@@ -612,7 +617,9 @@ _wchar_to_str (const wchar_t *wstr, char **retstr, UINT cp) | |||
612 | DWORD error; | 617 | DWORD error; |
613 | 618 | ||
614 | SetLastError (0); | 619 | SetLastError (0); |
615 | len = WideCharToMultiByte (cp, 0, wstr, -1, NULL, 0, NULL, (cp == CP_UTF8 || cp == CP_UTF7) ? NULL : &lossy); | 620 | len = WideCharToMultiByte (cp, 0, wstr, -1, NULL, 0, NULL, (cp == CP_UTF8 || |
621 | cp == CP_UTF7) ? | ||
622 | NULL : &lossy); | ||
616 | error = GetLastError (); | 623 | error = GetLastError (); |
617 | if (len <= 0) | 624 | if (len <= 0) |
618 | return -1; | 625 | return -1; |
@@ -620,7 +627,9 @@ _wchar_to_str (const wchar_t *wstr, char **retstr, UINT cp) | |||
620 | str = malloc (sizeof (char) * len); | 627 | str = malloc (sizeof (char) * len); |
621 | 628 | ||
622 | SetLastError (0); | 629 | SetLastError (0); |
623 | lenc = WideCharToMultiByte (cp, 0, wstr, -1, str, len, NULL, (cp == CP_UTF8 || cp == CP_UTF7) ? NULL : &lossy); | 630 | lenc = WideCharToMultiByte (cp, 0, wstr, -1, str, len, NULL, (cp == CP_UTF8 || |
631 | cp == CP_UTF7) ? | ||
632 | NULL : &lossy); | ||
624 | error = GetLastError (); | 633 | error = GetLastError (); |
625 | if (lenc != len) | 634 | if (lenc != len) |
626 | { | 635 | { |
@@ -632,6 +641,8 @@ _wchar_to_str (const wchar_t *wstr, char **retstr, UINT cp) | |||
632 | return 1; | 641 | return 1; |
633 | return 0; | 642 | return 0; |
634 | } | 643 | } |
644 | |||
645 | |||
635 | #endif | 646 | #endif |
636 | 647 | ||
637 | 648 | ||
@@ -711,10 +722,10 @@ _get_utf8_args (int argc, char *const *argv, int *u8argc, char ***u8argv) | |||
711 | 722 | ||
712 | *u8argv = _make_continuous_arg_copy (wargc, split_u8argv); | 723 | *u8argv = _make_continuous_arg_copy (wargc, split_u8argv); |
713 | if (NULL == *u8argv) | 724 | if (NULL == *u8argv) |
714 | { | 725 | { |
715 | free (split_u8argv); | 726 | free (split_u8argv); |
716 | return -1; | 727 | return -1; |
717 | } | 728 | } |
718 | *u8argc = wargc; | 729 | *u8argc = wargc; |
719 | 730 | ||
720 | for (i = 0; i < wargc; i++) | 731 | for (i = 0; i < wargc; i++) |
@@ -756,21 +767,21 @@ main (int argc, char *argv[]) | |||
756 | int utf8_argc; | 767 | int utf8_argc; |
757 | 768 | ||
758 | #if ENABLE_NLS | 769 | #if ENABLE_NLS |
759 | setlocale(LC_ALL, ""); | 770 | setlocale (LC_ALL, ""); |
760 | textdomain(PACKAGE); | 771 | textdomain (PACKAGE); |
761 | #endif | 772 | #endif |
762 | #ifndef WINDOWS | 773 | #ifndef WINDOWS |
763 | ignore_sigpipe (); | 774 | ignore_sigpipe (); |
764 | #endif | 775 | #endif |
765 | if (NULL == (print = malloc (sizeof (int) * EXTRACTOR_metatype_get_max ()))) | 776 | if (NULL == (print = malloc (sizeof (int) * EXTRACTOR_metatype_get_max ()))) |
766 | { | 777 | { |
767 | FPRINTF (stderr, | 778 | FPRINTF (stderr, |
768 | "malloc failed: %s\n", | 779 | "malloc failed: %s\n", |
769 | strerror (errno)); | 780 | strerror (errno)); |
770 | return 1; | 781 | return 1; |
771 | } | 782 | } |
772 | for (i = 0; i < EXTRACTOR_metatype_get_max (); i++) | 783 | for (i = 0; i < EXTRACTOR_metatype_get_max (); i++) |
773 | print[i] = YES; /* default: print everything */ | 784 | print[i] = YES; /* default: print everything */ |
774 | 785 | ||
775 | if (0 != _get_utf8_args (argc, argv, &utf8_argc, &utf8_argv)) | 786 | if (0 != _get_utf8_args (argc, argv, &utf8_argc, &utf8_argv)) |
776 | { | 787 | { |
@@ -779,249 +790,252 @@ main (int argc, char *argv[]) | |||
779 | } | 790 | } |
780 | 791 | ||
781 | while (1) | 792 | while (1) |
793 | { | ||
794 | static struct option long_options[] = { | ||
795 | {"bibtex", 0, 0, 'b'}, | ||
796 | {"grep-friendly", 0, 0, 'g'}, | ||
797 | {"help", 0, 0, 'h'}, | ||
798 | {"in-process", 0, 0, 'i'}, | ||
799 | {"from-memory", 0, 0, 'm'}, | ||
800 | {"list", 0, 0, 'L'}, | ||
801 | {"library", 1, 0, 'l'}, | ||
802 | {"nodefault", 0, 0, 'n'}, | ||
803 | {"print", 1, 0, 'p'}, | ||
804 | {"verbose", 0, 0, 'V'}, | ||
805 | {"version", 0, 0, 'v'}, | ||
806 | {"exclude", 1, 0, 'x'}, | ||
807 | {0, 0, 0, 0} | ||
808 | }; | ||
809 | option_index = 0; | ||
810 | c = getopt_long (utf8_argc, | ||
811 | utf8_argv, | ||
812 | "abghiml:Lnp:vVx:", | ||
813 | long_options, | ||
814 | &option_index); | ||
815 | |||
816 | if (c == -1) | ||
817 | break; /* No more flags to process */ | ||
818 | switch (c) | ||
782 | { | 819 | { |
783 | static struct option long_options[] = { | 820 | case 'b': |
784 | {"bibtex", 0, 0, 'b'}, | 821 | bibtex = YES; |
785 | {"grep-friendly", 0, 0, 'g'}, | 822 | if (NULL != processor) |
786 | {"help", 0, 0, 'h'}, | 823 | { |
787 | {"in-process", 0, 0, 'i'}, | 824 | FPRINTF (stderr, |
788 | {"from-memory", 0, 0, 'm'}, | 825 | "%s", |
789 | {"list", 0, 0, 'L'}, | 826 | _ ( |
790 | {"library", 1, 0, 'l'}, | 827 | "Illegal combination of options, cannot combine multiple styles of printing.\n")); |
791 | {"nodefault", 0, 0, 'n'}, | 828 | free (utf8_argv); |
792 | {"print", 1, 0, 'p'}, | 829 | return 0; |
793 | {"verbose", 0, 0, 'V'}, | 830 | } |
794 | {"version", 0, 0, 'v'}, | 831 | processor = &print_bibtex; |
795 | {"exclude", 1, 0, 'x'}, | 832 | break; |
796 | {0, 0, 0, 0} | 833 | case 'g': |
797 | }; | 834 | grepfriendly = YES; |
798 | option_index = 0; | 835 | if (NULL != processor) |
799 | c = getopt_long (utf8_argc, | 836 | { |
800 | utf8_argv, | 837 | FPRINTF (stderr, |
801 | "abghiml:Lnp:vVx:", | 838 | "%s", |
802 | long_options, | 839 | _ ( |
803 | &option_index); | 840 | "Illegal combination of options, cannot combine multiple styles of printing.\n")); |
804 | 841 | free (utf8_argv); | |
805 | if (c == -1) | 842 | return 0; |
806 | break; /* No more flags to process */ | 843 | } |
807 | switch (c) | 844 | processor = &print_selected_keywords_grep_friendly; |
808 | { | 845 | break; |
809 | case 'b': | 846 | case 'h': |
810 | bibtex = YES; | 847 | print_help (); |
811 | if (NULL != processor) | 848 | free (utf8_argv); |
812 | { | 849 | return 0; |
813 | FPRINTF (stderr, | 850 | case 'i': |
814 | "%s", | 851 | in_process = YES; |
815 | _("Illegal combination of options, cannot combine multiple styles of printing.\n")); | 852 | break; |
816 | free (utf8_argv); | 853 | case 'm': |
817 | return 0; | 854 | from_memory = YES; |
818 | } | 855 | break; |
819 | processor = &print_bibtex; | 856 | case 'l': |
820 | break; | 857 | libraries = optarg; |
821 | case 'g': | 858 | break; |
822 | grepfriendly = YES; | 859 | case 'L': |
823 | if (NULL != processor) | 860 | i = 0; |
824 | { | 861 | while (NULL != EXTRACTOR_metatype_to_string (i)) |
825 | FPRINTF (stderr, | 862 | printf ("%s\n", |
826 | "%s", | 863 | gettext (EXTRACTOR_metatype_to_string (i++))); |
827 | _("Illegal combination of options, cannot combine multiple styles of printing.\n")); | 864 | free (utf8_argv); |
828 | free (utf8_argv); | 865 | return 0; |
829 | return 0; | 866 | case 'n': |
830 | } | 867 | nodefault = YES; |
831 | processor = &print_selected_keywords_grep_friendly; | 868 | break; |
832 | break; | 869 | case 'p': |
833 | case 'h': | 870 | if (NULL == optarg) |
834 | print_help (); | 871 | { |
835 | free (utf8_argv); | 872 | FPRINTF (stderr, |
836 | return 0; | 873 | _ ( |
837 | case 'i': | 874 | "You must specify an argument for the `%s' option (option ignored).\n"), |
838 | in_process = YES; | 875 | "-p"); |
839 | break; | 876 | break; |
840 | case 'm': | 877 | } |
841 | from_memory = YES; | 878 | if (YES == defaultAll) |
879 | { | ||
880 | defaultAll = NO; | ||
881 | i = 0; | ||
882 | while (NULL != EXTRACTOR_metatype_to_string (i)) | ||
883 | print[i++] = NO; | ||
884 | } | ||
885 | i = 0; | ||
886 | while (NULL != EXTRACTOR_metatype_to_string (i)) | ||
887 | { | ||
888 | if ( (0 == strcmp (optarg, | ||
889 | EXTRACTOR_metatype_to_string (i))) || | ||
890 | (0 == strcmp (optarg, | ||
891 | gettext (EXTRACTOR_metatype_to_string (i)))) ) | ||
892 | |||
893 | { | ||
894 | print[i] = YES; | ||
842 | break; | 895 | break; |
843 | case 'l': | 896 | } |
844 | libraries = optarg; | 897 | i++; |
845 | break; | 898 | } |
846 | case 'L': | 899 | if (NULL == EXTRACTOR_metatype_to_string (i)) |
847 | i = 0; | 900 | { |
848 | while (NULL != EXTRACTOR_metatype_to_string (i)) | 901 | FPRINTF (stderr, |
849 | printf ("%s\n", | 902 | "Unknown keyword type `%s', use option `%s' to get a list.\n", |
850 | gettext(EXTRACTOR_metatype_to_string (i++))); | 903 | optarg, |
851 | free (utf8_argv); | 904 | "-L"); |
852 | return 0; | 905 | free (utf8_argv); |
853 | case 'n': | 906 | return -1; |
854 | nodefault = YES; | 907 | } |
855 | break; | 908 | break; |
856 | case 'p': | 909 | case 'v': |
857 | if (NULL == optarg) | 910 | printf ("extract v%s\n", PACKAGE_VERSION); |
858 | { | ||
859 | FPRINTF(stderr, | ||
860 | _("You must specify an argument for the `%s' option (option ignored).\n"), | ||
861 | "-p"); | ||
862 | break; | ||
863 | } | ||
864 | if (YES == defaultAll) | ||
865 | { | ||
866 | defaultAll = NO; | ||
867 | i = 0; | ||
868 | while (NULL != EXTRACTOR_metatype_to_string (i)) | ||
869 | print[i++] = NO; | ||
870 | } | ||
871 | i = 0; | ||
872 | while (NULL != EXTRACTOR_metatype_to_string (i)) | ||
873 | { | ||
874 | if ( (0 == strcmp (optarg, | ||
875 | EXTRACTOR_metatype_to_string (i))) || | ||
876 | (0 == strcmp (optarg, | ||
877 | gettext(EXTRACTOR_metatype_to_string (i)))) ) | ||
878 | |||
879 | { | ||
880 | print[i] = YES; | ||
881 | break; | ||
882 | } | ||
883 | i++; | ||
884 | } | ||
885 | if (NULL == EXTRACTOR_metatype_to_string (i)) | ||
886 | { | ||
887 | FPRINTF(stderr, | ||
888 | "Unknown keyword type `%s', use option `%s' to get a list.\n", | ||
889 | optarg, | ||
890 | "-L"); | ||
891 | free (utf8_argv); | ||
892 | return -1; | ||
893 | } | ||
894 | break; | ||
895 | case 'v': | ||
896 | printf ("extract v%s\n", PACKAGE_VERSION); | ||
897 | free (utf8_argv); | ||
898 | return 0; | ||
899 | case 'V': | ||
900 | verbose++; | ||
901 | break; | ||
902 | case 'x': | ||
903 | i = 0; | ||
904 | while (NULL != EXTRACTOR_metatype_to_string (i)) | ||
905 | { | ||
906 | if ( (0 == strcmp (optarg, | ||
907 | EXTRACTOR_metatype_to_string (i))) || | ||
908 | (0 == strcmp (optarg, | ||
909 | gettext(EXTRACTOR_metatype_to_string (i)))) ) | ||
910 | { | ||
911 | print[i] = NO; | ||
912 | break; | ||
913 | } | ||
914 | i++; | ||
915 | } | ||
916 | if (NULL == EXTRACTOR_metatype_to_string (i)) | ||
917 | { | ||
918 | FPRINTF (stderr, | ||
919 | "Unknown keyword type `%s', use option `%s' to get a list.\n", | ||
920 | optarg, | ||
921 | "-L"); | ||
922 | free (utf8_argv); | ||
923 | return -1; | ||
924 | } | ||
925 | break; | ||
926 | default: | ||
927 | FPRINTF (stderr, | ||
928 | "%s", | ||
929 | _("Use --help to get a list of options.\n")); | ||
930 | free (utf8_argv); | ||
931 | return -1; | ||
932 | } /* end of parsing commandline */ | ||
933 | } /* while (1) */ | ||
934 | if (optind < 0) | ||
935 | { | ||
936 | FPRINTF (stderr, | ||
937 | "%s", "Unknown error parsing options\n"); | ||
938 | free (print); | ||
939 | free (utf8_argv); | 911 | free (utf8_argv); |
940 | return -1; | 912 | return 0; |
941 | } | 913 | case 'V': |
942 | if (utf8_argc - optind < 1) | 914 | verbose++; |
943 | { | 915 | break; |
916 | case 'x': | ||
917 | i = 0; | ||
918 | while (NULL != EXTRACTOR_metatype_to_string (i)) | ||
919 | { | ||
920 | if ( (0 == strcmp (optarg, | ||
921 | EXTRACTOR_metatype_to_string (i))) || | ||
922 | (0 == strcmp (optarg, | ||
923 | gettext (EXTRACTOR_metatype_to_string (i)))) ) | ||
924 | { | ||
925 | print[i] = NO; | ||
926 | break; | ||
927 | } | ||
928 | i++; | ||
929 | } | ||
930 | if (NULL == EXTRACTOR_metatype_to_string (i)) | ||
931 | { | ||
932 | FPRINTF (stderr, | ||
933 | "Unknown keyword type `%s', use option `%s' to get a list.\n", | ||
934 | optarg, | ||
935 | "-L"); | ||
936 | free (utf8_argv); | ||
937 | return -1; | ||
938 | } | ||
939 | break; | ||
940 | default: | ||
944 | FPRINTF (stderr, | 941 | FPRINTF (stderr, |
945 | "%s", "Invoke with list of filenames to extract keywords form!\n"); | 942 | "%s", |
946 | free (print); | 943 | _ ("Use --help to get a list of options.\n")); |
947 | free (utf8_argv); | 944 | free (utf8_argv); |
948 | return -1; | 945 | return -1; |
949 | } | 946 | } /* end of parsing commandline */ |
947 | } /* while (1) */ | ||
948 | if (optind < 0) | ||
949 | { | ||
950 | FPRINTF (stderr, | ||
951 | "%s", "Unknown error parsing options\n"); | ||
952 | free (print); | ||
953 | free (utf8_argv); | ||
954 | return -1; | ||
955 | } | ||
956 | if (utf8_argc - optind < 1) | ||
957 | { | ||
958 | FPRINTF (stderr, | ||
959 | "%s", "Invoke with list of filenames to extract keywords form!\n"); | ||
960 | free (print); | ||
961 | free (utf8_argv); | ||
962 | return -1; | ||
963 | } | ||
950 | 964 | ||
951 | /* build list of libraries */ | 965 | /* build list of libraries */ |
952 | if (NO == nodefault) | 966 | if (NO == nodefault) |
953 | plugins = EXTRACTOR_plugin_add_defaults (in_process | 967 | plugins = EXTRACTOR_plugin_add_defaults (in_process |
954 | ? EXTRACTOR_OPTION_IN_PROCESS | 968 | ? EXTRACTOR_OPTION_IN_PROCESS |
955 | : EXTRACTOR_OPTION_DEFAULT_POLICY); | 969 | : EXTRACTOR_OPTION_DEFAULT_POLICY); |
956 | else | 970 | else |
957 | plugins = NULL; | 971 | plugins = NULL; |
958 | if (NULL != libraries) | 972 | if (NULL != libraries) |
959 | plugins = EXTRACTOR_plugin_add_config (plugins, | 973 | plugins = EXTRACTOR_plugin_add_config (plugins, |
960 | libraries, | 974 | libraries, |
961 | in_process | 975 | in_process |
962 | ? EXTRACTOR_OPTION_IN_PROCESS | 976 | ? EXTRACTOR_OPTION_IN_PROCESS |
963 | : EXTRACTOR_OPTION_DEFAULT_POLICY); | 977 | : EXTRACTOR_OPTION_DEFAULT_POLICY); |
964 | if (NULL == processor) | 978 | if (NULL == processor) |
965 | processor = &print_selected_keywords; | 979 | processor = &print_selected_keywords; |
966 | 980 | ||
967 | /* extract keywords */ | 981 | /* extract keywords */ |
968 | if (YES == bibtex) | 982 | if (YES == bibtex) |
969 | FPRINTF(stdout, | 983 | FPRINTF (stdout, |
970 | "%s", _("% BiBTeX file\n")); | 984 | "%s", _ ("% BiBTeX file\n")); |
971 | for (i = optind; i < utf8_argc; i++) | 985 | for (i = optind; i < utf8_argc; i++) |
986 | { | ||
987 | errno = 0; | ||
988 | if (YES == grepfriendly) | ||
989 | FPRINTF (stdout, "%s ", utf8_argv[i]); | ||
990 | else if (NO == bibtex) | ||
991 | FPRINTF (stdout, | ||
992 | _ ("Keywords for file %s:\n"), | ||
993 | utf8_argv[i]); | ||
994 | else | ||
995 | cleanup_bibtex (); | ||
996 | if (NO == from_memory) | ||
997 | EXTRACTOR_extract (plugins, | ||
998 | utf8_argv[i], | ||
999 | NULL, 0, | ||
1000 | processor, | ||
1001 | NULL); | ||
1002 | else | ||
972 | { | 1003 | { |
973 | errno = 0; | 1004 | struct stat sb; |
974 | if (YES == grepfriendly) | 1005 | unsigned char *data = NULL; |
975 | FPRINTF (stdout, "%s ", utf8_argv[i]); | 1006 | int f = OPEN (utf8_argv[i], O_RDONLY |
976 | else if (NO == bibtex) | ||
977 | FPRINTF (stdout, | ||
978 | _("Keywords for file %s:\n"), | ||
979 | utf8_argv[i]); | ||
980 | else | ||
981 | cleanup_bibtex (); | ||
982 | if (NO == from_memory) | ||
983 | EXTRACTOR_extract (plugins, | ||
984 | utf8_argv[i], | ||
985 | NULL, 0, | ||
986 | processor, | ||
987 | NULL); | ||
988 | else | ||
989 | { | ||
990 | struct stat sb; | ||
991 | unsigned char *data = NULL; | ||
992 | int f = OPEN (utf8_argv[i], O_RDONLY | ||
993 | #if WINDOWS | 1007 | #if WINDOWS |
994 | | O_BINARY | 1008 | | O_BINARY |
995 | #endif | 1009 | #endif |
996 | ); | 1010 | ); |
997 | if ( (-1 != f) && | 1011 | if ( (-1 != f) && |
998 | (0 == FSTAT (f, &sb)) && | 1012 | (0 == FSTAT (f, &sb)) && |
999 | (NULL != (data = malloc ((size_t) sb.st_size))) && | 1013 | (NULL != (data = malloc ((size_t) sb.st_size))) && |
1000 | (sb.st_size == READ (f, data, (size_t) sb.st_size) ) ) | 1014 | (sb.st_size == READ (f, data, (size_t) sb.st_size) ) ) |
1001 | { | 1015 | { |
1002 | EXTRACTOR_extract (plugins, | 1016 | EXTRACTOR_extract (plugins, |
1003 | NULL, | 1017 | NULL, |
1004 | data, sb.st_size, | 1018 | data, sb.st_size, |
1005 | processor, | 1019 | processor, |
1006 | NULL); | 1020 | NULL); |
1007 | } | 1021 | } |
1008 | else | 1022 | else |
1009 | { | 1023 | { |
1010 | if (verbose > 0) | 1024 | if (verbose > 0) |
1011 | FPRINTF(stderr, | 1025 | FPRINTF (stderr, |
1012 | "%s: %s: %s\n", | 1026 | "%s: %s: %s\n", |
1013 | utf8_argv[0], utf8_argv[i], strerror(errno)); | 1027 | utf8_argv[0], utf8_argv[i], strerror (errno)); |
1014 | ret = 1; | 1028 | ret = 1; |
1015 | } | 1029 | } |
1016 | if (NULL != data) | 1030 | if (NULL != data) |
1017 | free (data); | 1031 | free (data); |
1018 | if (-1 != f) | 1032 | if (-1 != f) |
1019 | (void) CLOSE (f); | 1033 | (void) CLOSE (f); |
1020 | } | ||
1021 | if (YES == grepfriendly) | ||
1022 | FPRINTF (stdout, "%s", "\n"); | ||
1023 | continue; | ||
1024 | } | 1034 | } |
1035 | if (YES == grepfriendly) | ||
1036 | FPRINTF (stdout, "%s", "\n"); | ||
1037 | continue; | ||
1038 | } | ||
1025 | if (YES == grepfriendly) | 1039 | if (YES == grepfriendly) |
1026 | FPRINTF (stdout, "%s", "\n"); | 1040 | FPRINTF (stdout, "%s", "\n"); |
1027 | if (bibtex) | 1041 | if (bibtex) |
@@ -1036,4 +1050,5 @@ main (int argc, char *argv[]) | |||
1036 | return ret; | 1050 | return ret; |
1037 | } | 1051 | } |
1038 | 1052 | ||
1053 | |||
1039 | /* end of extract.c */ | 1054 | /* end of extract.c */ |
diff --git a/src/main/extractor.c b/src/main/extractor.c index 3755da9..cb64b95 100644 --- a/src/main/extractor.c +++ b/src/main/extractor.c | |||
@@ -71,9 +71,9 @@ struct PluginReplyProcessor | |||
71 | */ | 71 | */ |
72 | static void | 72 | static void |
73 | send_update_message (struct EXTRACTOR_PluginList *plugin, | 73 | send_update_message (struct EXTRACTOR_PluginList *plugin, |
74 | int64_t shm_off, | 74 | int64_t shm_off, |
75 | size_t data_available, | 75 | size_t data_available, |
76 | struct EXTRACTOR_Datasource *ds) | 76 | struct EXTRACTOR_Datasource *ds) |
77 | { | 77 | { |
78 | struct UpdateMessage um; | 78 | struct UpdateMessage um; |
79 | 79 | ||
@@ -85,14 +85,14 @@ send_update_message (struct EXTRACTOR_PluginList *plugin, | |||
85 | um.file_size = EXTRACTOR_datasource_get_size_ (ds, 0); | 85 | um.file_size = EXTRACTOR_datasource_get_size_ (ds, 0); |
86 | if (sizeof (um) != | 86 | if (sizeof (um) != |
87 | EXTRACTOR_IPC_channel_send_ (plugin->channel, | 87 | EXTRACTOR_IPC_channel_send_ (plugin->channel, |
88 | &um, | 88 | &um, |
89 | sizeof (um)) ) | 89 | sizeof (um)) ) |
90 | { | 90 | { |
91 | LOG ("Failed to send UPDATED_SHM message to plugin\n"); | 91 | LOG ("Failed to send UPDATED_SHM message to plugin\n"); |
92 | EXTRACTOR_IPC_channel_destroy_ (plugin->channel); | 92 | EXTRACTOR_IPC_channel_destroy_ (plugin->channel); |
93 | plugin->channel = NULL; | 93 | plugin->channel = NULL; |
94 | plugin->round_finished = 1; | 94 | plugin->round_finished = 1; |
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
98 | 98 | ||
@@ -109,14 +109,14 @@ send_discard_message (struct EXTRACTOR_PluginList *plugin) | |||
109 | 109 | ||
110 | if (sizeof (disc_msg) != | 110 | if (sizeof (disc_msg) != |
111 | EXTRACTOR_IPC_channel_send_ (plugin->channel, | 111 | EXTRACTOR_IPC_channel_send_ (plugin->channel, |
112 | &disc_msg, | 112 | &disc_msg, |
113 | sizeof (disc_msg)) ) | 113 | sizeof (disc_msg)) ) |
114 | { | 114 | { |
115 | LOG ("Failed to send DISCARD_STATE message to plugin\n"); | 115 | LOG ("Failed to send DISCARD_STATE message to plugin\n"); |
116 | EXTRACTOR_IPC_channel_destroy_ (plugin->channel); | 116 | EXTRACTOR_IPC_channel_destroy_ (plugin->channel); |
117 | plugin->channel = NULL; | 117 | plugin->channel = NULL; |
118 | plugin->round_finished = 1; | 118 | plugin->round_finished = 1; |
119 | } | 119 | } |
120 | } | 120 | } |
121 | 121 | ||
122 | 122 | ||
@@ -131,12 +131,12 @@ abort_all_channels (struct EXTRACTOR_PluginList *plugins) | |||
131 | struct EXTRACTOR_PluginList *pos; | 131 | struct EXTRACTOR_PluginList *pos; |
132 | 132 | ||
133 | for (pos = plugins; NULL != pos; pos = pos->next) | 133 | for (pos = plugins; NULL != pos; pos = pos->next) |
134 | { | 134 | { |
135 | if (NULL == pos->channel) | 135 | if (NULL == pos->channel) |
136 | continue; | 136 | continue; |
137 | EXTRACTOR_IPC_channel_destroy_ (pos->channel); | 137 | EXTRACTOR_IPC_channel_destroy_ (pos->channel); |
138 | pos->channel = NULL; | 138 | pos->channel = NULL; |
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | 142 | ||
@@ -153,46 +153,46 @@ abort_all_channels (struct EXTRACTOR_PluginList *plugins) | |||
153 | */ | 153 | */ |
154 | static void | 154 | static void |
155 | process_plugin_reply (void *cls, | 155 | process_plugin_reply (void *cls, |
156 | struct EXTRACTOR_PluginList *plugin, | 156 | struct EXTRACTOR_PluginList *plugin, |
157 | enum EXTRACTOR_MetaType meta_type, | 157 | enum EXTRACTOR_MetaType meta_type, |
158 | enum EXTRACTOR_MetaFormat meta_format, | 158 | enum EXTRACTOR_MetaFormat meta_format, |
159 | const char *mime, | 159 | const char *mime, |
160 | const void *value, | 160 | const void *value, |
161 | size_t value_len) | 161 | size_t value_len) |
162 | { | 162 | { |
163 | static unsigned char cont_msg = MESSAGE_CONTINUE_EXTRACTING; | 163 | static unsigned char cont_msg = MESSAGE_CONTINUE_EXTRACTING; |
164 | struct PluginReplyProcessor *prp = cls; | 164 | struct PluginReplyProcessor *prp = cls; |
165 | 165 | ||
166 | if (0 != prp->file_finished) | 166 | if (0 != prp->file_finished) |
167 | { | 167 | { |
168 | /* client already aborted, ignore message, tell plugin about abort */ | 168 | /* client already aborted, ignore message, tell plugin about abort */ |
169 | return; | 169 | return; |
170 | } | 170 | } |
171 | if (0 != prp->proc (prp->proc_cls, | 171 | if (0 != prp->proc (prp->proc_cls, |
172 | plugin->short_libname, | 172 | plugin->short_libname, |
173 | meta_type, | 173 | meta_type, |
174 | meta_format, | 174 | meta_format, |
175 | mime, | 175 | mime, |
176 | value, | 176 | value, |
177 | value_len)) | 177 | value_len)) |
178 | { | 178 | { |
179 | prp->file_finished = 1; | 179 | prp->file_finished = 1; |
180 | #if DEBUG | 180 | #if DEBUG |
181 | fprintf (stderr, "Sending ABRT\n"); | 181 | fprintf (stderr, "Sending ABRT\n"); |
182 | #endif | 182 | #endif |
183 | send_discard_message (plugin); | 183 | send_discard_message (plugin); |
184 | return; | 184 | return; |
185 | } | 185 | } |
186 | if (sizeof (cont_msg) != | 186 | if (sizeof (cont_msg) != |
187 | EXTRACTOR_IPC_channel_send_ (plugin->channel, | 187 | EXTRACTOR_IPC_channel_send_ (plugin->channel, |
188 | &cont_msg, | 188 | &cont_msg, |
189 | sizeof (cont_msg)) ) | 189 | sizeof (cont_msg)) ) |
190 | { | 190 | { |
191 | LOG ("Failed to send CONTINUE_EXTRACTING message to plugin\n"); | 191 | LOG ("Failed to send CONTINUE_EXTRACTING message to plugin\n"); |
192 | EXTRACTOR_IPC_channel_destroy_ (plugin->channel); | 192 | EXTRACTOR_IPC_channel_destroy_ (plugin->channel); |
193 | plugin->channel = NULL; | 193 | plugin->channel = NULL; |
194 | plugin->round_finished = 1; | 194 | plugin->round_finished = 1; |
195 | } | 195 | } |
196 | } | 196 | } |
197 | 197 | ||
198 | 198 | ||
@@ -245,8 +245,8 @@ struct InProcessContext | |||
245 | */ | 245 | */ |
246 | static ssize_t | 246 | static ssize_t |
247 | in_process_read (void *cls, | 247 | in_process_read (void *cls, |
248 | void **data, | 248 | void **data, |
249 | size_t size) | 249 | size_t size) |
250 | { | 250 | { |
251 | struct InProcessContext *ctx = cls; | 251 | struct InProcessContext *ctx = cls; |
252 | ssize_t ret; | 252 | ssize_t ret; |
@@ -256,8 +256,8 @@ in_process_read (void *cls, | |||
256 | if (size < bsize) | 256 | if (size < bsize) |
257 | bsize = size; | 257 | bsize = size; |
258 | ret = EXTRACTOR_datasource_read_ (ctx->ds, | 258 | ret = EXTRACTOR_datasource_read_ (ctx->ds, |
259 | ctx->buf, | 259 | ctx->buf, |
260 | bsize); | 260 | bsize); |
261 | if (-1 == ret) | 261 | if (-1 == ret) |
262 | *data = NULL; | 262 | *data = NULL; |
263 | else | 263 | else |
@@ -279,14 +279,14 @@ in_process_read (void *cls, | |||
279 | */ | 279 | */ |
280 | static int64_t | 280 | static int64_t |
281 | in_process_seek (void *cls, | 281 | in_process_seek (void *cls, |
282 | int64_t pos, | 282 | int64_t pos, |
283 | int whence) | 283 | int whence) |
284 | { | 284 | { |
285 | struct InProcessContext *ctx = cls; | 285 | struct InProcessContext *ctx = cls; |
286 | 286 | ||
287 | return EXTRACTOR_datasource_seek_ (ctx->ds, | 287 | return EXTRACTOR_datasource_seek_ (ctx->ds, |
288 | pos, | 288 | pos, |
289 | whence); | 289 | whence); |
290 | } | 290 | } |
291 | 291 | ||
292 | 292 | ||
@@ -326,12 +326,12 @@ in_process_get_size (void *cls) | |||
326 | */ | 326 | */ |
327 | static int | 327 | static int |
328 | in_process_proc (void *cls, | 328 | in_process_proc (void *cls, |
329 | const char *plugin_name, | 329 | const char *plugin_name, |
330 | enum EXTRACTOR_MetaType type, | 330 | enum EXTRACTOR_MetaType type, |
331 | enum EXTRACTOR_MetaFormat format, | 331 | enum EXTRACTOR_MetaFormat format, |
332 | const char *data_mime_type, | 332 | const char *data_mime_type, |
333 | const char *data, | 333 | const char *data, |
334 | size_t data_len) | 334 | size_t data_len) |
335 | { | 335 | { |
336 | struct InProcessContext *ctx = cls; | 336 | struct InProcessContext *ctx = cls; |
337 | int ret; | 337 | int ret; |
@@ -339,12 +339,12 @@ in_process_proc (void *cls, | |||
339 | if (0 != ctx->finished) | 339 | if (0 != ctx->finished) |
340 | return 1; | 340 | return 1; |
341 | ret = ctx->proc (ctx->proc_cls, | 341 | ret = ctx->proc (ctx->proc_cls, |
342 | plugin_name, | 342 | plugin_name, |
343 | type, | 343 | type, |
344 | format, | 344 | format, |
345 | data_mime_type, | 345 | data_mime_type, |
346 | data, | 346 | data, |
347 | data_len); | 347 | data_len); |
348 | if (0 != ret) | 348 | if (0 != ret) |
349 | ctx->finished = 1; | 349 | ctx->finished = 1; |
350 | return ret; | 350 | return ret; |
@@ -363,9 +363,9 @@ in_process_proc (void *cls, | |||
363 | */ | 363 | */ |
364 | static void | 364 | static void |
365 | do_extract (struct EXTRACTOR_PluginList *plugins, | 365 | do_extract (struct EXTRACTOR_PluginList *plugins, |
366 | struct EXTRACTOR_SharedMemory *shm, | 366 | struct EXTRACTOR_SharedMemory *shm, |
367 | struct EXTRACTOR_Datasource *ds, | 367 | struct EXTRACTOR_Datasource *ds, |
368 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) | 368 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) |
369 | { | 369 | { |
370 | unsigned int plugin_count; | 370 | unsigned int plugin_count; |
371 | unsigned int plugin_off; | 371 | unsigned int plugin_off; |
@@ -406,153 +406,153 @@ do_extract (struct EXTRACTOR_PluginList *plugins, | |||
406 | start.shm_ready_bytes = (uint32_t) ready; | 406 | start.shm_ready_bytes = (uint32_t) ready; |
407 | start.file_size = EXTRACTOR_datasource_get_size_ (ds, 0); | 407 | start.file_size = EXTRACTOR_datasource_get_size_ (ds, 0); |
408 | for (pos = plugins; NULL != pos; pos = pos->next) | 408 | for (pos = plugins; NULL != pos; pos = pos->next) |
409 | { | ||
410 | if (EXTRACTOR_OPTION_IN_PROCESS == pos->flags) | ||
411 | have_in_memory = 1; | ||
412 | if ( (NULL != pos->channel) && | ||
413 | (-1 == EXTRACTOR_IPC_channel_send_ (pos->channel, | ||
414 | &start, | ||
415 | sizeof (start)) ) ) | ||
409 | { | 416 | { |
410 | if (EXTRACTOR_OPTION_IN_PROCESS == pos->flags) | 417 | LOG ("Failed to send EXTRACT_START message to plugin\n"); |
411 | have_in_memory = 1; | 418 | EXTRACTOR_IPC_channel_destroy_ (pos->channel); |
412 | if ( (NULL != pos->channel) && | 419 | pos->channel = NULL; |
413 | (-1 == EXTRACTOR_IPC_channel_send_ (pos->channel, | ||
414 | &start, | ||
415 | sizeof (start)) ) ) | ||
416 | { | ||
417 | LOG ("Failed to send EXTRACT_START message to plugin\n"); | ||
418 | EXTRACTOR_IPC_channel_destroy_ (pos->channel); | ||
419 | pos->channel = NULL; | ||
420 | } | ||
421 | } | 420 | } |
421 | } | ||
422 | if (-1 == ready) | 422 | if (-1 == ready) |
423 | { | 423 | { |
424 | LOG ("Failed to initialize IPC shared memory, cannot extract\n"); | 424 | LOG ("Failed to initialize IPC shared memory, cannot extract\n"); |
425 | done = 1; | 425 | done = 1; |
426 | } | 426 | } |
427 | else | 427 | else |
428 | done = 0; | 428 | done = 0; |
429 | while (! done) | 429 | while (! done) |
430 | { | ||
431 | struct EXTRACTOR_Channel *channels[plugin_count]; | ||
432 | |||
433 | /* calculate current 'channels' array */ | ||
434 | plugin_off = 0; | ||
435 | for (pos = plugins; NULL != pos; pos = pos->next) | ||
430 | { | 436 | { |
431 | struct EXTRACTOR_Channel *channels[plugin_count]; | 437 | if (-1 == pos->seek_request) |
432 | 438 | { | |
433 | /* calculate current 'channels' array */ | 439 | /* channel is not seeking, must be running or done */ |
434 | plugin_off = 0; | 440 | channels[plugin_off] = pos->channel; |
435 | for (pos = plugins; NULL != pos; pos = pos->next) | 441 | } |
436 | { | 442 | else |
437 | if (-1 == pos->seek_request) | 443 | { |
438 | { | 444 | /* not running this round, seeking! */ |
439 | /* channel is not seeking, must be running or done */ | 445 | channels[plugin_off] = NULL; |
440 | channels[plugin_off] = pos->channel; | 446 | } |
441 | } | 447 | plugin_off++; |
442 | else | 448 | } |
443 | { | 449 | /* give plugins chance to send us meta data, seek or finished messages */ |
444 | /* not running this round, seeking! */ | 450 | if (-1 == |
445 | channels[plugin_off] = NULL; | 451 | EXTRACTOR_IPC_channel_recv_ (channels, |
446 | } | 452 | plugin_count, |
447 | plugin_off++; | 453 | &process_plugin_reply, |
448 | } | 454 | &prp)) |
449 | /* give plugins chance to send us meta data, seek or finished messages */ | 455 | { |
450 | if (-1 == | 456 | /* serious problem in IPC; reset *all* channels */ |
451 | EXTRACTOR_IPC_channel_recv_ (channels, | 457 | LOG ("Failed to receive message from channels; full reset\n"); |
452 | plugin_count, | 458 | abort_all_channels (plugins); |
453 | &process_plugin_reply, | 459 | break; |
454 | &prp)) | 460 | } |
455 | { | 461 | |
456 | /* serious problem in IPC; reset *all* channels */ | 462 | /* calculate minimum seek request (or set done=0 to continue here) */ |
457 | LOG ("Failed to receive message from channels; full reset\n"); | 463 | done = 1; |
458 | abort_all_channels (plugins); | 464 | min_seek = -1; |
459 | break; | 465 | plugin_off = 0; |
460 | } | 466 | for (pos = plugins; NULL != pos; pos = pos->next) |
461 | 467 | { | |
462 | /* calculate minimum seek request (or set done=0 to continue here) */ | 468 | plugin_off++; |
463 | done = 1; | 469 | if ( (1 == pos->round_finished) || |
464 | min_seek = -1; | 470 | (NULL == pos->channel) ) |
465 | plugin_off = 0; | 471 | { |
466 | for (pos = plugins; NULL != pos; pos = pos->next) | 472 | continue; /* inactive plugin */ |
467 | { | 473 | } |
468 | plugin_off++; | 474 | if (-1 == pos->seek_request) |
469 | if ( (1 == pos->round_finished) || | 475 | { |
470 | (NULL == pos->channel) ) | 476 | /* possibly more meta data at current position, at least |
477 | this plugin is still working on it... */ | ||
478 | done = 0; | ||
479 | break; | ||
480 | } | ||
481 | if (-1 != pos->seek_request) | ||
482 | { | ||
483 | if (SEEK_END == pos->seek_whence) | ||
484 | { | ||
485 | /* convert distance from end to absolute position */ | ||
486 | pos->seek_whence = 0; | ||
487 | end = EXTRACTOR_datasource_get_size_ (ds, 1); | ||
488 | if (pos->seek_request > end) | ||
471 | { | 489 | { |
472 | continue; /* inactive plugin */ | 490 | LOG ("Cannot seek to before the beginning of the file!\n"); |
491 | pos->seek_request = 0; | ||
473 | } | 492 | } |
474 | if (-1 == pos->seek_request) | 493 | else |
475 | { | 494 | { |
476 | /* possibly more meta data at current position, at least | 495 | pos->seek_request = end - pos->seek_request; |
477 | this plugin is still working on it... */ | 496 | } |
478 | done = 0; | 497 | } |
479 | break; | 498 | if ( (-1 == min_seek) || |
480 | } | 499 | (min_seek > pos->seek_request) ) |
481 | if (-1 != pos->seek_request) | 500 | { |
482 | { | 501 | min_seek = pos->seek_request; |
483 | if (SEEK_END == pos->seek_whence) | 502 | } |
484 | { | 503 | } |
485 | /* convert distance from end to absolute position */ | 504 | } |
486 | pos->seek_whence = 0; | 505 | data_available = -1; |
487 | end = EXTRACTOR_datasource_get_size_ (ds, 1); | 506 | if ( (1 == done) && |
488 | if (pos->seek_request > end) | 507 | (-1 != min_seek) && |
489 | { | 508 | (NULL != shm) ) |
490 | LOG ("Cannot seek to before the beginning of the file!\n"); | 509 | { |
491 | pos->seek_request = 0; | 510 | /* current position done, but seek requested */ |
492 | } | 511 | done = 0; |
493 | else | 512 | if (-1 == |
494 | { | 513 | (data_available = EXTRACTOR_IPC_shared_memory_set_ (shm, |
495 | pos->seek_request = end - pos->seek_request; | 514 | ds, |
496 | } | 515 | min_seek, |
497 | } | 516 | DEFAULT_SHM_SIZE))) |
498 | if ( (-1 == min_seek) || | 517 | { |
499 | (min_seek > pos->seek_request) ) | 518 | LOG ("Failed to seek; full reset\n"); |
500 | { | 519 | abort_all_channels (plugins); |
501 | min_seek = pos->seek_request; | 520 | break; |
502 | } | 521 | } |
503 | } | 522 | } |
504 | } | 523 | /* if 'prp.file_finished', send 'abort' to plugins; |
505 | data_available = -1; | 524 | if not, send 'seek' notification to plugins in range */ |
506 | if ( (1 == done) && | 525 | for (pos = plugins; NULL != pos; pos = pos->next) |
507 | (-1 != min_seek) && | 526 | { |
508 | (NULL != shm) ) | 527 | if (NULL == (channel = pos->channel)) |
509 | { | 528 | { |
510 | /* current position done, but seek requested */ | 529 | /* Skipping plugin: channel down */ |
511 | done = 0; | 530 | continue; |
512 | if (-1 == | 531 | } |
513 | (data_available = EXTRACTOR_IPC_shared_memory_set_ (shm, | 532 | if ( (-1 != pos->seek_request) && |
514 | ds, | 533 | (1 == prp.file_finished) ) |
515 | min_seek, | 534 | { |
516 | DEFAULT_SHM_SIZE))) | 535 | send_discard_message (pos); |
517 | { | 536 | pos->round_finished = 1; |
518 | LOG ("Failed to seek; full reset\n"); | 537 | pos->seek_request = -1; |
519 | abort_all_channels (plugins); | 538 | } |
520 | break; | 539 | if ( (-1 != data_available) && |
521 | } | 540 | (-1 != pos->seek_request) && |
522 | } | 541 | (min_seek <= pos->seek_request) && |
523 | /* if 'prp.file_finished', send 'abort' to plugins; | 542 | ( (min_seek + data_available > pos->seek_request) || |
524 | if not, send 'seek' notification to plugins in range */ | 543 | (min_seek == EXTRACTOR_datasource_get_size_ (ds, 0))) ) |
525 | for (pos = plugins; NULL != pos; pos = pos->next) | 544 | { |
526 | { | 545 | /* Notify plugin about seek to 'min_seek' */ |
527 | if (NULL == (channel = pos->channel)) | 546 | send_update_message (pos, |
528 | { | 547 | min_seek, |
529 | /* Skipping plugin: channel down */ | 548 | data_available, |
530 | continue; | 549 | ds); |
531 | } | 550 | pos->seek_request = -1; |
532 | if ( (-1 != pos->seek_request) && | 551 | } |
533 | (1 == prp.file_finished) ) | 552 | if (0 == pos->round_finished) |
534 | { | 553 | done = 0; /* can't be done, plugin still active */ |
535 | send_discard_message (pos); | ||
536 | pos->round_finished = 1; | ||
537 | pos->seek_request = -1; | ||
538 | } | ||
539 | if ( (-1 != data_available) && | ||
540 | (-1 != pos->seek_request) && | ||
541 | (min_seek <= pos->seek_request) && | ||
542 | ( (min_seek + data_available > pos->seek_request) || | ||
543 | (min_seek == EXTRACTOR_datasource_get_size_ (ds, 0))) ) | ||
544 | { | ||
545 | /* Notify plugin about seek to 'min_seek' */ | ||
546 | send_update_message (pos, | ||
547 | min_seek, | ||
548 | data_available, | ||
549 | ds); | ||
550 | pos->seek_request = -1; | ||
551 | } | ||
552 | if (0 == pos->round_finished) | ||
553 | done = 0; /* can't be done, plugin still active */ | ||
554 | } | ||
555 | } | 554 | } |
555 | } | ||
556 | 556 | ||
557 | if (0 == have_in_memory) | 557 | if (0 == have_in_memory) |
558 | return; | 558 | return; |
@@ -567,22 +567,22 @@ do_extract (struct EXTRACTOR_PluginList *plugins, | |||
567 | ec.get_size = &in_process_get_size; | 567 | ec.get_size = &in_process_get_size; |
568 | ec.proc = &in_process_proc; | 568 | ec.proc = &in_process_proc; |
569 | for (pos = plugins; NULL != pos; pos = pos->next) | 569 | for (pos = plugins; NULL != pos; pos = pos->next) |
570 | { | ||
571 | if (EXTRACTOR_OPTION_IN_PROCESS != pos->flags) | ||
572 | continue; | ||
573 | if (-1 == EXTRACTOR_plugin_load_ (pos)) | ||
574 | continue; | ||
575 | ctx.plugin = pos; | ||
576 | ec.config = pos->plugin_options; | ||
577 | if (-1 == EXTRACTOR_datasource_seek_ (ds, 0, SEEK_SET)) | ||
570 | { | 578 | { |
571 | if (EXTRACTOR_OPTION_IN_PROCESS != pos->flags) | 579 | LOG ("Failed to seek to 0 for in-memory plugins\n"); |
572 | continue; | 580 | return; |
573 | if (-1 == EXTRACTOR_plugin_load_ (pos)) | ||
574 | continue; | ||
575 | ctx.plugin = pos; | ||
576 | ec.config = pos->plugin_options; | ||
577 | if (-1 == EXTRACTOR_datasource_seek_ (ds, 0, SEEK_SET)) | ||
578 | { | ||
579 | LOG ("Failed to seek to 0 for in-memory plugins\n"); | ||
580 | return; | ||
581 | } | ||
582 | pos->extract_method (&ec); | ||
583 | if (1 == ctx.finished) | ||
584 | break; | ||
585 | } | 581 | } |
582 | pos->extract_method (&ec); | ||
583 | if (1 == ctx.finished) | ||
584 | break; | ||
585 | } | ||
586 | } | 586 | } |
587 | 587 | ||
588 | 588 | ||
@@ -602,11 +602,11 @@ do_extract (struct EXTRACTOR_PluginList *plugins, | |||
602 | */ | 602 | */ |
603 | void | 603 | void |
604 | EXTRACTOR_extract (struct EXTRACTOR_PluginList *plugins, | 604 | EXTRACTOR_extract (struct EXTRACTOR_PluginList *plugins, |
605 | const char *filename, | 605 | const char *filename, |
606 | const void *data, | 606 | const void *data, |
607 | size_t size, | 607 | size_t size, |
608 | EXTRACTOR_MetaDataProcessor proc, | 608 | EXTRACTOR_MetaDataProcessor proc, |
609 | void *proc_cls) | 609 | void *proc_cls) |
610 | { | 610 | { |
611 | struct EXTRACTOR_Datasource *datasource; | 611 | struct EXTRACTOR_Datasource *datasource; |
612 | struct EXTRACTOR_SharedMemory *shm; | 612 | struct EXTRACTOR_SharedMemory *shm; |
@@ -617,47 +617,47 @@ EXTRACTOR_extract (struct EXTRACTOR_PluginList *plugins, | |||
617 | return; | 617 | return; |
618 | if (NULL == filename) | 618 | if (NULL == filename) |
619 | datasource = EXTRACTOR_datasource_create_from_buffer_ (data, size, | 619 | datasource = EXTRACTOR_datasource_create_from_buffer_ (data, size, |
620 | proc, proc_cls); | 620 | proc, proc_cls); |
621 | else | 621 | else |
622 | datasource = EXTRACTOR_datasource_create_from_file_ (filename, | 622 | datasource = EXTRACTOR_datasource_create_from_file_ (filename, |
623 | proc, proc_cls); | 623 | proc, proc_cls); |
624 | if (NULL == datasource) | 624 | if (NULL == datasource) |
625 | return; | 625 | return; |
626 | shm = NULL; | 626 | shm = NULL; |
627 | have_oop = 0; | 627 | have_oop = 0; |
628 | for (pos = plugins; NULL != pos; pos = pos->next) | 628 | for (pos = plugins; NULL != pos; pos = pos->next) |
629 | { | 629 | { |
630 | if (NULL == shm) | 630 | if (NULL == shm) |
631 | shm = pos->shm; | 631 | shm = pos->shm; |
632 | if (EXTRACTOR_OPTION_IN_PROCESS != pos->flags) | 632 | if (EXTRACTOR_OPTION_IN_PROCESS != pos->flags) |
633 | have_oop = 1; | 633 | have_oop = 1; |
634 | pos->round_finished = 0; | 634 | pos->round_finished = 0; |
635 | } | 635 | } |
636 | if ( (NULL == shm) && | 636 | if ( (NULL == shm) && |
637 | (1 == have_oop) ) | 637 | (1 == have_oop) ) |
638 | { | ||
639 | /* need to create shared memory segment */ | ||
640 | shm = EXTRACTOR_IPC_shared_memory_create_ (DEFAULT_SHM_SIZE); | ||
641 | if (NULL == shm) | ||
638 | { | 642 | { |
639 | /* need to create shared memory segment */ | 643 | LOG ("Failed to setup IPC\n"); |
640 | shm = EXTRACTOR_IPC_shared_memory_create_ (DEFAULT_SHM_SIZE); | 644 | EXTRACTOR_datasource_destroy_ (datasource); |
641 | if (NULL == shm) | 645 | return; |
642 | { | ||
643 | LOG ("Failed to setup IPC\n"); | ||
644 | EXTRACTOR_datasource_destroy_ (datasource); | ||
645 | return; | ||
646 | } | ||
647 | } | 646 | } |
647 | } | ||
648 | for (pos = plugins; NULL != pos; pos = pos->next) | 648 | for (pos = plugins; NULL != pos; pos = pos->next) |
649 | if ( (NULL == pos->channel) && | 649 | if ( (NULL == pos->channel) && |
650 | (NULL != shm) && | 650 | (NULL != shm) && |
651 | (EXTRACTOR_OPTION_IN_PROCESS != pos->flags) ) | 651 | (EXTRACTOR_OPTION_IN_PROCESS != pos->flags) ) |
652 | { | ||
653 | if (NULL == pos->shm) | ||
652 | { | 654 | { |
653 | if (NULL == pos->shm) | 655 | pos->shm = shm; |
654 | { | 656 | (void) EXTRACTOR_IPC_shared_memory_change_rc_ (shm, 1); |
655 | pos->shm = shm; | ||
656 | (void) EXTRACTOR_IPC_shared_memory_change_rc_ (shm, 1); | ||
657 | } | ||
658 | pos->channel = EXTRACTOR_IPC_channel_create_ (pos, | ||
659 | shm); | ||
660 | } | 657 | } |
658 | pos->channel = EXTRACTOR_IPC_channel_create_ (pos, | ||
659 | shm); | ||
660 | } | ||
661 | do_extract (plugins, | 661 | do_extract (plugins, |
662 | shm, | 662 | shm, |
663 | datasource, | 663 | datasource, |
@@ -680,14 +680,14 @@ EXTRACTOR_ltdl_init () | |||
680 | #endif | 680 | #endif |
681 | err = lt_dlinit (); | 681 | err = lt_dlinit (); |
682 | if (err > 0) | 682 | if (err > 0) |
683 | { | 683 | { |
684 | #if DEBUG | 684 | #if DEBUG |
685 | fprintf (stderr, | 685 | fprintf (stderr, |
686 | _("Initialization of plugin mechanism failed: %s!\n"), | 686 | _ ("Initialization of plugin mechanism failed: %s!\n"), |
687 | lt_dlerror ()); | 687 | lt_dlerror ()); |
688 | #endif | 688 | #endif |
689 | return; | 689 | return; |
690 | } | 690 | } |
691 | #if WINDOWS | 691 | #if WINDOWS |
692 | plibc_init_utf8 ("GNU", PACKAGE, 1); | 692 | plibc_init_utf8 ("GNU", PACKAGE, 1); |
693 | plibc_set_stat_size_size (sizeof (((struct stat *) 0)->st_size)); | 693 | plibc_set_stat_size_size (sizeof (((struct stat *) 0)->st_size)); |
@@ -700,11 +700,13 @@ EXTRACTOR_ltdl_init () | |||
700 | * Deinit. | 700 | * Deinit. |
701 | */ | 701 | */ |
702 | void __attribute__ ((destructor)) | 702 | void __attribute__ ((destructor)) |
703 | EXTRACTOR_ltdl_fini () { | 703 | EXTRACTOR_ltdl_fini () |
704 | { | ||
704 | #if WINDOWS | 705 | #if WINDOWS |
705 | plibc_shutdown (); | 706 | plibc_shutdown (); |
706 | #endif | 707 | #endif |
707 | lt_dlexit (); | 708 | lt_dlexit (); |
708 | } | 709 | } |
709 | 710 | ||
711 | |||
710 | /* end of extractor.c */ | 712 | /* end of extractor.c */ |
diff --git a/src/main/extractor_common.c b/src/main/extractor_common.c index 866609e..59524b3 100644 --- a/src/main/extractor_common.c +++ b/src/main/extractor_common.c | |||
@@ -39,27 +39,27 @@ | |||
39 | * @param buf buffer to read from | 39 | * @param buf buffer to read from |
40 | * @param size number of bytes to write | 40 | * @param size number of bytes to write |
41 | * @return number of bytes written (that is 'size'), or -1 on error | 41 | * @return number of bytes written (that is 'size'), or -1 on error |
42 | */ | 42 | */ |
43 | ssize_t | 43 | ssize_t |
44 | EXTRACTOR_write_all_ (int fd, | 44 | EXTRACTOR_write_all_ (int fd, |
45 | const void *buf, | 45 | const void *buf, |
46 | size_t size) | 46 | size_t size) |
47 | { | 47 | { |
48 | const char *data = buf; | 48 | const char *data = buf; |
49 | size_t off = 0; | 49 | size_t off = 0; |
50 | ssize_t ret; | 50 | ssize_t ret; |
51 | 51 | ||
52 | while (off < size) | 52 | while (off < size) |
53 | { | ||
54 | ret = write (fd, &data[off], size - off); | ||
55 | if (ret <= 0) | ||
53 | { | 56 | { |
54 | ret = write (fd, &data[off], size - off); | 57 | if (-1 == ret) |
55 | if (ret <= 0) | 58 | LOG_STRERROR ("write"); |
56 | { | 59 | return -1; |
57 | if (-1 == ret) | ||
58 | LOG_STRERROR ("write"); | ||
59 | return -1; | ||
60 | } | ||
61 | off += ret; | ||
62 | } | 60 | } |
61 | off += ret; | ||
62 | } | ||
63 | return size; | 63 | return size; |
64 | } | 64 | } |
65 | 65 | ||
@@ -74,28 +74,27 @@ EXTRACTOR_write_all_ (int fd, | |||
74 | */ | 74 | */ |
75 | ssize_t | 75 | ssize_t |
76 | EXTRACTOR_read_all_ (int fd, | 76 | EXTRACTOR_read_all_ (int fd, |
77 | void *buf, | 77 | void *buf, |
78 | size_t size) | 78 | size_t size) |
79 | { | 79 | { |
80 | char *data = buf; | 80 | char *data = buf; |
81 | size_t off = 0; | 81 | size_t off = 0; |
82 | ssize_t ret; | 82 | ssize_t ret; |
83 | 83 | ||
84 | while (off < size) | 84 | while (off < size) |
85 | { | ||
86 | ret = read (fd, &data[off], size - off); | ||
87 | if (ret <= 0) | ||
85 | { | 88 | { |
86 | ret = read (fd, &data[off], size - off); | 89 | if (-1 == ret) |
87 | if (ret <= 0) | 90 | LOG_STRERROR ("write"); |
88 | { | 91 | return -1; |
89 | if (-1 == ret) | ||
90 | LOG_STRERROR ("write"); | ||
91 | return -1; | ||
92 | } | ||
93 | off += ret; | ||
94 | } | 92 | } |
93 | off += ret; | ||
94 | } | ||
95 | return size; | 95 | return size; |
96 | |||
97 | } | ||
98 | 96 | ||
97 | } | ||
99 | 98 | ||
100 | 99 | ||
101 | /* end of extractor_common.c */ | 100 | /* end of extractor_common.c */ |
diff --git a/src/main/extractor_common.h b/src/main/extractor_common.h index 14b1c7f..5887c05 100644 --- a/src/main/extractor_common.h +++ b/src/main/extractor_common.h | |||
@@ -35,11 +35,11 @@ | |||
35 | * @param buf buffer to read from | 35 | * @param buf buffer to read from |
36 | * @param size number of bytes to write | 36 | * @param size number of bytes to write |
37 | * @return number of bytes written (that is 'size'), or -1 on error | 37 | * @return number of bytes written (that is 'size'), or -1 on error |
38 | */ | 38 | */ |
39 | ssize_t | 39 | ssize_t |
40 | EXTRACTOR_write_all_ (int fd, | 40 | EXTRACTOR_write_all_ (int fd, |
41 | const void *buf, | 41 | const void *buf, |
42 | size_t size); | 42 | size_t size); |
43 | 43 | ||
44 | 44 | ||
45 | /** | 45 | /** |
@@ -52,8 +52,8 @@ EXTRACTOR_write_all_ (int fd, | |||
52 | */ | 52 | */ |
53 | ssize_t | 53 | ssize_t |
54 | EXTRACTOR_read_all_ (int fd, | 54 | EXTRACTOR_read_all_ (int fd, |
55 | void *buf, | 55 | void *buf, |
56 | size_t size); | 56 | size_t size); |
57 | 57 | ||
58 | 58 | ||
59 | #endif | 59 | #endif |
diff --git a/src/main/extractor_datasource.c b/src/main/extractor_datasource.c index 888e524..0b18d7c 100644 --- a/src/main/extractor_datasource.c +++ b/src/main/extractor_datasource.c | |||
@@ -214,35 +214,35 @@ struct CompressedFileSource | |||
214 | */ | 214 | */ |
215 | static int | 215 | static int |
216 | bfds_pick_next_buffer_at (struct BufferedFileDataSource *bfds, | 216 | bfds_pick_next_buffer_at (struct BufferedFileDataSource *bfds, |
217 | uint64_t pos) | 217 | uint64_t pos) |
218 | { | 218 | { |
219 | int64_t position; | 219 | int64_t position; |
220 | ssize_t rd; | 220 | ssize_t rd; |
221 | 221 | ||
222 | if (pos > bfds->fsize) | 222 | if (pos > bfds->fsize) |
223 | { | 223 | { |
224 | LOG ("Invalid seek operation\n"); | 224 | LOG ("Invalid seek operation\n"); |
225 | return -1; /* invalid */ | 225 | return -1; /* invalid */ |
226 | } | 226 | } |
227 | if (NULL == bfds->buffer) | 227 | if (NULL == bfds->buffer) |
228 | { | 228 | { |
229 | bfds->buffer_pos = pos; | 229 | bfds->buffer_pos = pos; |
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | position = (int64_t) LSEEK (bfds->fd, pos, SEEK_SET); | 232 | position = (int64_t) LSEEK (bfds->fd, pos, SEEK_SET); |
233 | if (position < 0) | 233 | if (position < 0) |
234 | { | 234 | { |
235 | LOG_STRERROR ("lseek"); | 235 | LOG_STRERROR ("lseek"); |
236 | return -1; | 236 | return -1; |
237 | } | 237 | } |
238 | bfds->fpos = position; | 238 | bfds->fpos = position; |
239 | bfds->buffer_pos = 0; | 239 | bfds->buffer_pos = 0; |
240 | rd = read (bfds->fd, bfds->buffer, bfds->buffer_size); | 240 | rd = read (bfds->fd, bfds->buffer, bfds->buffer_size); |
241 | if (rd < 0) | 241 | if (rd < 0) |
242 | { | 242 | { |
243 | LOG_STRERROR ("read"); | 243 | LOG_STRERROR ("read"); |
244 | return -1; | 244 | return -1; |
245 | } | 245 | } |
246 | bfds->buffer_bytes = rd; | 246 | bfds->buffer_bytes = rd; |
247 | return 0; | 247 | return 0; |
248 | } | 248 | } |
@@ -258,8 +258,8 @@ bfds_pick_next_buffer_at (struct BufferedFileDataSource *bfds, | |||
258 | */ | 258 | */ |
259 | static struct BufferedFileDataSource * | 259 | static struct BufferedFileDataSource * |
260 | bfds_new (const void *data, | 260 | bfds_new (const void *data, |
261 | int fd, | 261 | int fd, |
262 | int64_t fsize) | 262 | int64_t fsize) |
263 | { | 263 | { |
264 | struct BufferedFileDataSource *result; | 264 | struct BufferedFileDataSource *result; |
265 | size_t xtra; | 265 | size_t xtra; |
@@ -269,19 +269,19 @@ bfds_new (const void *data, | |||
269 | else | 269 | else |
270 | xtra = (size_t) fsize; | 270 | xtra = (size_t) fsize; |
271 | if ( (-1 == fd) && (NULL == data) ) | 271 | if ( (-1 == fd) && (NULL == data) ) |
272 | { | 272 | { |
273 | LOG ("Invalid arguments\n"); | 273 | LOG ("Invalid arguments\n"); |
274 | return NULL; | 274 | return NULL; |
275 | } | 275 | } |
276 | if ( (-1 != fd) && (NULL != data) ) | 276 | if ( (-1 != fd) && (NULL != data) ) |
277 | fd = -1; /* don't need fd */ | 277 | fd = -1; /* don't need fd */ |
278 | if (NULL != data) | 278 | if (NULL != data) |
279 | xtra = 0; | 279 | xtra = 0; |
280 | if (NULL == (result = malloc (sizeof (struct BufferedFileDataSource) + xtra))) | 280 | if (NULL == (result = malloc (sizeof (struct BufferedFileDataSource) + xtra))) |
281 | { | 281 | { |
282 | LOG_STRERROR ("malloc"); | 282 | LOG_STRERROR ("malloc"); |
283 | return NULL; | 283 | return NULL; |
284 | } | 284 | } |
285 | memset (result, 0, sizeof (struct BufferedFileDataSource)); | 285 | memset (result, 0, sizeof (struct BufferedFileDataSource)); |
286 | result->data = (NULL != data) ? data : &result[1]; | 286 | result->data = (NULL != data) ? data : &result[1]; |
287 | result->buffer = (NULL != data) ? NULL : &result[1]; | 287 | result->buffer = (NULL != data) ? NULL : &result[1]; |
@@ -318,79 +318,79 @@ bfds_delete (struct BufferedFileDataSource *bfds) | |||
318 | */ | 318 | */ |
319 | static int64_t | 319 | static int64_t |
320 | bfds_seek (struct BufferedFileDataSource *bfds, | 320 | bfds_seek (struct BufferedFileDataSource *bfds, |
321 | int64_t pos, int whence) | 321 | int64_t pos, int whence) |
322 | { | 322 | { |
323 | uint64_t npos; | 323 | uint64_t npos; |
324 | size_t nbpos; | 324 | size_t nbpos; |
325 | 325 | ||
326 | switch (whence) | 326 | switch (whence) |
327 | { | ||
328 | case SEEK_CUR: | ||
329 | npos = bfds->fpos + bfds->buffer_pos + pos; | ||
330 | if (npos > bfds->fsize) | ||
327 | { | 331 | { |
328 | case SEEK_CUR: | 332 | LOG ("Invalid seek operation to %lld from %llu (max is %llu)\n", |
329 | npos = bfds->fpos + bfds->buffer_pos + pos; | 333 | (long long) pos, |
330 | if (npos > bfds->fsize) | 334 | bfds->fpos + bfds->buffer_pos, |
331 | { | 335 | (unsigned long long) bfds->fsize); |
332 | LOG ("Invalid seek operation to %lld from %llu (max is %llu)\n", | 336 | return -1; |
333 | (long long) pos, | 337 | } |
334 | bfds->fpos + bfds->buffer_pos, | 338 | nbpos = bfds->buffer_pos + pos; |
335 | (unsigned long long) bfds->fsize); | 339 | if ( (NULL == bfds->buffer) || |
336 | return -1; | 340 | (nbpos < bfds->buffer_bytes) ) |
337 | } | 341 | { |
338 | nbpos = bfds->buffer_pos + pos; | 342 | bfds->buffer_pos = nbpos; |
339 | if ( (NULL == bfds->buffer) || | ||
340 | (nbpos < bfds->buffer_bytes) ) | ||
341 | { | ||
342 | bfds->buffer_pos = nbpos; | ||
343 | return npos; | ||
344 | } | ||
345 | if (0 != bfds_pick_next_buffer_at (bfds, | ||
346 | npos)) | ||
347 | { | ||
348 | LOG ("seek operation failed\n"); | ||
349 | return -1; | ||
350 | } | ||
351 | return npos; | 343 | return npos; |
352 | case SEEK_END: | 344 | } |
353 | if (pos > 0) | 345 | if (0 != bfds_pick_next_buffer_at (bfds, |
354 | { | 346 | npos)) |
355 | LOG ("Invalid seek operation\n"); | 347 | { |
356 | return -1; | 348 | LOG ("seek operation failed\n"); |
357 | } | 349 | return -1; |
358 | if (bfds->fsize < - pos) | 350 | } |
359 | { | 351 | return npos; |
360 | LOG ("Invalid seek operation\n"); | 352 | case SEEK_END: |
361 | return -1; | 353 | if (pos > 0) |
362 | } | 354 | { |
363 | pos = bfds->fsize + pos; | 355 | LOG ("Invalid seek operation\n"); |
364 | /* fall-through! */ | 356 | return -1; |
365 | case SEEK_SET: | 357 | } |
366 | if (pos < 0) | 358 | if (bfds->fsize < -pos) |
367 | { | 359 | { |
368 | LOG ("Invalid seek operation\n"); | 360 | LOG ("Invalid seek operation\n"); |
369 | return -1; | 361 | return -1; |
370 | } | 362 | } |
371 | if (pos > bfds->fsize) | 363 | pos = bfds->fsize + pos; |
372 | { | 364 | /* fall-through! */ |
373 | LOG ("Invalid seek operation (%lld > %llu) %d\n", | 365 | case SEEK_SET: |
374 | (long long) pos, | 366 | if (pos < 0) |
375 | (unsigned long long) bfds->fsize, | 367 | { |
376 | SEEK_SET == whence); | 368 | LOG ("Invalid seek operation\n"); |
377 | return -1; | 369 | return -1; |
378 | } | 370 | } |
379 | if ( (NULL == bfds->buffer) || | 371 | if (pos > bfds->fsize) |
380 | ( (bfds->fpos <= pos) && | 372 | { |
381 | (bfds->fpos + bfds->buffer_bytes > pos) ) ) | 373 | LOG ("Invalid seek operation (%lld > %llu) %d\n", |
382 | { | 374 | (long long) pos, |
383 | bfds->buffer_pos = pos - bfds->fpos; | 375 | (unsigned long long) bfds->fsize, |
384 | return pos; | 376 | SEEK_SET == whence); |
385 | } | 377 | return -1; |
386 | if (0 != bfds_pick_next_buffer_at (bfds, pos)) | 378 | } |
387 | { | 379 | if ( (NULL == bfds->buffer) || |
388 | LOG ("seek operation failed\n"); | 380 | ( (bfds->fpos <= pos) && |
389 | return -1; | 381 | (bfds->fpos + bfds->buffer_bytes > pos) ) ) |
390 | } | 382 | { |
391 | ASSERT (pos == bfds->fpos + bfds->buffer_pos); | 383 | bfds->buffer_pos = pos - bfds->fpos; |
392 | return pos; | 384 | return pos; |
393 | } | 385 | } |
386 | if (0 != bfds_pick_next_buffer_at (bfds, pos)) | ||
387 | { | ||
388 | LOG ("seek operation failed\n"); | ||
389 | return -1; | ||
390 | } | ||
391 | ASSERT (pos == bfds->fpos + bfds->buffer_pos); | ||
392 | return pos; | ||
393 | } | ||
394 | return -1; | 394 | return -1; |
395 | } | 395 | } |
396 | 396 | ||
@@ -407,8 +407,8 @@ bfds_seek (struct BufferedFileDataSource *bfds, | |||
407 | */ | 407 | */ |
408 | static ssize_t | 408 | static ssize_t |
409 | bfds_read (struct BufferedFileDataSource *bfds, | 409 | bfds_read (struct BufferedFileDataSource *bfds, |
410 | void *buf_ptr, | 410 | void *buf_ptr, |
411 | size_t count) | 411 | size_t count) |
412 | { | 412 | { |
413 | char *cbuf = buf_ptr; | 413 | char *cbuf = buf_ptr; |
414 | uint64_t old_off; | 414 | uint64_t old_off; |
@@ -420,28 +420,28 @@ bfds_read (struct BufferedFileDataSource *bfds, | |||
420 | return 0; /* end of stream */ | 420 | return 0; /* end of stream */ |
421 | ret = 0; | 421 | ret = 0; |
422 | while (count > 0) | 422 | while (count > 0) |
423 | { | ||
424 | if ( (bfds->buffer_bytes == bfds->buffer_pos) && | ||
425 | (0 != bfds_pick_next_buffer_at (bfds, | ||
426 | bfds->fpos + bfds->buffer_bytes)) ) | ||
423 | { | 427 | { |
424 | if ( (bfds->buffer_bytes == bfds->buffer_pos) && | 428 | /* revert to original position, invalidate buffer */ |
425 | (0 != bfds_pick_next_buffer_at (bfds, | 429 | bfds->fpos = old_off; |
426 | bfds->fpos + bfds->buffer_bytes)) ) | 430 | bfds->buffer_bytes = 0; |
427 | { | 431 | bfds->buffer_pos = 0; |
428 | /* revert to original position, invalidate buffer */ | 432 | LOG ("read operation failed\n"); |
429 | bfds->fpos = old_off; | 433 | return -1; /* getting more failed */ |
430 | bfds->buffer_bytes = 0; | ||
431 | bfds->buffer_pos = 0; | ||
432 | LOG ("read operation failed\n"); | ||
433 | return -1; /* getting more failed */ | ||
434 | } | ||
435 | avail = bfds->buffer_bytes - bfds->buffer_pos; | ||
436 | if (avail > count) | ||
437 | avail = count; | ||
438 | if (0 == avail) | ||
439 | break; | ||
440 | memcpy (&cbuf[ret], bfds->data + bfds->buffer_pos, avail); | ||
441 | bfds->buffer_pos += avail; | ||
442 | count -= avail; | ||
443 | ret += avail; | ||
444 | } | 434 | } |
435 | avail = bfds->buffer_bytes - bfds->buffer_pos; | ||
436 | if (avail > count) | ||
437 | avail = count; | ||
438 | if (0 == avail) | ||
439 | break; | ||
440 | memcpy (&cbuf[ret], bfds->data + bfds->buffer_pos, avail); | ||
441 | bfds->buffer_pos += avail; | ||
442 | count -= avail; | ||
443 | ret += avail; | ||
444 | } | ||
445 | return ret; | 445 | return ret; |
446 | } | 446 | } |
447 | 447 | ||
@@ -458,17 +458,17 @@ bfds_read (struct BufferedFileDataSource *bfds, | |||
458 | */ | 458 | */ |
459 | static int | 459 | static int |
460 | cfs_init_decompressor_zlib (struct CompressedFileSource *cfs, | 460 | cfs_init_decompressor_zlib (struct CompressedFileSource *cfs, |
461 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) | 461 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) |
462 | { | 462 | { |
463 | unsigned int gzip_header_length = 10; | 463 | unsigned int gzip_header_length = 10; |
464 | unsigned char hdata[12]; | 464 | unsigned char hdata[12]; |
465 | ssize_t rsize; | 465 | ssize_t rsize; |
466 | 466 | ||
467 | if (0 != bfds_seek (cfs->bfds, 0, SEEK_SET)) | 467 | if (0 != bfds_seek (cfs->bfds, 0, SEEK_SET)) |
468 | { | 468 | { |
469 | LOG ("Failed to seek to offset 0!\n"); | 469 | LOG ("Failed to seek to offset 0!\n"); |
470 | return -1; | 470 | return -1; |
471 | } | 471 | } |
472 | /* Process gzip header */ | 472 | /* Process gzip header */ |
473 | rsize = bfds_read (cfs->bfds, hdata, sizeof (hdata)); | 473 | rsize = bfds_read (cfs->bfds, hdata, sizeof (hdata)); |
474 | if ( (-1 == rsize) || | 474 | if ( (-1 == rsize) || |
@@ -478,72 +478,74 @@ cfs_init_decompressor_zlib (struct CompressedFileSource *cfs, | |||
478 | gzip_header_length += 2 + (hdata[10] & 0xff) + ((hdata[11] & 0xff) * 256); | 478 | gzip_header_length += 2 + (hdata[10] & 0xff) + ((hdata[11] & 0xff) * 256); |
479 | 479 | ||
480 | if (0 != (hdata[3] & 0x8)) | 480 | if (0 != (hdata[3] & 0x8)) |
481 | { | ||
482 | /* FNAME set */ | ||
483 | char fname[1024]; | ||
484 | char *cptr; | ||
485 | size_t len; | ||
486 | ssize_t buf_bytes; | ||
487 | |||
488 | if (gzip_header_length > bfds_seek (cfs->bfds, gzip_header_length, | ||
489 | SEEK_SET)) | ||
481 | { | 490 | { |
482 | /* FNAME set */ | 491 | LOG ("Corrupt gzip, failed to seek to end of header\n"); |
483 | char fname[1024]; | 492 | return -1; |
484 | char *cptr; | ||
485 | size_t len; | ||
486 | ssize_t buf_bytes; | ||
487 | |||
488 | if (gzip_header_length > bfds_seek (cfs->bfds, gzip_header_length, SEEK_SET)) | ||
489 | { | ||
490 | LOG ("Corrupt gzip, failed to seek to end of header\n"); | ||
491 | return -1; | ||
492 | } | ||
493 | buf_bytes = bfds_read (cfs->bfds, fname, sizeof (fname)); | ||
494 | if (buf_bytes <= 0) | ||
495 | { | ||
496 | LOG ("Corrupt gzip, failed to read filename\n"); | ||
497 | return -1; | ||
498 | } | ||
499 | if (NULL == (cptr = memchr (fname, 0, buf_bytes))) | ||
500 | { | ||
501 | LOG ("Corrupt gzip, failed to read filename terminator\n"); | ||
502 | return -1; | ||
503 | } | ||
504 | len = cptr - fname; | ||
505 | if ( (NULL != proc) && | ||
506 | (0 != proc (proc_cls, "<zlib>", EXTRACTOR_METATYPE_FILENAME, | ||
507 | EXTRACTOR_METAFORMAT_C_STRING, "text/plain", | ||
508 | fname, | ||
509 | len)) ) | ||
510 | return 0; /* done */ | ||
511 | gzip_header_length += len + 1; | ||
512 | } | 493 | } |
494 | buf_bytes = bfds_read (cfs->bfds, fname, sizeof (fname)); | ||
495 | if (buf_bytes <= 0) | ||
496 | { | ||
497 | LOG ("Corrupt gzip, failed to read filename\n"); | ||
498 | return -1; | ||
499 | } | ||
500 | if (NULL == (cptr = memchr (fname, 0, buf_bytes))) | ||
501 | { | ||
502 | LOG ("Corrupt gzip, failed to read filename terminator\n"); | ||
503 | return -1; | ||
504 | } | ||
505 | len = cptr - fname; | ||
506 | if ( (NULL != proc) && | ||
507 | (0 != proc (proc_cls, "<zlib>", EXTRACTOR_METATYPE_FILENAME, | ||
508 | EXTRACTOR_METAFORMAT_C_STRING, "text/plain", | ||
509 | fname, | ||
510 | len)) ) | ||
511 | return 0; /* done */ | ||
512 | gzip_header_length += len + 1; | ||
513 | } | ||
513 | 514 | ||
514 | if (0 != (hdata[3] & 0x16)) | 515 | if (0 != (hdata[3] & 0x16)) |
516 | { | ||
517 | /* FCOMMENT set */ | ||
518 | char fcomment[1024]; | ||
519 | char *cptr; | ||
520 | ssize_t buf_bytes; | ||
521 | size_t len; | ||
522 | |||
523 | if (gzip_header_length > bfds_seek (cfs->bfds, gzip_header_length, | ||
524 | SEEK_SET)) | ||
515 | { | 525 | { |
516 | /* FCOMMENT set */ | 526 | LOG ("Corrupt gzip, failed to seek to end of header\n"); |
517 | char fcomment[1024]; | 527 | return -1; |
518 | char *cptr; | 528 | } |
519 | ssize_t buf_bytes; | 529 | buf_bytes = bfds_read (cfs->bfds, fcomment, sizeof (fcomment)); |
520 | size_t len; | 530 | if (buf_bytes <= 0) |
521 | 531 | { | |
522 | if (gzip_header_length > bfds_seek (cfs->bfds, gzip_header_length, SEEK_SET)) | 532 | LOG ("Corrupt gzip, failed to read comment\n"); |
523 | { | 533 | return -1; |
524 | LOG ("Corrupt gzip, failed to seek to end of header\n"); | 534 | } |
525 | return -1; | 535 | if (NULL == (cptr = memchr (fcomment, 0, buf_bytes))) |
526 | } | 536 | { |
527 | buf_bytes = bfds_read (cfs->bfds, fcomment, sizeof (fcomment)); | 537 | LOG ("Corrupt gzip, failed to read comment terminator\n"); |
528 | if (buf_bytes <= 0) | 538 | return -1; |
529 | { | ||
530 | LOG ("Corrupt gzip, failed to read comment\n"); | ||
531 | return -1; | ||
532 | } | ||
533 | if (NULL == (cptr = memchr (fcomment, 0, buf_bytes))) | ||
534 | { | ||
535 | LOG ("Corrupt gzip, failed to read comment terminator\n"); | ||
536 | return -1; | ||
537 | } | ||
538 | len = cptr - fcomment; | ||
539 | if ( (NULL != proc) && | ||
540 | (0 != proc (proc_cls, "<zlib>", EXTRACTOR_METATYPE_COMMENT, | ||
541 | EXTRACTOR_METAFORMAT_C_STRING, "text/plain", | ||
542 | (const char *) fcomment, | ||
543 | len)) ) | ||
544 | return 0; /* done */ | ||
545 | gzip_header_length += len + 1; | ||
546 | } | 539 | } |
540 | len = cptr - fcomment; | ||
541 | if ( (NULL != proc) && | ||
542 | (0 != proc (proc_cls, "<zlib>", EXTRACTOR_METATYPE_COMMENT, | ||
543 | EXTRACTOR_METAFORMAT_C_STRING, "text/plain", | ||
544 | (const char *) fcomment, | ||
545 | len)) ) | ||
546 | return 0; /* done */ | ||
547 | gzip_header_length += len + 1; | ||
548 | } | ||
547 | if (0 != (hdata[3] & 0x2)) /* FCHRC set */ | 549 | if (0 != (hdata[3] & 0x2)) /* FCHRC set */ |
548 | gzip_header_length += 2; | 550 | gzip_header_length += 2; |
549 | memset (&cfs->strm, 0, sizeof (z_stream)); | 551 | memset (&cfs->strm, 0, sizeof (z_stream)); |
@@ -556,10 +558,10 @@ cfs_init_decompressor_zlib (struct CompressedFileSource *cfs, | |||
556 | 558 | ||
557 | if (cfs->gzip_header_length != | 559 | if (cfs->gzip_header_length != |
558 | bfds_seek (cfs->bfds, cfs->gzip_header_length, SEEK_SET)) | 560 | bfds_seek (cfs->bfds, cfs->gzip_header_length, SEEK_SET)) |
559 | { | 561 | { |
560 | LOG ("Failed to seek to start to initialize gzip decompressor\n"); | 562 | LOG ("Failed to seek to start to initialize gzip decompressor\n"); |
561 | return -1; | 563 | return -1; |
562 | } | 564 | } |
563 | cfs->strm.avail_out = COM_CHUNK_SIZE; | 565 | cfs->strm.avail_out = COM_CHUNK_SIZE; |
564 | /* | 566 | /* |
565 | * note: maybe plain inflateInit(&strm) is adequate, | 567 | * note: maybe plain inflateInit(&strm) is adequate, |
@@ -567,20 +569,21 @@ cfs_init_decompressor_zlib (struct CompressedFileSource *cfs, | |||
567 | * | 569 | * |
568 | * ZLIB_VERNUM isn't defined by zlib version 1.1.4 ; | 570 | * ZLIB_VERNUM isn't defined by zlib version 1.1.4 ; |
569 | * there might be a better check. | 571 | * there might be a better check. |
570 | */ | 572 | */if (Z_OK != inflateInit2 (&cfs->strm, |
571 | if (Z_OK != inflateInit2 (&cfs->strm, | ||
572 | #ifdef ZLIB_VERNUM | 573 | #ifdef ZLIB_VERNUM |
573 | 15 + 32 | 574 | 15 + 32 |
574 | #else | 575 | #else |
575 | - MAX_WBITS | 576 | -MAX_WBITS |
576 | #endif | 577 | #endif |
577 | )) | 578 | )) |
578 | { | 579 | { |
579 | LOG ("Failed to initialize zlib decompression\n"); | 580 | LOG ("Failed to initialize zlib decompression\n"); |
580 | return -1; | 581 | return -1; |
581 | } | 582 | } |
582 | return 1; | 583 | return 1; |
583 | } | 584 | } |
585 | |||
586 | |||
584 | #endif | 587 | #endif |
585 | 588 | ||
586 | 589 | ||
@@ -596,24 +599,26 @@ cfs_init_decompressor_zlib (struct CompressedFileSource *cfs, | |||
596 | */ | 599 | */ |
597 | static int | 600 | static int |
598 | cfs_init_decompressor_bz2 (struct CompressedFileSource *cfs, | 601 | cfs_init_decompressor_bz2 (struct CompressedFileSource *cfs, |
599 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) | 602 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) |
600 | { | 603 | { |
601 | if (0 != | 604 | if (0 != |
602 | bfds_seek (cfs->bfds, 0, SEEK_SET)) | 605 | bfds_seek (cfs->bfds, 0, SEEK_SET)) |
603 | { | 606 | { |
604 | LOG ("Failed to seek to start to initialize BZ2 decompressor\n"); | 607 | LOG ("Failed to seek to start to initialize BZ2 decompressor\n"); |
605 | return -1; | 608 | return -1; |
606 | } | 609 | } |
607 | memset (&cfs->bstrm, 0, sizeof (bz_stream)); | 610 | memset (&cfs->bstrm, 0, sizeof (bz_stream)); |
608 | if (BZ_OK != | 611 | if (BZ_OK != |
609 | BZ2_bzDecompressInit (&cfs->bstrm, 0, 0)) | 612 | BZ2_bzDecompressInit (&cfs->bstrm, 0, 0)) |
610 | { | 613 | { |
611 | LOG ("Failed to initialize BZ2 decompressor\n"); | 614 | LOG ("Failed to initialize BZ2 decompressor\n"); |
612 | return -1; | 615 | return -1; |
613 | } | 616 | } |
614 | cfs->bstrm.avail_out = COM_CHUNK_SIZE; | 617 | cfs->bstrm.avail_out = COM_CHUNK_SIZE; |
615 | return 1; | 618 | return 1; |
616 | } | 619 | } |
620 | |||
621 | |||
617 | #endif | 622 | #endif |
618 | 623 | ||
619 | 624 | ||
@@ -628,24 +633,24 @@ cfs_init_decompressor_bz2 (struct CompressedFileSource *cfs, | |||
628 | */ | 633 | */ |
629 | static int | 634 | static int |
630 | cfs_init_decompressor (struct CompressedFileSource *cfs, | 635 | cfs_init_decompressor (struct CompressedFileSource *cfs, |
631 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) | 636 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) |
632 | { | 637 | { |
633 | cfs->result_pos = 0; | 638 | cfs->result_pos = 0; |
634 | cfs->fpos = 0; | 639 | cfs->fpos = 0; |
635 | switch (cfs->compression_type) | 640 | switch (cfs->compression_type) |
636 | { | 641 | { |
637 | #if HAVE_ZLIB | 642 | #if HAVE_ZLIB |
638 | case COMP_TYPE_ZLIB: | 643 | case COMP_TYPE_ZLIB: |
639 | return cfs_init_decompressor_zlib (cfs, proc, proc_cls); | 644 | return cfs_init_decompressor_zlib (cfs, proc, proc_cls); |
640 | #endif | 645 | #endif |
641 | #if HAVE_LIBBZ2 | 646 | #if HAVE_LIBBZ2 |
642 | case COMP_TYPE_BZ2: | 647 | case COMP_TYPE_BZ2: |
643 | return cfs_init_decompressor_bz2 (cfs, proc, proc_cls); | 648 | return cfs_init_decompressor_bz2 (cfs, proc, proc_cls); |
644 | #endif | 649 | #endif |
645 | default: | 650 | default: |
646 | LOG ("invalid compression type selected\n"); | 651 | LOG ("invalid compression type selected\n"); |
647 | return -1; | 652 | return -1; |
648 | } | 653 | } |
649 | } | 654 | } |
650 | 655 | ||
651 | 656 | ||
@@ -662,6 +667,8 @@ cfs_deinit_decompressor_zlib (struct CompressedFileSource *cfs) | |||
662 | inflateEnd (&cfs->strm); | 667 | inflateEnd (&cfs->strm); |
663 | return 1; | 668 | return 1; |
664 | } | 669 | } |
670 | |||
671 | |||
665 | #endif | 672 | #endif |
666 | 673 | ||
667 | 674 | ||
@@ -678,6 +685,8 @@ cfs_deinit_decompressor_bz2 (struct CompressedFileSource *cfs) | |||
678 | BZ2_bzDecompressEnd (&cfs->bstrm); | 685 | BZ2_bzDecompressEnd (&cfs->bstrm); |
679 | return 1; | 686 | return 1; |
680 | } | 687 | } |
688 | |||
689 | |||
681 | #endif | 690 | #endif |
682 | 691 | ||
683 | 692 | ||
@@ -691,19 +700,19 @@ static int | |||
691 | cfs_deinit_decompressor (struct CompressedFileSource *cfs) | 700 | cfs_deinit_decompressor (struct CompressedFileSource *cfs) |
692 | { | 701 | { |
693 | switch (cfs->compression_type) | 702 | switch (cfs->compression_type) |
694 | { | 703 | { |
695 | #if HAVE_ZLIB | 704 | #if HAVE_ZLIB |
696 | case COMP_TYPE_ZLIB: | 705 | case COMP_TYPE_ZLIB: |
697 | return cfs_deinit_decompressor_zlib (cfs); | 706 | return cfs_deinit_decompressor_zlib (cfs); |
698 | #endif | 707 | #endif |
699 | #if HAVE_LIBBZ2 | 708 | #if HAVE_LIBBZ2 |
700 | case COMP_TYPE_BZ2: | 709 | case COMP_TYPE_BZ2: |
701 | return cfs_deinit_decompressor_bz2 (cfs); | 710 | return cfs_deinit_decompressor_bz2 (cfs); |
702 | #endif | 711 | #endif |
703 | default: | 712 | default: |
704 | LOG ("invalid compression type selected\n"); | 713 | LOG ("invalid compression type selected\n"); |
705 | return -1; | 714 | return -1; |
706 | } | 715 | } |
707 | } | 716 | } |
708 | 717 | ||
709 | 718 | ||
@@ -750,28 +759,28 @@ cfs_destroy (struct CompressedFileSource *cfs) | |||
750 | */ | 759 | */ |
751 | struct CompressedFileSource * | 760 | struct CompressedFileSource * |
752 | cfs_new (struct BufferedFileDataSource *bfds, | 761 | cfs_new (struct BufferedFileDataSource *bfds, |
753 | int64_t fsize, | 762 | int64_t fsize, |
754 | enum ExtractorCompressionType compression_type, | 763 | enum ExtractorCompressionType compression_type, |
755 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) | 764 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) |
756 | { | 765 | { |
757 | struct CompressedFileSource *cfs; | 766 | struct CompressedFileSource *cfs; |
758 | 767 | ||
759 | if (NULL == (cfs = malloc (sizeof (struct CompressedFileSource)))) | 768 | if (NULL == (cfs = malloc (sizeof (struct CompressedFileSource)))) |
760 | { | 769 | { |
761 | LOG_STRERROR ("malloc"); | 770 | LOG_STRERROR ("malloc"); |
762 | return NULL; | 771 | return NULL; |
763 | } | 772 | } |
764 | memset (cfs, 0, sizeof (struct CompressedFileSource)); | 773 | memset (cfs, 0, sizeof (struct CompressedFileSource)); |
765 | cfs->compression_type = compression_type; | 774 | cfs->compression_type = compression_type; |
766 | cfs->bfds = bfds; | 775 | cfs->bfds = bfds; |
767 | cfs->fsize = fsize; | 776 | cfs->fsize = fsize; |
768 | cfs->uncompressed_size = -1; | 777 | cfs->uncompressed_size = -1; |
769 | if (1 != cfs_init_decompressor (cfs, | 778 | if (1 != cfs_init_decompressor (cfs, |
770 | proc, proc_cls)) | 779 | proc, proc_cls)) |
771 | { | 780 | { |
772 | free (cfs); | 781 | free (cfs); |
773 | return NULL; | 782 | return NULL; |
774 | } | 783 | } |
775 | return cfs; | 784 | return cfs; |
776 | } | 785 | } |
777 | 786 | ||
@@ -789,8 +798,8 @@ cfs_new (struct BufferedFileDataSource *bfds, | |||
789 | */ | 798 | */ |
790 | static ssize_t | 799 | static ssize_t |
791 | cfs_read_zlib (struct CompressedFileSource *cfs, | 800 | cfs_read_zlib (struct CompressedFileSource *cfs, |
792 | void *data, | 801 | void *data, |
793 | size_t size) | 802 | size_t size) |
794 | { | 803 | { |
795 | char *dst = data; | 804 | char *dst = data; |
796 | int ret; | 805 | int ret; |
@@ -799,77 +808,79 @@ cfs_read_zlib (struct CompressedFileSource *cfs, | |||
799 | unsigned char buf[COM_CHUNK_SIZE]; | 808 | unsigned char buf[COM_CHUNK_SIZE]; |
800 | 809 | ||
801 | if (cfs->fpos == cfs->uncompressed_size) | 810 | if (cfs->fpos == cfs->uncompressed_size) |
802 | { | 811 | { |
803 | /* end of file */ | 812 | /* end of file */ |
804 | return 0; | 813 | return 0; |
805 | } | 814 | } |
806 | rc = 0; | 815 | rc = 0; |
807 | if (COM_CHUNK_SIZE > cfs->strm.avail_out + cfs->result_pos) | 816 | if (COM_CHUNK_SIZE > cfs->strm.avail_out + cfs->result_pos) |
808 | { | 817 | { |
809 | /* got left-over decompressed data from previous round! */ | 818 | /* got left-over decompressed data from previous round! */ |
810 | in = COM_CHUNK_SIZE - (cfs->strm.avail_out + cfs->result_pos); | 819 | in = COM_CHUNK_SIZE - (cfs->strm.avail_out + cfs->result_pos); |
811 | if (in > size) | 820 | if (in > size) |
812 | in = size; | 821 | in = size; |
813 | memcpy (&dst[rc], &cfs->result[cfs->result_pos], in); | 822 | memcpy (&dst[rc], &cfs->result[cfs->result_pos], in); |
814 | cfs->fpos += in; | 823 | cfs->fpos += in; |
815 | cfs->result_pos += in; | 824 | cfs->result_pos += in; |
816 | rc += in; | 825 | rc += in; |
817 | } | 826 | } |
818 | ret = Z_OK; | 827 | ret = Z_OK; |
819 | while ( (rc < size) && (Z_STREAM_END != ret) ) | 828 | while ( (rc < size) && (Z_STREAM_END != ret) ) |
829 | { | ||
830 | /* read block from original data source */ | ||
831 | in = bfds_read (cfs->bfds, | ||
832 | buf, sizeof (buf)); | ||
833 | if (in < 0) | ||
820 | { | 834 | { |
821 | /* read block from original data source */ | 835 | LOG ("unexpected EOF\n"); |
822 | in = bfds_read (cfs->bfds, | 836 | return -1; /* unexpected EOF */ |
823 | buf, sizeof (buf)); | ||
824 | if (in < 0) | ||
825 | { | ||
826 | LOG ("unexpected EOF\n"); | ||
827 | return -1; /* unexpected EOF */ | ||
828 | } | ||
829 | if (0 == in) | ||
830 | { | ||
831 | cfs->uncompressed_size = cfs->fpos; | ||
832 | return rc; | ||
833 | } | ||
834 | cfs->strm.next_in = buf; | ||
835 | cfs->strm.avail_in = (uInt) in; | ||
836 | cfs->strm.next_out = (unsigned char *) cfs->result; | ||
837 | cfs->strm.avail_out = COM_CHUNK_SIZE; | ||
838 | cfs->result_pos = 0; | ||
839 | ret = inflate (&cfs->strm, Z_SYNC_FLUSH); | ||
840 | if ( (Z_OK != ret) && (Z_STREAM_END != ret) ) | ||
841 | { | ||
842 | LOG ("unexpected gzip inflate error: %d\n", ret); | ||
843 | return -1; /* unexpected error */ | ||
844 | } | ||
845 | /* go backwards by the number of bytes left in the buffer */ | ||
846 | if (-1 == bfds_seek (cfs->bfds, - (int64_t) cfs->strm.avail_in, SEEK_CUR)) | ||
847 | { | ||
848 | LOG ("seek failed\n"); | ||
849 | return -1; | ||
850 | } | ||
851 | /* copy decompressed bytes to target buffer */ | ||
852 | in = COM_CHUNK_SIZE - cfs->strm.avail_out; | ||
853 | if (in > size - rc) | ||
854 | { | ||
855 | if (Z_STREAM_END == ret) | ||
856 | { | ||
857 | cfs->uncompressed_size = cfs->fpos + in; | ||
858 | ret = Z_OK; | ||
859 | } | ||
860 | in = size - rc; | ||
861 | } | ||
862 | memcpy (&dst[rc], &cfs->result[cfs->result_pos], in); | ||
863 | cfs->fpos += in; | ||
864 | cfs->result_pos += in; | ||
865 | rc += in; | ||
866 | } | 837 | } |
867 | if (Z_STREAM_END == ret) | 838 | if (0 == in) |
868 | { | 839 | { |
869 | cfs->uncompressed_size = cfs->fpos; | 840 | cfs->uncompressed_size = cfs->fpos; |
841 | return rc; | ||
842 | } | ||
843 | cfs->strm.next_in = buf; | ||
844 | cfs->strm.avail_in = (uInt) in; | ||
845 | cfs->strm.next_out = (unsigned char *) cfs->result; | ||
846 | cfs->strm.avail_out = COM_CHUNK_SIZE; | ||
847 | cfs->result_pos = 0; | ||
848 | ret = inflate (&cfs->strm, Z_SYNC_FLUSH); | ||
849 | if ( (Z_OK != ret) && (Z_STREAM_END != ret) ) | ||
850 | { | ||
851 | LOG ("unexpected gzip inflate error: %d\n", ret); | ||
852 | return -1; /* unexpected error */ | ||
853 | } | ||
854 | /* go backwards by the number of bytes left in the buffer */ | ||
855 | if (-1 == bfds_seek (cfs->bfds, -(int64_t) cfs->strm.avail_in, SEEK_CUR)) | ||
856 | { | ||
857 | LOG ("seek failed\n"); | ||
858 | return -1; | ||
859 | } | ||
860 | /* copy decompressed bytes to target buffer */ | ||
861 | in = COM_CHUNK_SIZE - cfs->strm.avail_out; | ||
862 | if (in > size - rc) | ||
863 | { | ||
864 | if (Z_STREAM_END == ret) | ||
865 | { | ||
866 | cfs->uncompressed_size = cfs->fpos + in; | ||
867 | ret = Z_OK; | ||
868 | } | ||
869 | in = size - rc; | ||
870 | } | 870 | } |
871 | memcpy (&dst[rc], &cfs->result[cfs->result_pos], in); | ||
872 | cfs->fpos += in; | ||
873 | cfs->result_pos += in; | ||
874 | rc += in; | ||
875 | } | ||
876 | if (Z_STREAM_END == ret) | ||
877 | { | ||
878 | cfs->uncompressed_size = cfs->fpos; | ||
879 | } | ||
871 | return rc; | 880 | return rc; |
872 | } | 881 | } |
882 | |||
883 | |||
873 | #endif | 884 | #endif |
874 | 885 | ||
875 | 886 | ||
@@ -886,8 +897,8 @@ cfs_read_zlib (struct CompressedFileSource *cfs, | |||
886 | */ | 897 | */ |
887 | static ssize_t | 898 | static ssize_t |
888 | cfs_read_bz2 (struct CompressedFileSource *cfs, | 899 | cfs_read_bz2 (struct CompressedFileSource *cfs, |
889 | void *data, | 900 | void *data, |
890 | size_t size) | 901 | size_t size) |
891 | { | 902 | { |
892 | char *dst = data; | 903 | char *dst = data; |
893 | int ret; | 904 | int ret; |
@@ -896,77 +907,79 @@ cfs_read_bz2 (struct CompressedFileSource *cfs, | |||
896 | char buf[COM_CHUNK_SIZE]; | 907 | char buf[COM_CHUNK_SIZE]; |
897 | 908 | ||
898 | if (cfs->fpos == cfs->uncompressed_size) | 909 | if (cfs->fpos == cfs->uncompressed_size) |
899 | { | 910 | { |
900 | /* end of file */ | 911 | /* end of file */ |
901 | return 0; | 912 | return 0; |
902 | } | 913 | } |
903 | rc = 0; | 914 | rc = 0; |
904 | if (COM_CHUNK_SIZE > cfs->bstrm.avail_out + cfs->result_pos) | 915 | if (COM_CHUNK_SIZE > cfs->bstrm.avail_out + cfs->result_pos) |
905 | { | 916 | { |
906 | /* got left-over decompressed data from previous round! */ | 917 | /* got left-over decompressed data from previous round! */ |
907 | in = COM_CHUNK_SIZE - (cfs->bstrm.avail_out + cfs->result_pos); | 918 | in = COM_CHUNK_SIZE - (cfs->bstrm.avail_out + cfs->result_pos); |
908 | if (in > size) | 919 | if (in > size) |
909 | in = size; | 920 | in = size; |
910 | memcpy (&dst[rc], &cfs->result[cfs->result_pos], in); | 921 | memcpy (&dst[rc], &cfs->result[cfs->result_pos], in); |
911 | cfs->fpos += in; | 922 | cfs->fpos += in; |
912 | cfs->result_pos += in; | 923 | cfs->result_pos += in; |
913 | rc += in; | 924 | rc += in; |
914 | } | 925 | } |
915 | ret = BZ_OK; | 926 | ret = BZ_OK; |
916 | while ( (rc < size) && (BZ_STREAM_END != ret) ) | 927 | while ( (rc < size) && (BZ_STREAM_END != ret) ) |
928 | { | ||
929 | /* read block from original data source */ | ||
930 | in = bfds_read (cfs->bfds, | ||
931 | buf, sizeof (buf)); | ||
932 | if (in < 0) | ||
917 | { | 933 | { |
918 | /* read block from original data source */ | 934 | LOG ("unexpected EOF\n"); |
919 | in = bfds_read (cfs->bfds, | 935 | return -1; /* unexpected EOF */ |
920 | buf, sizeof (buf)); | ||
921 | if (in < 0) | ||
922 | { | ||
923 | LOG ("unexpected EOF\n"); | ||
924 | return -1; /* unexpected EOF */ | ||
925 | } | ||
926 | if (0 == in) | ||
927 | { | ||
928 | cfs->uncompressed_size = cfs->fpos; | ||
929 | return rc; | ||
930 | } | ||
931 | cfs->bstrm.next_in = buf; | ||
932 | cfs->bstrm.avail_in = (unsigned int) in; | ||
933 | cfs->bstrm.next_out = cfs->result; | ||
934 | cfs->bstrm.avail_out = COM_CHUNK_SIZE; | ||
935 | cfs->result_pos = 0; | ||
936 | ret = BZ2_bzDecompress (&cfs->bstrm); | ||
937 | if ( (BZ_OK != ret) && (BZ_STREAM_END != ret) ) | ||
938 | { | ||
939 | LOG ("unexpected bzip2 decompress error: %d\n", ret); | ||
940 | return -1; /* unexpected error */ | ||
941 | } | ||
942 | /* go backwards by the number of bytes left in the buffer */ | ||
943 | if (-1 == bfds_seek (cfs->bfds, - (int64_t) cfs->bstrm.avail_in, SEEK_CUR)) | ||
944 | { | ||
945 | LOG ("seek failed\n"); | ||
946 | return -1; | ||
947 | } | ||
948 | /* copy decompressed bytes to target buffer */ | ||
949 | in = COM_CHUNK_SIZE - cfs->bstrm.avail_out; | ||
950 | if (in > size - rc) | ||
951 | { | ||
952 | if (BZ_STREAM_END == ret) | ||
953 | { | ||
954 | cfs->uncompressed_size = cfs->fpos + in; | ||
955 | ret = BZ_OK; | ||
956 | } | ||
957 | in = size - rc; | ||
958 | } | ||
959 | memcpy (&dst[rc], &cfs->result[cfs->result_pos], in); | ||
960 | cfs->fpos += in; | ||
961 | cfs->result_pos += in; | ||
962 | rc += in; | ||
963 | } | 936 | } |
964 | if (BZ_STREAM_END == ret) | 937 | if (0 == in) |
965 | { | 938 | { |
966 | cfs->uncompressed_size = cfs->fpos; | 939 | cfs->uncompressed_size = cfs->fpos; |
940 | return rc; | ||
941 | } | ||
942 | cfs->bstrm.next_in = buf; | ||
943 | cfs->bstrm.avail_in = (unsigned int) in; | ||
944 | cfs->bstrm.next_out = cfs->result; | ||
945 | cfs->bstrm.avail_out = COM_CHUNK_SIZE; | ||
946 | cfs->result_pos = 0; | ||
947 | ret = BZ2_bzDecompress (&cfs->bstrm); | ||
948 | if ( (BZ_OK != ret) && (BZ_STREAM_END != ret) ) | ||
949 | { | ||
950 | LOG ("unexpected bzip2 decompress error: %d\n", ret); | ||
951 | return -1; /* unexpected error */ | ||
952 | } | ||
953 | /* go backwards by the number of bytes left in the buffer */ | ||
954 | if (-1 == bfds_seek (cfs->bfds, -(int64_t) cfs->bstrm.avail_in, SEEK_CUR)) | ||
955 | { | ||
956 | LOG ("seek failed\n"); | ||
957 | return -1; | ||
967 | } | 958 | } |
959 | /* copy decompressed bytes to target buffer */ | ||
960 | in = COM_CHUNK_SIZE - cfs->bstrm.avail_out; | ||
961 | if (in > size - rc) | ||
962 | { | ||
963 | if (BZ_STREAM_END == ret) | ||
964 | { | ||
965 | cfs->uncompressed_size = cfs->fpos + in; | ||
966 | ret = BZ_OK; | ||
967 | } | ||
968 | in = size - rc; | ||
969 | } | ||
970 | memcpy (&dst[rc], &cfs->result[cfs->result_pos], in); | ||
971 | cfs->fpos += in; | ||
972 | cfs->result_pos += in; | ||
973 | rc += in; | ||
974 | } | ||
975 | if (BZ_STREAM_END == ret) | ||
976 | { | ||
977 | cfs->uncompressed_size = cfs->fpos; | ||
978 | } | ||
968 | return rc; | 979 | return rc; |
969 | } | 980 | } |
981 | |||
982 | |||
970 | #endif | 983 | #endif |
971 | 984 | ||
972 | 985 | ||
@@ -982,23 +995,23 @@ cfs_read_bz2 (struct CompressedFileSource *cfs, | |||
982 | */ | 995 | */ |
983 | static ssize_t | 996 | static ssize_t |
984 | cfs_read (struct CompressedFileSource *cfs, | 997 | cfs_read (struct CompressedFileSource *cfs, |
985 | void *data, | 998 | void *data, |
986 | size_t size) | 999 | size_t size) |
987 | { | 1000 | { |
988 | switch (cfs->compression_type) | 1001 | switch (cfs->compression_type) |
989 | { | 1002 | { |
990 | #if HAVE_ZLIB | 1003 | #if HAVE_ZLIB |
991 | case COMP_TYPE_ZLIB: | 1004 | case COMP_TYPE_ZLIB: |
992 | return cfs_read_zlib (cfs, data, size); | 1005 | return cfs_read_zlib (cfs, data, size); |
993 | #endif | 1006 | #endif |
994 | #if HAVE_LIBBZ2 | 1007 | #if HAVE_LIBBZ2 |
995 | case COMP_TYPE_BZ2: | 1008 | case COMP_TYPE_BZ2: |
996 | return cfs_read_bz2 (cfs, data, size); | 1009 | return cfs_read_bz2 (cfs, data, size); |
997 | #endif | 1010 | #endif |
998 | default: | 1011 | default: |
999 | LOG ("invalid compression type selected\n"); | 1012 | LOG ("invalid compression type selected\n"); |
1000 | return -1; | 1013 | return -1; |
1001 | } | 1014 | } |
1002 | } | 1015 | } |
1003 | 1016 | ||
1004 | 1017 | ||
@@ -1014,104 +1027,105 @@ cfs_read (struct CompressedFileSource *cfs, | |||
1014 | */ | 1027 | */ |
1015 | static int64_t | 1028 | static int64_t |
1016 | cfs_seek (struct CompressedFileSource *cfs, | 1029 | cfs_seek (struct CompressedFileSource *cfs, |
1017 | int64_t position, | 1030 | int64_t position, |
1018 | int whence) | 1031 | int whence) |
1019 | { | 1032 | { |
1020 | uint64_t nposition; | 1033 | uint64_t nposition; |
1021 | int64_t delta; | 1034 | int64_t delta; |
1022 | 1035 | ||
1023 | switch (whence) | 1036 | switch (whence) |
1037 | { | ||
1038 | case SEEK_CUR: | ||
1039 | if (cfs->fpos + position < 0) | ||
1040 | { | ||
1041 | /* underflow */ | ||
1042 | LOG ("Invalid seek operation\n"); | ||
1043 | return -1; | ||
1044 | } | ||
1045 | if ( (-1 != cfs->uncompressed_size) && | ||
1046 | (cfs->fpos + position > cfs->uncompressed_size) ) | ||
1047 | { | ||
1048 | LOG ("Invalid seek operation\n"); | ||
1049 | return -1; | ||
1050 | } | ||
1051 | nposition = cfs->fpos + position; | ||
1052 | break; | ||
1053 | case SEEK_END: | ||
1054 | ASSERT (-1 != cfs->uncompressed_size); | ||
1055 | if (position > 0) | ||
1024 | { | 1056 | { |
1025 | case SEEK_CUR: | ||
1026 | if (cfs->fpos + position < 0) | ||
1027 | { | ||
1028 | /* underflow */ | ||
1029 | LOG ("Invalid seek operation\n"); | ||
1030 | return -1; | ||
1031 | } | ||
1032 | if ( (-1 != cfs->uncompressed_size) && | ||
1033 | (cfs->fpos + position > cfs->uncompressed_size) ) | ||
1034 | { | ||
1035 | LOG ("Invalid seek operation\n"); | ||
1036 | return -1; | ||
1037 | } | ||
1038 | nposition = cfs->fpos + position; | ||
1039 | break; | ||
1040 | case SEEK_END: | ||
1041 | ASSERT (-1 != cfs->uncompressed_size); | ||
1042 | if (position > 0) | ||
1043 | { | ||
1044 | LOG ("Invalid seek operation\n"); | ||
1045 | return -1; | ||
1046 | } | ||
1047 | if (cfs->uncompressed_size < - position) | ||
1048 | { | ||
1049 | LOG ("Invalid seek operation\n"); | ||
1050 | return -1; | ||
1051 | } | ||
1052 | nposition = cfs->uncompressed_size + position; | ||
1053 | break; | ||
1054 | case SEEK_SET: | ||
1055 | if (position < 0) | ||
1056 | { | ||
1057 | LOG ("Invalid seek operation\n"); | ||
1058 | return -1; | ||
1059 | } | ||
1060 | if ( (-1 != cfs->uncompressed_size) && | ||
1061 | (cfs->uncompressed_size < position ) ) | ||
1062 | { | ||
1063 | LOG ("Invalid seek operation\n"); | ||
1064 | return -1; | ||
1065 | } | ||
1066 | nposition = (uint64_t) position; | ||
1067 | break; | ||
1068 | default: | ||
1069 | LOG ("Invalid seek operation\n"); | 1057 | LOG ("Invalid seek operation\n"); |
1070 | return -1; | 1058 | return -1; |
1071 | } | 1059 | } |
1060 | if (cfs->uncompressed_size < -position) | ||
1061 | { | ||
1062 | LOG ("Invalid seek operation\n"); | ||
1063 | return -1; | ||
1064 | } | ||
1065 | nposition = cfs->uncompressed_size + position; | ||
1066 | break; | ||
1067 | case SEEK_SET: | ||
1068 | if (position < 0) | ||
1069 | { | ||
1070 | LOG ("Invalid seek operation\n"); | ||
1071 | return -1; | ||
1072 | } | ||
1073 | if ( (-1 != cfs->uncompressed_size) && | ||
1074 | (cfs->uncompressed_size < position) ) | ||
1075 | { | ||
1076 | LOG ("Invalid seek operation\n"); | ||
1077 | return -1; | ||
1078 | } | ||
1079 | nposition = (uint64_t) position; | ||
1080 | break; | ||
1081 | default: | ||
1082 | LOG ("Invalid seek operation\n"); | ||
1083 | return -1; | ||
1084 | } | ||
1072 | delta = nposition - cfs->fpos; | 1085 | delta = nposition - cfs->fpos; |
1073 | if (delta < 0) | 1086 | if (delta < 0) |
1087 | { | ||
1088 | if (cfs->result_pos >= -delta) | ||
1074 | { | 1089 | { |
1075 | if (cfs->result_pos >= - delta) | 1090 | cfs->result_pos += delta; |
1076 | { | 1091 | cfs->fpos += delta; |
1077 | cfs->result_pos += delta; | 1092 | delta = 0; |
1078 | cfs->fpos += delta; | ||
1079 | delta = 0; | ||
1080 | } | ||
1081 | else | ||
1082 | { | ||
1083 | if (-1 == cfs_reset_stream (cfs)) | ||
1084 | { | ||
1085 | LOG ("Failed to restart compressed stream for seek operation\n"); | ||
1086 | return -1; | ||
1087 | } | ||
1088 | delta = nposition; | ||
1089 | } | ||
1090 | } | 1093 | } |
1094 | else | ||
1095 | { | ||
1096 | if (-1 == cfs_reset_stream (cfs)) | ||
1097 | { | ||
1098 | LOG ("Failed to restart compressed stream for seek operation\n"); | ||
1099 | return -1; | ||
1100 | } | ||
1101 | delta = nposition; | ||
1102 | } | ||
1103 | } | ||
1091 | while (delta > 0) | 1104 | while (delta > 0) |
1105 | { | ||
1106 | char buf[COM_CHUNK_SIZE]; | ||
1107 | size_t max; | ||
1108 | int64_t ret; | ||
1109 | |||
1110 | max = (sizeof (buf) > delta) ? delta : sizeof (buf); | ||
1111 | ret = cfs_read (cfs, buf, max); | ||
1112 | if (-1 == ret) | ||
1113 | { | ||
1114 | LOG ("Failed to read decompressed stream for seek operation\n"); | ||
1115 | return -1; | ||
1116 | } | ||
1117 | if (0 == ret) | ||
1092 | { | 1118 | { |
1093 | char buf[COM_CHUNK_SIZE]; | 1119 | LOG ( |
1094 | size_t max; | 1120 | "Reached unexpected end of stream at %llu during seek operation to %llu (%d left)\n", |
1095 | int64_t ret; | 1121 | (unsigned long long) cfs->fpos, |
1096 | 1122 | (unsigned long long) nposition, | |
1097 | max = (sizeof (buf) > delta) ? delta : sizeof (buf); | 1123 | delta); |
1098 | ret = cfs_read (cfs, buf, max); | 1124 | return -1; |
1099 | if (-1 == ret) | ||
1100 | { | ||
1101 | LOG ("Failed to read decompressed stream for seek operation\n"); | ||
1102 | return -1; | ||
1103 | } | ||
1104 | if (0 == ret) | ||
1105 | { | ||
1106 | LOG ("Reached unexpected end of stream at %llu during seek operation to %llu (%d left)\n", | ||
1107 | (unsigned long long) cfs->fpos, | ||
1108 | (unsigned long long) nposition, | ||
1109 | delta); | ||
1110 | return -1; | ||
1111 | } | ||
1112 | ASSERT (ret <= delta); | ||
1113 | delta -= ret; | ||
1114 | } | 1125 | } |
1126 | ASSERT (ret <= delta); | ||
1127 | delta -= ret; | ||
1128 | } | ||
1115 | return cfs->fpos; | 1129 | return cfs->fpos; |
1116 | } | 1130 | } |
1117 | 1131 | ||
@@ -1186,8 +1200,8 @@ struct EXTRACTOR_Datasource | |||
1186 | */ | 1200 | */ |
1187 | struct EXTRACTOR_Datasource * | 1201 | struct EXTRACTOR_Datasource * |
1188 | EXTRACTOR_datasource_create_from_file_ (const char *filename, | 1202 | EXTRACTOR_datasource_create_from_file_ (const char *filename, |
1189 | EXTRACTOR_MetaDataProcessor proc, | 1203 | EXTRACTOR_MetaDataProcessor proc, |
1190 | void *proc_cls) | 1204 | void *proc_cls) |
1191 | { | 1205 | { |
1192 | struct BufferedFileDataSource *bfds; | 1206 | struct BufferedFileDataSource *bfds; |
1193 | struct EXTRACTOR_Datasource *ds; | 1207 | struct EXTRACTOR_Datasource *ds; |
@@ -1201,56 +1215,56 @@ EXTRACTOR_datasource_create_from_file_ (const char *filename, | |||
1201 | #endif | 1215 | #endif |
1202 | 1216 | ||
1203 | if (-1 == (fd = OPEN (filename, O_RDONLY | O_LARGEFILE | winmode))) | 1217 | if (-1 == (fd = OPEN (filename, O_RDONLY | O_LARGEFILE | winmode))) |
1204 | { | 1218 | { |
1205 | LOG_STRERROR_FILE ("open", filename); | 1219 | LOG_STRERROR_FILE ("open", filename); |
1206 | return NULL; | 1220 | return NULL; |
1207 | } | 1221 | } |
1208 | if ( (0 != FSTAT (fd, &sb)) || | 1222 | if ( (0 != FSTAT (fd, &sb)) || |
1209 | (S_ISDIR (sb.st_mode)) ) | 1223 | (S_ISDIR (sb.st_mode)) ) |
1210 | { | 1224 | { |
1211 | if (! S_ISDIR (sb.st_mode)) | 1225 | if (! S_ISDIR (sb.st_mode)) |
1212 | LOG_STRERROR_FILE ("fstat", filename); | 1226 | LOG_STRERROR_FILE ("fstat", filename); |
1213 | else | 1227 | else |
1214 | LOG ("Skipping directory `%s'\n", filename); | 1228 | LOG ("Skipping directory `%s'\n", filename); |
1215 | (void) CLOSE (fd); | 1229 | (void) CLOSE (fd); |
1216 | return NULL; | 1230 | return NULL; |
1217 | } | 1231 | } |
1218 | fsize = (int64_t) sb.st_size; | 1232 | fsize = (int64_t) sb.st_size; |
1219 | if (0 == fsize) | 1233 | if (0 == fsize) |
1220 | { | 1234 | { |
1221 | (void) CLOSE (fd); | 1235 | (void) CLOSE (fd); |
1222 | return NULL; | 1236 | return NULL; |
1223 | } | 1237 | } |
1224 | bfds = bfds_new (NULL, fd, fsize); | 1238 | bfds = bfds_new (NULL, fd, fsize); |
1225 | if (NULL == bfds) | 1239 | if (NULL == bfds) |
1226 | { | 1240 | { |
1227 | (void) CLOSE (fd); | 1241 | (void) CLOSE (fd); |
1228 | return NULL; | 1242 | return NULL; |
1229 | } | 1243 | } |
1230 | if (NULL == (ds = malloc (sizeof (struct EXTRACTOR_Datasource)))) | 1244 | if (NULL == (ds = malloc (sizeof (struct EXTRACTOR_Datasource)))) |
1231 | { | 1245 | { |
1232 | LOG_STRERROR ("malloc"); | 1246 | LOG_STRERROR ("malloc"); |
1233 | bfds_delete (bfds); | 1247 | bfds_delete (bfds); |
1234 | (void) CLOSE (fd); | 1248 | (void) CLOSE (fd); |
1235 | return NULL; | 1249 | return NULL; |
1236 | } | 1250 | } |
1237 | ds->bfds = bfds; | 1251 | ds->bfds = bfds; |
1238 | ds->fd = fd; | 1252 | ds->fd = fd; |
1239 | ds->cfs = NULL; | 1253 | ds->cfs = NULL; |
1240 | ct = get_compression_type (bfds); | 1254 | ct = get_compression_type (bfds); |
1241 | if ( (COMP_TYPE_ZLIB == ct) || | 1255 | if ( (COMP_TYPE_ZLIB == ct) || |
1242 | (COMP_TYPE_BZ2 == ct) ) | 1256 | (COMP_TYPE_BZ2 == ct) ) |
1257 | { | ||
1258 | ds->cfs = cfs_new (bfds, fsize, ct, proc, proc_cls); | ||
1259 | if (NULL == ds->cfs) | ||
1243 | { | 1260 | { |
1244 | ds->cfs = cfs_new (bfds, fsize, ct, proc, proc_cls); | 1261 | LOG ("Failed to initialize decompressor\n"); |
1245 | if (NULL == ds->cfs) | 1262 | bfds_delete (bfds); |
1246 | { | 1263 | free (ds); |
1247 | LOG ("Failed to initialize decompressor\n"); | 1264 | (void) CLOSE (fd); |
1248 | bfds_delete (bfds); | 1265 | return NULL; |
1249 | free (ds); | ||
1250 | (void) CLOSE (fd); | ||
1251 | return NULL; | ||
1252 | } | ||
1253 | } | 1266 | } |
1267 | } | ||
1254 | return ds; | 1268 | return ds; |
1255 | } | 1269 | } |
1256 | 1270 | ||
@@ -1266,8 +1280,9 @@ EXTRACTOR_datasource_create_from_file_ (const char *filename, | |||
1266 | */ | 1280 | */ |
1267 | struct EXTRACTOR_Datasource * | 1281 | struct EXTRACTOR_Datasource * |
1268 | EXTRACTOR_datasource_create_from_buffer_ (const char *buf, | 1282 | EXTRACTOR_datasource_create_from_buffer_ (const char *buf, |
1269 | size_t size, | 1283 | size_t size, |
1270 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls) | 1284 | EXTRACTOR_MetaDataProcessor proc, |
1285 | void *proc_cls) | ||
1271 | { | 1286 | { |
1272 | struct BufferedFileDataSource *bfds; | 1287 | struct BufferedFileDataSource *bfds; |
1273 | struct EXTRACTOR_Datasource *ds; | 1288 | struct EXTRACTOR_Datasource *ds; |
@@ -1276,32 +1291,32 @@ EXTRACTOR_datasource_create_from_buffer_ (const char *buf, | |||
1276 | if (0 == size) | 1291 | if (0 == size) |
1277 | return NULL; | 1292 | return NULL; |
1278 | if (NULL == (bfds = bfds_new (buf, -1, size))) | 1293 | if (NULL == (bfds = bfds_new (buf, -1, size))) |
1279 | { | 1294 | { |
1280 | LOG ("Failed to initialize buffer data source\n"); | 1295 | LOG ("Failed to initialize buffer data source\n"); |
1281 | return NULL; | 1296 | return NULL; |
1282 | } | 1297 | } |
1283 | if (NULL == (ds = malloc (sizeof (struct EXTRACTOR_Datasource)))) | 1298 | if (NULL == (ds = malloc (sizeof (struct EXTRACTOR_Datasource)))) |
1284 | { | 1299 | { |
1285 | LOG_STRERROR ("malloc"); | 1300 | LOG_STRERROR ("malloc"); |
1286 | bfds_delete (bfds); | 1301 | bfds_delete (bfds); |
1287 | return NULL; | 1302 | return NULL; |
1288 | } | 1303 | } |
1289 | ds->bfds = bfds; | 1304 | ds->bfds = bfds; |
1290 | ds->fd = -1; | 1305 | ds->fd = -1; |
1291 | ds->cfs = NULL; | 1306 | ds->cfs = NULL; |
1292 | ct = get_compression_type (bfds); | 1307 | ct = get_compression_type (bfds); |
1293 | if ( (COMP_TYPE_ZLIB == ct) || | 1308 | if ( (COMP_TYPE_ZLIB == ct) || |
1294 | (COMP_TYPE_BZ2 == ct) ) | 1309 | (COMP_TYPE_BZ2 == ct) ) |
1310 | { | ||
1311 | ds->cfs = cfs_new (bfds, size, ct, proc, proc_cls); | ||
1312 | if (NULL == ds->cfs) | ||
1295 | { | 1313 | { |
1296 | ds->cfs = cfs_new (bfds, size, ct, proc, proc_cls); | 1314 | LOG ("Failed to initialize decompressor\n"); |
1297 | if (NULL == ds->cfs) | 1315 | bfds_delete (bfds); |
1298 | { | 1316 | free (ds); |
1299 | LOG ("Failed to initialize decompressor\n"); | 1317 | return NULL; |
1300 | bfds_delete (bfds); | ||
1301 | free (ds); | ||
1302 | return NULL; | ||
1303 | } | ||
1304 | } | 1318 | } |
1319 | } | ||
1305 | return ds; | 1320 | return ds; |
1306 | } | 1321 | } |
1307 | 1322 | ||
@@ -1334,8 +1349,8 @@ EXTRACTOR_datasource_destroy_ (struct EXTRACTOR_Datasource *ds) | |||
1334 | */ | 1349 | */ |
1335 | ssize_t | 1350 | ssize_t |
1336 | EXTRACTOR_datasource_read_ (void *cls, | 1351 | EXTRACTOR_datasource_read_ (void *cls, |
1337 | void *data, | 1352 | void *data, |
1338 | size_t size) | 1353 | size_t size) |
1339 | { | 1354 | { |
1340 | struct EXTRACTOR_Datasource *ds = cls; | 1355 | struct EXTRACTOR_Datasource *ds = cls; |
1341 | 1356 | ||
@@ -1357,23 +1372,23 @@ EXTRACTOR_datasource_read_ (void *cls, | |||
1357 | */ | 1372 | */ |
1358 | int64_t | 1373 | int64_t |
1359 | EXTRACTOR_datasource_seek_ (void *cls, | 1374 | EXTRACTOR_datasource_seek_ (void *cls, |
1360 | int64_t pos, | 1375 | int64_t pos, |
1361 | int whence) | 1376 | int whence) |
1362 | { | 1377 | { |
1363 | struct EXTRACTOR_Datasource *ds = cls; | 1378 | struct EXTRACTOR_Datasource *ds = cls; |
1364 | 1379 | ||
1365 | if (NULL != ds->cfs) | 1380 | if (NULL != ds->cfs) |
1381 | { | ||
1382 | if ( (SEEK_END == whence) && | ||
1383 | (-1 == ds->cfs->uncompressed_size) ) | ||
1366 | { | 1384 | { |
1367 | if ( (SEEK_END == whence) && | 1385 | /* need to obtain uncompressed size */ |
1368 | (-1 == ds->cfs->uncompressed_size) ) | 1386 | (void) EXTRACTOR_datasource_get_size_ (ds, 1); |
1369 | { | 1387 | if (-1 == ds->cfs->uncompressed_size) |
1370 | /* need to obtain uncompressed size */ | 1388 | return -1; |
1371 | (void) EXTRACTOR_datasource_get_size_ (ds, 1); | ||
1372 | if (-1 == ds->cfs->uncompressed_size) | ||
1373 | return -1; | ||
1374 | } | ||
1375 | return cfs_seek (ds->cfs, pos, whence); | ||
1376 | } | 1389 | } |
1390 | return cfs_seek (ds->cfs, pos, whence); | ||
1391 | } | ||
1377 | return bfds_seek (ds->bfds, pos, whence); | 1392 | return bfds_seek (ds->bfds, pos, whence); |
1378 | } | 1393 | } |
1379 | 1394 | ||
@@ -1387,30 +1402,32 @@ EXTRACTOR_datasource_seek_ (void *cls, | |||
1387 | */ | 1402 | */ |
1388 | int64_t | 1403 | int64_t |
1389 | EXTRACTOR_datasource_get_size_ (void *cls, | 1404 | EXTRACTOR_datasource_get_size_ (void *cls, |
1390 | int force) | 1405 | int force) |
1391 | { | 1406 | { |
1392 | struct EXTRACTOR_Datasource *ds = cls; | 1407 | struct EXTRACTOR_Datasource *ds = cls; |
1393 | char buf[32 * 1024]; | 1408 | char buf[32 * 1024]; |
1394 | uint64_t pos; | 1409 | uint64_t pos; |
1395 | 1410 | ||
1396 | if (NULL != ds->cfs) | 1411 | if (NULL != ds->cfs) |
1412 | { | ||
1413 | if ( (force) && | ||
1414 | (-1 == ds->cfs->uncompressed_size) ) | ||
1397 | { | 1415 | { |
1398 | if ( (force) && | 1416 | pos = ds->cfs->fpos; |
1399 | (-1 == ds->cfs->uncompressed_size) ) | 1417 | while ( (-1 == ds->cfs->uncompressed_size) && |
1400 | { | 1418 | (-1 != cfs_read (ds->cfs, buf, sizeof (buf))) ) |
1401 | pos = ds->cfs->fpos; | 1419 | ; |
1402 | while ( (-1 == ds->cfs->uncompressed_size) && | 1420 | if (-1 == cfs_seek (ds->cfs, pos, SEEK_SET)) |
1403 | (-1 != cfs_read (ds->cfs, buf, sizeof (buf))) ) ; | 1421 | { |
1404 | if (-1 == cfs_seek (ds->cfs, pos, SEEK_SET)) | 1422 | LOG ( |
1405 | { | 1423 | "Serious problem, I moved the buffer to determine the file size but could not restore it...\n"); |
1406 | LOG ("Serious problem, I moved the buffer to determine the file size but could not restore it...\n"); | 1424 | return -1; |
1407 | return -1; | 1425 | } |
1408 | } | 1426 | if (-1 == ds->cfs->uncompressed_size) |
1409 | if (-1 == ds->cfs->uncompressed_size) | 1427 | return -1; |
1410 | return -1; | ||
1411 | } | ||
1412 | return ds->cfs->uncompressed_size; | ||
1413 | } | 1428 | } |
1429 | return ds->cfs->uncompressed_size; | ||
1430 | } | ||
1414 | return ds->bfds->fsize; | 1431 | return ds->bfds->fsize; |
1415 | } | 1432 | } |
1416 | 1433 | ||
diff --git a/src/main/extractor_datasource.h b/src/main/extractor_datasource.h index f25cc4b..dc548a6 100644 --- a/src/main/extractor_datasource.h +++ b/src/main/extractor_datasource.h | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | /** | 30 | /** |
31 | * Handle to a datasource we can use for the plugins. | 31 | * Handle to a datasource we can use for the plugins. |
32 | */ | 32 | */ |
33 | struct EXTRACTOR_Datasource; | 33 | struct EXTRACTOR_Datasource; |
34 | 34 | ||
35 | 35 | ||
@@ -43,7 +43,8 @@ struct EXTRACTOR_Datasource; | |||
43 | */ | 43 | */ |
44 | struct EXTRACTOR_Datasource * | 44 | struct EXTRACTOR_Datasource * |
45 | EXTRACTOR_datasource_create_from_file_ (const char *filename, | 45 | EXTRACTOR_datasource_create_from_file_ (const char *filename, |
46 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls); | 46 | EXTRACTOR_MetaDataProcessor proc, |
47 | void *proc_cls); | ||
47 | 48 | ||
48 | 49 | ||
49 | /** | 50 | /** |
@@ -57,8 +58,9 @@ EXTRACTOR_datasource_create_from_file_ (const char *filename, | |||
57 | */ | 58 | */ |
58 | struct EXTRACTOR_Datasource * | 59 | struct EXTRACTOR_Datasource * |
59 | EXTRACTOR_datasource_create_from_buffer_ (const char *buf, | 60 | EXTRACTOR_datasource_create_from_buffer_ (const char *buf, |
60 | size_t size, | 61 | size_t size, |
61 | EXTRACTOR_MetaDataProcessor proc, void *proc_cls); | 62 | EXTRACTOR_MetaDataProcessor proc, |
63 | void *proc_cls); | ||
62 | 64 | ||
63 | 65 | ||
64 | /** | 66 | /** |
@@ -81,14 +83,14 @@ EXTRACTOR_datasource_destroy_ (struct EXTRACTOR_Datasource *ds); | |||
81 | */ | 83 | */ |
82 | ssize_t | 84 | ssize_t |
83 | EXTRACTOR_datasource_read_ (void *cls, | 85 | EXTRACTOR_datasource_read_ (void *cls, |
84 | void *data, | 86 | void *data, |
85 | size_t size); | 87 | size_t size); |
86 | 88 | ||
87 | 89 | ||
88 | /** | 90 | /** |
89 | * Seek in the datasource. Use 'SEEK_CUR' for whence and 'pos' of 0 to | 91 | * Seek in the datasource. Use 'SEEK_CUR' for whence and 'pos' of 0 to |
90 | * obtain the current position in the file. | 92 | * obtain the current position in the file. |
91 | * | 93 | * |
92 | * @param cls must be a 'struct EXTRACTOR_Datasource' | 94 | * @param cls must be a 'struct EXTRACTOR_Datasource' |
93 | * @param pos position to seek (see 'man lseek')o | 95 | * @param pos position to seek (see 'man lseek')o |
94 | * @param whence how to see (absolute to start, relative, absolute to end) | 96 | * @param whence how to see (absolute to start, relative, absolute to end) |
@@ -97,20 +99,20 @@ EXTRACTOR_datasource_read_ (void *cls, | |||
97 | */ | 99 | */ |
98 | int64_t | 100 | int64_t |
99 | EXTRACTOR_datasource_seek_ (void *cls, | 101 | EXTRACTOR_datasource_seek_ (void *cls, |
100 | int64_t pos, | 102 | int64_t pos, |
101 | int whence); | 103 | int whence); |
102 | 104 | ||
103 | 105 | ||
104 | /** | 106 | /** |
105 | * Determine the overall size of the data source (after compression). | 107 | * Determine the overall size of the data source (after compression). |
106 | * | 108 | * |
107 | * @param cls must be a 'struct EXTRACTOR_Datasource' | 109 | * @param cls must be a 'struct EXTRACTOR_Datasource' |
108 | * @param force force computing the size if it is unavailable | 110 | * @param force force computing the size if it is unavailable |
109 | * @return overall file size, -1 on error or unknown | 111 | * @return overall file size, -1 on error or unknown |
110 | */ | 112 | */ |
111 | int64_t | 113 | int64_t |
112 | EXTRACTOR_datasource_get_size_ (void *cls, | 114 | EXTRACTOR_datasource_get_size_ (void *cls, |
113 | int force); | 115 | int force); |
114 | 116 | ||
115 | 117 | ||
116 | #endif | 118 | #endif |
diff --git a/src/main/extractor_ipc.c b/src/main/extractor_ipc.c index 47d9d4d..b343bd6 100644 --- a/src/main/extractor_ipc.c +++ b/src/main/extractor_ipc.c | |||
@@ -40,10 +40,10 @@ | |||
40 | */ | 40 | */ |
41 | ssize_t | 41 | ssize_t |
42 | EXTRACTOR_IPC_process_reply_ (struct EXTRACTOR_PluginList *plugin, | 42 | EXTRACTOR_IPC_process_reply_ (struct EXTRACTOR_PluginList *plugin, |
43 | const void *data, | 43 | const void *data, |
44 | size_t size, | 44 | size_t size, |
45 | EXTRACTOR_ChannelMessageProcessor proc, | 45 | EXTRACTOR_ChannelMessageProcessor proc, |
46 | void *proc_cls) | 46 | void *proc_cls) |
47 | { | 47 | { |
48 | const char *cdata; | 48 | const char *cdata; |
49 | unsigned char code; | 49 | unsigned char code; |
@@ -55,83 +55,84 @@ EXTRACTOR_IPC_process_reply_ (struct EXTRACTOR_PluginList *plugin, | |||
55 | 55 | ||
56 | ret = 0; | 56 | ret = 0; |
57 | while (size > 0) | 57 | while (size > 0) |
58 | { | ||
59 | cdata = data; | ||
60 | code = (unsigned char) cdata[0]; | ||
61 | switch (code) | ||
58 | { | 62 | { |
59 | cdata = data; | 63 | case MESSAGE_DONE: /* Done */ |
60 | code = (unsigned char) cdata[0]; | 64 | plugin->seek_request = -1; |
61 | switch (code) | 65 | plugin->round_finished = 1; |
62 | { | 66 | ret++; |
63 | case MESSAGE_DONE: /* Done */ | 67 | size--; |
64 | plugin->seek_request = -1; | 68 | data++; |
65 | plugin->round_finished = 1; | 69 | continue; |
66 | ret++; | 70 | case MESSAGE_SEEK: /* Seek */ |
67 | size--; | 71 | if (size < sizeof (struct SeekRequestMessage)) |
68 | data++; | 72 | { |
69 | continue; | 73 | plugin->seek_request = -1; |
70 | case MESSAGE_SEEK: /* Seek */ | 74 | return ret; |
71 | if (size < sizeof (struct SeekRequestMessage)) | 75 | } |
72 | { | 76 | memcpy (&seek, cdata, sizeof (seek)); |
73 | plugin->seek_request = -1; | 77 | plugin->seek_request = (int64_t) seek.file_offset; |
74 | return ret; | 78 | plugin->seek_whence = seek.whence; |
75 | } | 79 | ret += sizeof (struct SeekRequestMessage); |
76 | memcpy (&seek, cdata, sizeof (seek)); | 80 | data += sizeof (struct SeekRequestMessage); |
77 | plugin->seek_request = (int64_t) seek.file_offset; | 81 | size -= sizeof (struct SeekRequestMessage); |
78 | plugin->seek_whence = seek.whence; | 82 | continue; |
79 | ret += sizeof (struct SeekRequestMessage); | 83 | case MESSAGE_META: /* Meta */ |
80 | data += sizeof (struct SeekRequestMessage); | 84 | if (size < sizeof (struct MetaMessage)) |
81 | size -= sizeof (struct SeekRequestMessage); | 85 | { |
82 | continue; | 86 | plugin->seek_request = -1; |
83 | case MESSAGE_META: /* Meta */ | 87 | return ret; |
84 | if (size < sizeof (struct MetaMessage)) | 88 | } |
85 | { | 89 | memcpy (&meta, cdata, sizeof (meta)); |
86 | plugin->seek_request = -1; | 90 | /* check hdr for sanity */ |
87 | return ret; | 91 | if (meta.value_size > MAX_META_DATA) |
88 | } | 92 | { |
89 | memcpy (&meta, cdata, sizeof (meta)); | 93 | LOG ("Meta data exceeds size limit\n"); |
90 | /* check hdr for sanity */ | 94 | return -1; /* not allowing more than MAX_META_DATA meta data */ |
91 | if (meta.value_size > MAX_META_DATA) | 95 | } |
92 | { | 96 | if (size < sizeof (meta) + meta.mime_length + meta.value_size) |
93 | LOG ("Meta data exceeds size limit\n"); | 97 | { |
94 | return -1; /* not allowing more than MAX_META_DATA meta data */ | 98 | plugin->seek_request = -1; |
95 | } | 99 | return ret; |
96 | if (size < sizeof (meta) + meta.mime_length + meta.value_size) | 100 | } |
97 | { | 101 | if (0 == meta.mime_length) |
98 | plugin->seek_request = -1; | 102 | { |
99 | return ret; | 103 | mime_type = NULL; |
100 | } | 104 | } |
101 | if (0 == meta.mime_length) | 105 | else |
102 | { | 106 | { |
103 | mime_type = NULL; | 107 | mime_type = &cdata[sizeof (struct MetaMessage)]; |
104 | } | 108 | if ('\0' != mime_type[meta.mime_length - 1]) |
105 | else | 109 | { |
106 | { | 110 | LOG ("Mime type not 0-terminated\n"); |
107 | mime_type = &cdata[sizeof (struct MetaMessage)]; | 111 | return -1; |
108 | if ('\0' != mime_type[meta.mime_length - 1]) | 112 | } |
109 | { | 113 | } |
110 | LOG ("Mime type not 0-terminated\n"); | 114 | if (0 == meta.value_size) |
111 | return -1; | 115 | value = NULL; |
112 | } | 116 | else |
113 | } | 117 | value = &cdata[sizeof (struct MetaMessage) + meta.mime_length]; |
114 | if (0 == meta.value_size) | 118 | if (meta.meta_type >= EXTRACTOR_metatype_get_max ()) |
115 | value = NULL; | 119 | meta.meta_type = EXTRACTOR_METATYPE_UNKNOWN; |
116 | else | 120 | proc (proc_cls, |
117 | value = &cdata[sizeof (struct MetaMessage) + meta.mime_length]; | 121 | plugin, |
118 | if (meta.meta_type >= EXTRACTOR_metatype_get_max ()) | 122 | (enum EXTRACTOR_MetaType) meta.meta_type, |
119 | meta.meta_type = EXTRACTOR_METATYPE_UNKNOWN; | 123 | (enum EXTRACTOR_MetaFormat) meta.meta_format, |
120 | proc (proc_cls, | 124 | mime_type, value, meta.value_size); |
121 | plugin, | 125 | ret += sizeof (struct MetaMessage) + meta.mime_length + meta.value_size; |
122 | (enum EXTRACTOR_MetaType) meta.meta_type, | 126 | size -= sizeof (struct MetaMessage) + meta.mime_length + meta.value_size; |
123 | (enum EXTRACTOR_MetaFormat) meta.meta_format, | 127 | data += sizeof (struct MetaMessage) + meta.mime_length + meta.value_size; |
124 | mime_type, value, meta.value_size); | 128 | continue; |
125 | ret += sizeof (struct MetaMessage) + meta.mime_length + meta.value_size; | 129 | default: |
126 | size -= sizeof (struct MetaMessage) + meta.mime_length + meta.value_size; | 130 | LOG ("Invalid message type %d\n", (int) code); |
127 | data += sizeof (struct MetaMessage) + meta.mime_length + meta.value_size; | 131 | return -1; |
128 | continue; | ||
129 | default: | ||
130 | LOG ("Invalid message type %d\n", (int) code); | ||
131 | return -1; | ||
132 | } | ||
133 | } | 132 | } |
133 | } | ||
134 | return ret; | 134 | return ret; |
135 | } | 135 | } |
136 | 136 | ||
137 | |||
137 | /* end of extractor_ipc.c */ | 138 | /* end of extractor_ipc.c */ |
diff --git a/src/main/extractor_ipc.h b/src/main/extractor_ipc.h index 0109b66..8e7fe09 100644 --- a/src/main/extractor_ipc.h +++ b/src/main/extractor_ipc.h | |||
@@ -27,7 +27,7 @@ | |||
27 | * as follows. Each message begins with a 1-character opcode which | 27 | * as follows. Each message begins with a 1-character opcode which |
28 | * specifies the message type. The main library starts the plugins | 28 | * specifies the message type. The main library starts the plugins |
29 | * by forking the helper process and establishes two pipes for | 29 | * by forking the helper process and establishes two pipes for |
30 | * communication in both directions. | 30 | * communication in both directions. |
31 | * First, the main library send an 'INIT_STATE' message | 31 | * First, the main library send an 'INIT_STATE' message |
32 | * to the plugin. The start message specifies the name (and size) | 32 | * to the plugin. The start message specifies the name (and size) |
33 | * of a shared memory segment which will contain parts of the (uncompressed) | 33 | * of a shared memory segment which will contain parts of the (uncompressed) |
@@ -39,7 +39,7 @@ | |||
39 | * size of the file (or -1 if unknown) and the number of bytes | 39 | * size of the file (or -1 if unknown) and the number of bytes |
40 | * ready in the shared memory segment. The plugin then answers | 40 | * ready in the shared memory segment. The plugin then answers |
41 | * with either: | 41 | * with either: |
42 | * 1) MESSAGE_DONE to indicate that no further processing is | 42 | * 1) MESSAGE_DONE to indicate that no further processing is |
43 | * required for this file; the IPC continues with the | 43 | * required for this file; the IPC continues with the |
44 | * EXTRACT_START message for the next file afterwards; | 44 | * EXTRACT_START message for the next file afterwards; |
45 | * 2) MESSAGE_SEEK to indicate that the plugin would like to | 45 | * 2) MESSAGE_SEEK to indicate that the plugin would like to |
@@ -161,7 +161,7 @@ struct StartMessage | |||
161 | 161 | ||
162 | /** | 162 | /** |
163 | * Sent from LE to a plugin to tell it that shm contents | 163 | * Sent from LE to a plugin to tell it that shm contents |
164 | * were updated. | 164 | * were updated. |
165 | */ | 165 | */ |
166 | #define MESSAGE_UPDATED_SHM 0x02 | 166 | #define MESSAGE_UPDATED_SHM 0x02 |
167 | 167 | ||
@@ -245,7 +245,7 @@ struct SeekRequestMessage | |||
245 | /** | 245 | /** |
246 | * Requested offset; a positive value from the end of the | 246 | * Requested offset; a positive value from the end of the |
247 | * file is used of 'whence' is SEEK_END; a postive value | 247 | * file is used of 'whence' is SEEK_END; a postive value |
248 | * from the start is used of 'whence' is SEEK_SET. | 248 | * from the start is used of 'whence' is SEEK_SET. |
249 | * 'SEEK_CUR' is never used. | 249 | * 'SEEK_CUR' is never used. |
250 | */ | 250 | */ |
251 | uint64_t file_offset; | 251 | uint64_t file_offset; |
@@ -292,9 +292,9 @@ struct MetaMessage | |||
292 | */ | 292 | */ |
293 | uint32_t value_size; | 293 | uint32_t value_size; |
294 | 294 | ||
295 | /* followed by mime_length bytes of 0-terminated | 295 | /* followed by mime_length bytes of 0-terminated |
296 | mime-type (unless mime_length is 0) */ | 296 | mime-type (unless mime_length is 0) */ |
297 | 297 | ||
298 | /* followed by value_size bytes of value */ | 298 | /* followed by value_size bytes of value */ |
299 | 299 | ||
300 | }; | 300 | }; |
@@ -355,7 +355,7 @@ EXTRACTOR_IPC_shared_memory_destroy_ (struct EXTRACTOR_SharedMemory *shm); | |||
355 | */ | 355 | */ |
356 | unsigned int | 356 | unsigned int |
357 | EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm, | 357 | EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm, |
358 | int delta); | 358 | int delta); |
359 | 359 | ||
360 | 360 | ||
361 | /** | 361 | /** |
@@ -369,9 +369,9 @@ EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm, | |||
369 | */ | 369 | */ |
370 | ssize_t | 370 | ssize_t |
371 | EXTRACTOR_IPC_shared_memory_set_ (struct EXTRACTOR_SharedMemory *shm, | 371 | EXTRACTOR_IPC_shared_memory_set_ (struct EXTRACTOR_SharedMemory *shm, |
372 | struct EXTRACTOR_Datasource *ds, | 372 | struct EXTRACTOR_Datasource *ds, |
373 | uint64_t off, | 373 | uint64_t off, |
374 | size_t size); | 374 | size_t size); |
375 | 375 | ||
376 | 376 | ||
377 | /** | 377 | /** |
@@ -391,10 +391,10 @@ EXTRACTOR_datasource_get_pos_ (struct EXTRACTOR_Datasource *ds); | |||
391 | * @param plugin the plugin | 391 | * @param plugin the plugin |
392 | * @param shm memory to share with the process | 392 | * @param shm memory to share with the process |
393 | * @return NULL on error, otherwise IPC channel | 393 | * @return NULL on error, otherwise IPC channel |
394 | */ | 394 | */ |
395 | struct EXTRACTOR_Channel * | 395 | struct EXTRACTOR_Channel * |
396 | EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | 396 | EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, |
397 | struct EXTRACTOR_SharedMemory *shm); | 397 | struct EXTRACTOR_SharedMemory *shm); |
398 | 398 | ||
399 | 399 | ||
400 | /** | 400 | /** |
@@ -418,8 +418,8 @@ EXTRACTOR_IPC_channel_destroy_ (struct EXTRACTOR_Channel *channel); | |||
418 | */ | 418 | */ |
419 | ssize_t | 419 | ssize_t |
420 | EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, | 420 | EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, |
421 | const void *data, | 421 | const void *data, |
422 | size_t size); | 422 | size_t size); |
423 | 423 | ||
424 | 424 | ||
425 | /** | 425 | /** |
@@ -434,12 +434,15 @@ EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, | |||
434 | * @param value_len number of bytes in 'value' | 434 | * @param value_len number of bytes in 'value' |
435 | */ | 435 | */ |
436 | typedef void (*EXTRACTOR_ChannelMessageProcessor) (void *cls, | 436 | typedef void (*EXTRACTOR_ChannelMessageProcessor) (void *cls, |
437 | struct EXTRACTOR_PluginList *plugin, | 437 | struct EXTRACTOR_PluginList * |
438 | enum EXTRACTOR_MetaType meta_type, | 438 | plugin, |
439 | enum EXTRACTOR_MetaFormat meta_format, | 439 | enum EXTRACTOR_MetaType |
440 | const char *mime, | 440 | meta_type, |
441 | const void *value, | 441 | enum EXTRACTOR_MetaFormat |
442 | size_t value_len); | 442 | meta_format, |
443 | const char *mime, | ||
444 | const void *value, | ||
445 | size_t value_len); | ||
443 | 446 | ||
444 | 447 | ||
445 | /** | 448 | /** |
@@ -454,10 +457,10 @@ typedef void (*EXTRACTOR_ChannelMessageProcessor) (void *cls, | |||
454 | */ | 457 | */ |
455 | ssize_t | 458 | ssize_t |
456 | EXTRACTOR_IPC_process_reply_ (struct EXTRACTOR_PluginList *plugin, | 459 | EXTRACTOR_IPC_process_reply_ (struct EXTRACTOR_PluginList *plugin, |
457 | const void *data, | 460 | const void *data, |
458 | size_t size, | 461 | size_t size, |
459 | EXTRACTOR_ChannelMessageProcessor proc, | 462 | EXTRACTOR_ChannelMessageProcessor proc, |
460 | void *proc_cls); | 463 | void *proc_cls); |
461 | 464 | ||
462 | 465 | ||
463 | /** | 466 | /** |
@@ -473,9 +476,9 @@ EXTRACTOR_IPC_process_reply_ (struct EXTRACTOR_PluginList *plugin, | |||
473 | */ | 476 | */ |
474 | int | 477 | int |
475 | EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, | 478 | EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, |
476 | unsigned int num_channels, | 479 | unsigned int num_channels, |
477 | EXTRACTOR_ChannelMessageProcessor proc, | 480 | EXTRACTOR_ChannelMessageProcessor proc, |
478 | void *proc_cls); | 481 | void *proc_cls); |
479 | 482 | ||
480 | 483 | ||
481 | #endif | 484 | #endif |
diff --git a/src/main/extractor_ipc_gnu.c b/src/main/extractor_ipc_gnu.c index 7bb8914..5400636 100644 --- a/src/main/extractor_ipc_gnu.c +++ b/src/main/extractor_ipc_gnu.c | |||
@@ -138,10 +138,10 @@ EXTRACTOR_IPC_shared_memory_create_ (size_t size) | |||
138 | const char *tpath; | 138 | const char *tpath; |
139 | 139 | ||
140 | if (NULL == (shm = malloc (sizeof (struct EXTRACTOR_SharedMemory)))) | 140 | if (NULL == (shm = malloc (sizeof (struct EXTRACTOR_SharedMemory)))) |
141 | { | 141 | { |
142 | LOG_STRERROR ("malloc"); | 142 | LOG_STRERROR ("malloc"); |
143 | return NULL; | 143 | return NULL; |
144 | } | 144 | } |
145 | #if SOMEBSD | 145 | #if SOMEBSD |
146 | /* this works on FreeBSD, not sure about others... */ | 146 | /* this works on FreeBSD, not sure about others... */ |
147 | tpath = getenv ("TMPDIR"); | 147 | tpath = getenv ("TMPDIR"); |
@@ -151,24 +151,24 @@ EXTRACTOR_IPC_shared_memory_create_ (size_t size) | |||
151 | tpath = "/"; /* Linux */ | 151 | tpath = "/"; /* Linux */ |
152 | #endif | 152 | #endif |
153 | snprintf (shm->shm_name, | 153 | snprintf (shm->shm_name, |
154 | MAX_SHM_NAME, | 154 | MAX_SHM_NAME, |
155 | "%sLE-%u-%u", | 155 | "%sLE-%u-%u", |
156 | tpath, getpid (), | 156 | tpath, getpid (), |
157 | (unsigned int) RANDOM()); | 157 | (unsigned int) RANDOM ()); |
158 | if (-1 == (shm->shm_id = shm_open (shm->shm_name, | 158 | if (-1 == (shm->shm_id = shm_open (shm->shm_name, |
159 | O_RDWR | O_CREAT, S_IRUSR | S_IWUSR))) | 159 | O_RDWR | O_CREAT, S_IRUSR | S_IWUSR))) |
160 | { | 160 | { |
161 | LOG_STRERROR_FILE ("shm_open", | 161 | LOG_STRERROR_FILE ("shm_open", |
162 | shm->shm_name); | 162 | shm->shm_name); |
163 | free (shm); | 163 | free (shm); |
164 | return NULL; | 164 | return NULL; |
165 | } | 165 | } |
166 | if ( (0 != ftruncate (shm->shm_id, size)) || | 166 | if ( (0 != ftruncate (shm->shm_id, size)) || |
167 | (NULL == (shm->shm_ptr = mmap (NULL, | 167 | (NULL == (shm->shm_ptr = mmap (NULL, |
168 | size, | 168 | size, |
169 | PROT_WRITE, | 169 | PROT_WRITE, |
170 | MAP_SHARED, | 170 | MAP_SHARED, |
171 | shm->shm_id, | 171 | shm->shm_id, |
172 | 0))) || | 172 | 0))) || |
173 | (((void*) -1) == shm->shm_ptr) ) | 173 | (((void*) -1) == shm->shm_ptr) ) |
174 | { | 174 | { |
@@ -193,7 +193,7 @@ EXTRACTOR_IPC_shared_memory_create_ (size_t size) | |||
193 | */ | 193 | */ |
194 | unsigned int | 194 | unsigned int |
195 | EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm, | 195 | EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm, |
196 | int delta) | 196 | int delta) |
197 | { | 197 | { |
198 | shm->rc += delta; | 198 | shm->rc += delta; |
199 | return shm->rc; | 199 | return shm->rc; |
@@ -228,23 +228,23 @@ EXTRACTOR_IPC_shared_memory_destroy_ (struct EXTRACTOR_SharedMemory *shm) | |||
228 | */ | 228 | */ |
229 | ssize_t | 229 | ssize_t |
230 | EXTRACTOR_IPC_shared_memory_set_ (struct EXTRACTOR_SharedMemory *shm, | 230 | EXTRACTOR_IPC_shared_memory_set_ (struct EXTRACTOR_SharedMemory *shm, |
231 | struct EXTRACTOR_Datasource *ds, | 231 | struct EXTRACTOR_Datasource *ds, |
232 | uint64_t off, | 232 | uint64_t off, |
233 | size_t size) | 233 | size_t size) |
234 | { | 234 | { |
235 | if (-1 == | 235 | if (-1 == |
236 | EXTRACTOR_datasource_seek_ (ds, | 236 | EXTRACTOR_datasource_seek_ (ds, |
237 | off, | 237 | off, |
238 | SEEK_SET)) | 238 | SEEK_SET)) |
239 | { | 239 | { |
240 | LOG ("Failed to set IPC memory due to seek error\n"); | 240 | LOG ("Failed to set IPC memory due to seek error\n"); |
241 | return -1; | 241 | return -1; |
242 | } | 242 | } |
243 | if (size > shm->shm_size) | 243 | if (size > shm->shm_size) |
244 | size = shm->shm_size; | 244 | size = shm->shm_size; |
245 | return EXTRACTOR_datasource_read_ (ds, | 245 | return EXTRACTOR_datasource_read_ (ds, |
246 | shm->shm_ptr, | 246 | shm->shm_ptr, |
247 | size); | 247 | size); |
248 | } | 248 | } |
249 | 249 | ||
250 | 250 | ||
@@ -277,7 +277,7 @@ EXTRACTOR_datasource_get_pos_ (struct EXTRACTOR_Datasource *ds) | |||
277 | */ | 277 | */ |
278 | struct EXTRACTOR_Channel * | 278 | struct EXTRACTOR_Channel * |
279 | EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | 279 | EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, |
280 | struct EXTRACTOR_SharedMemory *shm) | 280 | struct EXTRACTOR_SharedMemory *shm) |
281 | { | 281 | { |
282 | struct EXTRACTOR_Channel *channel; | 282 | struct EXTRACTOR_Channel *channel; |
283 | int p1[2]; | 283 | int p1[2]; |
@@ -287,74 +287,74 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
287 | size_t slen; | 287 | size_t slen; |
288 | 288 | ||
289 | if (NULL == (channel = malloc (sizeof (struct EXTRACTOR_Channel)))) | 289 | if (NULL == (channel = malloc (sizeof (struct EXTRACTOR_Channel)))) |
290 | { | 290 | { |
291 | LOG_STRERROR ("malloc"); | 291 | LOG_STRERROR ("malloc"); |
292 | return NULL; | 292 | return NULL; |
293 | } | 293 | } |
294 | channel->mdata_size = 1024; | 294 | channel->mdata_size = 1024; |
295 | if (NULL == (channel->mdata = malloc (channel->mdata_size))) | 295 | if (NULL == (channel->mdata = malloc (channel->mdata_size))) |
296 | { | 296 | { |
297 | LOG_STRERROR ("malloc"); | 297 | LOG_STRERROR ("malloc"); |
298 | free (channel); | 298 | free (channel); |
299 | return NULL; | 299 | return NULL; |
300 | } | 300 | } |
301 | channel->shm = shm; | 301 | channel->shm = shm; |
302 | channel->plugin = plugin; | 302 | channel->plugin = plugin; |
303 | channel->size = 0; | 303 | channel->size = 0; |
304 | if (0 != pipe (p1)) | 304 | if (0 != pipe (p1)) |
305 | { | 305 | { |
306 | LOG_STRERROR ("pipe"); | 306 | LOG_STRERROR ("pipe"); |
307 | free (channel->mdata); | 307 | free (channel->mdata); |
308 | free (channel); | 308 | free (channel); |
309 | return NULL; | 309 | return NULL; |
310 | } | 310 | } |
311 | if (0 != pipe (p2)) | 311 | if (0 != pipe (p2)) |
312 | { | 312 | { |
313 | LOG_STRERROR ("pipe"); | 313 | LOG_STRERROR ("pipe"); |
314 | (void) close (p1[0]); | 314 | (void) close (p1[0]); |
315 | (void) close (p1[1]); | 315 | (void) close (p1[1]); |
316 | free (channel->mdata); | 316 | free (channel->mdata); |
317 | free (channel); | 317 | free (channel); |
318 | return NULL; | 318 | return NULL; |
319 | } | 319 | } |
320 | pid = fork (); | 320 | pid = fork (); |
321 | if (pid == -1) | 321 | if (pid == -1) |
322 | { | 322 | { |
323 | LOG_STRERROR ("fork"); | 323 | LOG_STRERROR ("fork"); |
324 | (void) close (p1[0]); | 324 | (void) close (p1[0]); |
325 | (void) close (p1[1]); | 325 | (void) close (p1[1]); |
326 | (void) close (p2[0]); | 326 | (void) close (p2[0]); |
327 | (void) close (p2[1]); | 327 | (void) close (p2[1]); |
328 | free (channel->mdata); | 328 | free (channel->mdata); |
329 | free (channel); | 329 | free (channel); |
330 | return NULL; | 330 | return NULL; |
331 | } | 331 | } |
332 | if (0 == pid) | 332 | if (0 == pid) |
333 | { | 333 | { |
334 | (void) close (p1[1]); | 334 | (void) close (p1[1]); |
335 | (void) close (p2[0]); | 335 | (void) close (p2[0]); |
336 | free (channel->mdata); | 336 | free (channel->mdata); |
337 | free (channel); | 337 | free (channel); |
338 | #if HAVE_SYS_APPARMOR_H | 338 | #if HAVE_SYS_APPARMOR_H |
339 | #if HAVE_APPARMOR | 339 | #if HAVE_APPARMOR |
340 | if (0 > aa_change_profile("libextractor")) | 340 | if (0 > aa_change_profile ("libextractor")) |
341 | { | ||
342 | int eno = errno; | ||
343 | |||
344 | if ( (EINVAL != eno) && | ||
345 | (ENOENT != eno) ) | ||
341 | { | 346 | { |
342 | int eno = errno; | 347 | fprintf (stderr, |
343 | 348 | "Failure changing AppArmor profile: %s\n", | |
344 | if ( (EINVAL != eno) && | 349 | strerror (errno)); |
345 | (ENOENT != eno) ) | 350 | _exit (1); |
346 | { | ||
347 | fprintf (stderr, | ||
348 | "Failure changing AppArmor profile: %s\n", | ||
349 | strerror (errno)); | ||
350 | _exit(1); | ||
351 | } | ||
352 | } | 351 | } |
352 | } | ||
353 | #endif | 353 | #endif |
354 | #endif | 354 | #endif |
355 | EXTRACTOR_plugin_main_ (plugin, p1[0], p2[1]); | 355 | EXTRACTOR_plugin_main_ (plugin, p1[0], p2[1]); |
356 | _exit (0); | 356 | _exit (0); |
357 | } | 357 | } |
358 | (void) close (p1[0]); | 358 | (void) close (p1[0]); |
359 | (void) close (p2[1]); | 359 | (void) close (p2[1]); |
360 | channel->cpipe_in = p1[1]; | 360 | channel->cpipe_in = p1[1]; |
@@ -362,11 +362,11 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
362 | channel->cpid = pid; | 362 | channel->cpid = pid; |
363 | slen = strlen (shm->shm_name) + 1; | 363 | slen = strlen (shm->shm_name) + 1; |
364 | if (NULL == (init = malloc (sizeof (struct InitMessage) + slen))) | 364 | if (NULL == (init = malloc (sizeof (struct InitMessage) + slen))) |
365 | { | 365 | { |
366 | LOG_STRERROR ("malloc"); | 366 | LOG_STRERROR ("malloc"); |
367 | EXTRACTOR_IPC_channel_destroy_ (channel); | 367 | EXTRACTOR_IPC_channel_destroy_ (channel); |
368 | return NULL; | 368 | return NULL; |
369 | } | 369 | } |
370 | init->opcode = MESSAGE_INIT_STATE; | 370 | init->opcode = MESSAGE_INIT_STATE; |
371 | init->reserved = 0; | 371 | init->reserved = 0; |
372 | init->reserved2 = 0; | 372 | init->reserved2 = 0; |
@@ -375,14 +375,14 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
375 | memcpy (&init[1], shm->shm_name, slen); | 375 | memcpy (&init[1], shm->shm_name, slen); |
376 | if (sizeof (struct InitMessage) + slen != | 376 | if (sizeof (struct InitMessage) + slen != |
377 | EXTRACTOR_IPC_channel_send_ (channel, | 377 | EXTRACTOR_IPC_channel_send_ (channel, |
378 | init, | 378 | init, |
379 | sizeof (struct InitMessage) + slen) ) | 379 | sizeof (struct InitMessage) + slen) ) |
380 | { | 380 | { |
381 | LOG ("Failed to send INIT_STATE message to plugin\n"); | 381 | LOG ("Failed to send INIT_STATE message to plugin\n"); |
382 | EXTRACTOR_IPC_channel_destroy_ (channel); | 382 | EXTRACTOR_IPC_channel_destroy_ (channel); |
383 | free (init); | 383 | free (init); |
384 | return NULL; | 384 | return NULL; |
385 | } | 385 | } |
386 | free (init); | 386 | free (init); |
387 | return channel; | 387 | return channel; |
388 | } | 388 | } |
@@ -425,24 +425,24 @@ EXTRACTOR_IPC_channel_destroy_ (struct EXTRACTOR_Channel *channel) | |||
425 | */ | 425 | */ |
426 | ssize_t | 426 | ssize_t |
427 | EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, | 427 | EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, |
428 | const void *data, | 428 | const void *data, |
429 | size_t size) | 429 | size_t size) |
430 | { | 430 | { |
431 | const char *cdata = data; | 431 | const char *cdata = data; |
432 | size_t off = 0; | 432 | size_t off = 0; |
433 | ssize_t ret; | 433 | ssize_t ret; |
434 | 434 | ||
435 | while (off < size) | 435 | while (off < size) |
436 | { | ||
437 | ret = write (channel->cpipe_in, &cdata[off], size - off); | ||
438 | if (ret <= 0) | ||
436 | { | 439 | { |
437 | ret = write (channel->cpipe_in, &cdata[off], size - off); | 440 | if (-1 == ret) |
438 | if (ret <= 0) | 441 | LOG_STRERROR ("write"); |
439 | { | 442 | return -1; |
440 | if (-1 == ret) | ||
441 | LOG_STRERROR ("write"); | ||
442 | return -1; | ||
443 | } | ||
444 | off += ret; | ||
445 | } | 443 | } |
444 | off += ret; | ||
445 | } | ||
446 | return size; | 446 | return size; |
447 | } | 447 | } |
448 | 448 | ||
@@ -464,9 +464,9 @@ EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, | |||
464 | */ | 464 | */ |
465 | int | 465 | int |
466 | EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, | 466 | EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, |
467 | unsigned int num_channels, | 467 | unsigned int num_channels, |
468 | EXTRACTOR_ChannelMessageProcessor proc, | 468 | EXTRACTOR_ChannelMessageProcessor proc, |
469 | void *proc_cls) | 469 | void *proc_cls) |
470 | { | 470 | { |
471 | struct timeval tv; | 471 | struct timeval tv; |
472 | fd_set to_check; | 472 | fd_set to_check; |
@@ -480,105 +480,106 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, | |||
480 | 480 | ||
481 | FD_ZERO (&to_check); | 481 | FD_ZERO (&to_check); |
482 | max = -1; | 482 | max = -1; |
483 | for (i=0;i<num_channels;i++) | 483 | for (i = 0; i<num_channels; i++) |
484 | { | ||
485 | channel = channels[i]; | ||
486 | if (NULL == channel) | ||
487 | continue; | ||
488 | FD_SET (channel->cpipe_out, &to_check); | ||
489 | if (max < channel->cpipe_out) | ||
490 | max = channel->cpipe_out; | ||
491 | } | ||
492 | if (-1 == max) | ||
493 | { | ||
494 | return 1; /* nothing left to do! */ | ||
495 | } | ||
496 | tv.tv_sec = 0; | ||
497 | tv.tv_usec = 500000; /* 500 ms */ | ||
498 | if (0 >= select (max + 1, &to_check, NULL, NULL, &tv)) | ||
499 | { | ||
500 | /* an error or timeout -> something's wrong or all plugins hung up */ | ||
501 | closed_channel = 0; | ||
502 | for (i = 0; i<num_channels; i++) | ||
484 | { | 503 | { |
485 | channel = channels[i]; | 504 | channel = channels[i]; |
486 | if (NULL == channel) | 505 | if (NULL == channel) |
487 | continue; | 506 | continue; |
488 | FD_SET (channel->cpipe_out, &to_check); | 507 | if (-1 == channel->plugin->seek_request) |
489 | if (max < channel->cpipe_out) | 508 | { |
490 | max = channel->cpipe_out; | 509 | /* plugin blocked for too long, kill channel */ |
510 | LOG ("Channel blocked, closing channel to %s\n", | ||
511 | channel->plugin->libname); | ||
512 | channel->plugin->channel = NULL; | ||
513 | channel->plugin->round_finished = 1; | ||
514 | EXTRACTOR_IPC_channel_destroy_ (channel); | ||
515 | channels[i] = NULL; | ||
516 | closed_channel = 1; | ||
517 | } | ||
491 | } | 518 | } |
492 | if (-1 == max) | 519 | if (1 == closed_channel) |
520 | return 1; | ||
521 | /* strange, no channel is to blame, let's die just to be safe */ | ||
522 | if ((EINTR != errno) && (0 != errno)) | ||
523 | LOG_STRERROR ("select"); | ||
524 | return -1; | ||
525 | } | ||
526 | for (i = 0; i<num_channels; i++) | ||
527 | { | ||
528 | channel = channels[i]; | ||
529 | if (NULL == channel) | ||
530 | continue; | ||
531 | if (! FD_ISSET (channel->cpipe_out, &to_check)) | ||
532 | continue; | ||
533 | if (channel->mdata_size == channel->size) | ||
493 | { | 534 | { |
494 | return 1; /* nothing left to do! */ | 535 | /* not enough space, need to grow allocation (if allowed) */ |
536 | if (MAX_META_DATA == channel->mdata_size) | ||
537 | { | ||
538 | LOG ("Inbound message from channel too large, aborting\n"); | ||
539 | EXTRACTOR_IPC_channel_destroy_ (channel); | ||
540 | channels[i] = NULL; | ||
541 | continue; | ||
542 | } | ||
543 | channel->mdata_size *= 2; | ||
544 | if (channel->mdata_size > MAX_META_DATA) | ||
545 | channel->mdata_size = MAX_META_DATA; | ||
546 | if (NULL == (ndata = realloc (channel->mdata, | ||
547 | channel->mdata_size))) | ||
548 | { | ||
549 | LOG_STRERROR ("realloc"); | ||
550 | EXTRACTOR_IPC_channel_destroy_ (channel); | ||
551 | channels[i] = NULL; | ||
552 | continue; | ||
553 | } | ||
554 | channel->mdata = ndata; | ||
495 | } | 555 | } |
496 | tv.tv_sec = 0; | 556 | if ( (-1 == (iret = read (channel->cpipe_out, |
497 | tv.tv_usec = 500000; /* 500 ms */ | 557 | &channel->mdata[channel->size], |
498 | if (0 >= select (max + 1, &to_check, NULL, NULL, &tv)) | 558 | channel->mdata_size - channel->size)) ) || |
559 | (0 == iret) || | ||
560 | (-1 == (ret = EXTRACTOR_IPC_process_reply_ (channel->plugin, | ||
561 | channel->mdata, | ||
562 | channel->size + iret, | ||
563 | proc, proc_cls)) ) ) | ||
499 | { | 564 | { |
500 | /* an error or timeout -> something's wrong or all plugins hung up */ | 565 | if (-1 == iret) |
501 | closed_channel = 0; | 566 | LOG_STRERROR ("read"); |
502 | for (i=0;i<num_channels;i++) | 567 | LOG ("Read error from channel, closing channel %s\n", |
503 | { | 568 | channel->plugin->libname); |
504 | channel = channels[i]; | 569 | EXTRACTOR_IPC_channel_destroy_ (channel); |
505 | if (NULL == channel) | 570 | channels[i] = NULL; |
506 | continue; | 571 | continue; |
507 | if (-1 == channel->plugin->seek_request) | ||
508 | { | ||
509 | /* plugin blocked for too long, kill channel */ | ||
510 | LOG ("Channel blocked, closing channel to %s\n", | ||
511 | channel->plugin->libname); | ||
512 | channel->plugin->channel = NULL; | ||
513 | channel->plugin->round_finished = 1; | ||
514 | EXTRACTOR_IPC_channel_destroy_ (channel); | ||
515 | channels[i] = NULL; | ||
516 | closed_channel = 1; | ||
517 | } | ||
518 | } | ||
519 | if (1 == closed_channel) | ||
520 | return 1; | ||
521 | /* strange, no channel is to blame, let's die just to be safe */ | ||
522 | if ((EINTR != errno) && (0 != errno)) | ||
523 | LOG_STRERROR ("select"); | ||
524 | return -1; | ||
525 | } | 572 | } |
526 | for (i=0;i<num_channels;i++) | 573 | else |
527 | { | 574 | { |
528 | channel = channels[i]; | 575 | channel->size = channel->size + iret - ret; |
529 | if (NULL == channel) | 576 | memmove (channel->mdata, |
530 | continue; | 577 | &channel->mdata[ret], |
531 | if (! FD_ISSET (channel->cpipe_out, &to_check)) | 578 | channel->size); |
532 | continue; | ||
533 | if (channel->mdata_size == channel->size) | ||
534 | { | ||
535 | /* not enough space, need to grow allocation (if allowed) */ | ||
536 | if (MAX_META_DATA == channel->mdata_size) | ||
537 | { | ||
538 | LOG ("Inbound message from channel too large, aborting\n"); | ||
539 | EXTRACTOR_IPC_channel_destroy_ (channel); | ||
540 | channels[i] = NULL; | ||
541 | continue; | ||
542 | } | ||
543 | channel->mdata_size *= 2; | ||
544 | if (channel->mdata_size > MAX_META_DATA) | ||
545 | channel->mdata_size = MAX_META_DATA; | ||
546 | if (NULL == (ndata = realloc (channel->mdata, | ||
547 | channel->mdata_size))) | ||
548 | { | ||
549 | LOG_STRERROR ("realloc"); | ||
550 | EXTRACTOR_IPC_channel_destroy_ (channel); | ||
551 | channels[i] = NULL; | ||
552 | continue; | ||
553 | } | ||
554 | channel->mdata = ndata; | ||
555 | } | ||
556 | if ( (-1 == (iret = read (channel->cpipe_out, | ||
557 | &channel->mdata[channel->size], | ||
558 | channel->mdata_size - channel->size)) ) || | ||
559 | (0 == iret) || | ||
560 | (-1 == (ret = EXTRACTOR_IPC_process_reply_ (channel->plugin, | ||
561 | channel->mdata, | ||
562 | channel->size + iret, | ||
563 | proc, proc_cls)) ) ) | ||
564 | { | ||
565 | if (-1 == iret) | ||
566 | LOG_STRERROR ("read"); | ||
567 | LOG ("Read error from channel, closing channel %s\n", | ||
568 | channel->plugin->libname); | ||
569 | EXTRACTOR_IPC_channel_destroy_ (channel); | ||
570 | channels[i] = NULL; | ||
571 | continue; | ||
572 | } | ||
573 | else | ||
574 | { | ||
575 | channel->size = channel->size + iret - ret; | ||
576 | memmove (channel->mdata, | ||
577 | &channel->mdata[ret], | ||
578 | channel->size); | ||
579 | } | ||
580 | } | 579 | } |
580 | } | ||
581 | return 1; | 581 | return 1; |
582 | } | 582 | } |
583 | 583 | ||
584 | |||
584 | /* end of extractor_ipc_gnu.c */ | 585 | /* end of extractor_ipc_gnu.c */ |
diff --git a/src/main/extractor_ipc_w32.c b/src/main/extractor_ipc_w32.c index c4fbf1b..b53bc3c 100644 --- a/src/main/extractor_ipc_w32.c +++ b/src/main/extractor_ipc_w32.c | |||
@@ -34,32 +34,32 @@ struct EXTRACTOR_SharedMemory | |||
34 | 34 | ||
35 | /** | 35 | /** |
36 | * W32 handle of the shm into which data is uncompressed | 36 | * W32 handle of the shm into which data is uncompressed |
37 | */ | 37 | */ |
38 | HANDLE map; | 38 | HANDLE map; |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * Name of the shm | 41 | * Name of the shm |
42 | */ | 42 | */ |
43 | char shm_name[MAX_SHM_NAME + 1]; | 43 | char shm_name[MAX_SHM_NAME + 1]; |
44 | 44 | ||
45 | /** | 45 | /** |
46 | * Pointer to the mapped region of the shm (covers the whole shm) | 46 | * Pointer to the mapped region of the shm (covers the whole shm) |
47 | */ | 47 | */ |
48 | void *ptr; | 48 | void *ptr; |
49 | 49 | ||
50 | /** | 50 | /** |
51 | * Position within shm | 51 | * Position within shm |
52 | */ | 52 | */ |
53 | int64_t pos; | 53 | int64_t pos; |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * Allocated size of the shm | 56 | * Allocated size of the shm |
57 | */ | 57 | */ |
58 | int64_t shm_size; | 58 | int64_t shm_size; |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * Number of bytes in shm (<= shm_size) | 61 | * Number of bytes in shm (<= shm_size) |
62 | */ | 62 | */ |
63 | size_t shm_buf_size; | 63 | size_t shm_buf_size; |
64 | 64 | ||
65 | size_t shm_map_size; | 65 | size_t shm_map_size; |
@@ -132,11 +132,11 @@ struct EXTRACTOR_Channel | |||
132 | */ | 132 | */ |
133 | char *mdata; | 133 | char *mdata; |
134 | 134 | ||
135 | /** | 135 | /** |
136 | * Size of the 'mdata' buffer. | 136 | * Size of the 'mdata' buffer. |
137 | */ | 137 | */ |
138 | size_t mdata_size; | 138 | size_t mdata_size; |
139 | 139 | ||
140 | /** | 140 | /** |
141 | * Number of valid bytes in the channel's buffer. | 141 | * Number of valid bytes in the channel's buffer. |
142 | */ | 142 | */ |
@@ -159,11 +159,12 @@ EXTRACTOR_IPC_shared_memory_create_ (size_t size) | |||
159 | if (NULL == (shm = malloc (sizeof (struct EXTRACTOR_SharedMemory)))) | 159 | if (NULL == (shm = malloc (sizeof (struct EXTRACTOR_SharedMemory)))) |
160 | return NULL; | 160 | return NULL; |
161 | 161 | ||
162 | snprintf (shm->shm_name, MAX_SHM_NAME, | 162 | snprintf (shm->shm_name, MAX_SHM_NAME, |
163 | "%slibextractor-shm-%u-%u", | 163 | "%slibextractor-shm-%u-%u", |
164 | tpath, getpid(), | 164 | tpath, getpid (), |
165 | (unsigned int) RANDOM()); | 165 | (unsigned int) RANDOM ()); |
166 | shm->map = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm->shm_name); | 166 | shm->map = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, |
167 | size, shm->shm_name); | ||
167 | shm->ptr = MapViewOfFile (shm->map, FILE_MAP_WRITE, 0, 0, size); | 168 | shm->ptr = MapViewOfFile (shm->map, FILE_MAP_WRITE, 0, 0, size); |
168 | if (shm->ptr == NULL) | 169 | if (shm->ptr == NULL) |
169 | { | 170 | { |
@@ -176,6 +177,7 @@ EXTRACTOR_IPC_shared_memory_create_ (size_t size) | |||
176 | return shm; | 177 | return shm; |
177 | } | 178 | } |
178 | 179 | ||
180 | |||
179 | /** | 181 | /** |
180 | * Change the reference counter for this shm instance. | 182 | * Change the reference counter for this shm instance. |
181 | * | 183 | * |
@@ -185,7 +187,7 @@ EXTRACTOR_IPC_shared_memory_create_ (size_t size) | |||
185 | */ | 187 | */ |
186 | unsigned int | 188 | unsigned int |
187 | EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm, | 189 | EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm, |
188 | int delta) | 190 | int delta) |
189 | { | 191 | { |
190 | shm->rc += delta; | 192 | shm->rc += delta; |
191 | return shm->rc; | 193 | return shm->rc; |
@@ -200,7 +202,7 @@ EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm, | |||
200 | */ | 202 | */ |
201 | void | 203 | void |
202 | EXTRACTOR_IPC_shared_memory_destroy_ (struct EXTRACTOR_SharedMemory *shm) | 204 | EXTRACTOR_IPC_shared_memory_destroy_ (struct EXTRACTOR_SharedMemory *shm) |
203 | { | 205 | { |
204 | if (shm->ptr != NULL) | 206 | if (shm->ptr != NULL) |
205 | UnmapViewOfFile (shm->ptr); | 207 | UnmapViewOfFile (shm->ptr); |
206 | if (shm->map != 0) | 208 | if (shm->map != 0) |
@@ -208,6 +210,7 @@ EXTRACTOR_IPC_shared_memory_destroy_ (struct EXTRACTOR_SharedMemory *shm) | |||
208 | free (shm); | 210 | free (shm); |
209 | } | 211 | } |
210 | 212 | ||
213 | |||
211 | /** | 214 | /** |
212 | * Initialize shared memory area from data source. | 215 | * Initialize shared memory area from data source. |
213 | * | 216 | * |
@@ -219,21 +222,21 @@ EXTRACTOR_IPC_shared_memory_destroy_ (struct EXTRACTOR_SharedMemory *shm) | |||
219 | */ | 222 | */ |
220 | ssize_t | 223 | ssize_t |
221 | EXTRACTOR_IPC_shared_memory_set_ (struct EXTRACTOR_SharedMemory *shm, | 224 | EXTRACTOR_IPC_shared_memory_set_ (struct EXTRACTOR_SharedMemory *shm, |
222 | struct EXTRACTOR_Datasource *ds, | 225 | struct EXTRACTOR_Datasource *ds, |
223 | uint64_t off, | 226 | uint64_t off, |
224 | size_t size) | 227 | size_t size) |
225 | { | 228 | { |
226 | if (-1 == | 229 | if (-1 == |
227 | EXTRACTOR_datasource_seek_ (ds, off, SEEK_SET)) | 230 | EXTRACTOR_datasource_seek_ (ds, off, SEEK_SET)) |
228 | { | 231 | { |
229 | LOG ("Failed to set IPC memory due to seek error\n"); | 232 | LOG ("Failed to set IPC memory due to seek error\n"); |
230 | return -1; | 233 | return -1; |
231 | } | 234 | } |
232 | if (size > shm->shm_size) | 235 | if (size > shm->shm_size) |
233 | size = shm->shm_size; | 236 | size = shm->shm_size; |
234 | return EXTRACTOR_datasource_read_ (ds, | 237 | return EXTRACTOR_datasource_read_ (ds, |
235 | shm->ptr, | 238 | shm->ptr, |
236 | size); | 239 | size); |
237 | } | 240 | } |
238 | 241 | ||
239 | 242 | ||
@@ -291,7 +294,7 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, | |||
291 | static volatile LONG pipe_unique_id; | 294 | static volatile LONG pipe_unique_id; |
292 | 295 | ||
293 | snprintf (pipename, sizeof pipename, "\\\\.\\pipe\\gnunet-%d-%ld", | 296 | snprintf (pipename, sizeof pipename, "\\\\.\\pipe\\gnunet-%d-%ld", |
294 | getpid (), InterlockedIncrement ((LONG *) & pipe_unique_id)); | 297 | getpid (), InterlockedIncrement ((LONG *) &pipe_unique_id)); |
295 | /* Use CreateNamedPipe instead of CreatePipe, because the latter | 298 | /* Use CreateNamedPipe instead of CreatePipe, because the latter |
296 | * returns a write handle that does not permit FILE_READ_ATTRIBUTES | 299 | * returns a write handle that does not permit FILE_READ_ATTRIBUTES |
297 | * access, on versions of win32 earlier than WinXP SP2. | 300 | * access, on versions of win32 earlier than WinXP SP2. |
@@ -300,8 +303,8 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, | |||
300 | * It's important to only allow a single instance, to ensure that | 303 | * It's important to only allow a single instance, to ensure that |
301 | * the pipe was not created earlier by some other process, even if | 304 | * the pipe was not created earlier by some other process, even if |
302 | * the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE | 305 | * the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE |
303 | * because that is only available for Win2k SP2 and WinXP. */ | 306 | * because that is only available for Win2k SP2 and WinXP. */read_pipe = CreateNamedPipeA (pipename, PIPE_ACCESS_INBOUND | dwReadMode, |
304 | read_pipe = CreateNamedPipeA (pipename, PIPE_ACCESS_INBOUND | dwReadMode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, /* max instances */ | 307 | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, /* max instances */ |
305 | psize, /* output buffer size */ | 308 | psize, /* output buffer size */ |
306 | psize, /* input buffer size */ | 309 | psize, /* input buffer size */ |
307 | NMPWAIT_USE_DEFAULT_WAIT, sa_ptr); | 310 | NMPWAIT_USE_DEFAULT_WAIT, sa_ptr); |
@@ -359,6 +362,7 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, | |||
359 | return 0; | 362 | return 0; |
360 | } | 363 | } |
361 | 364 | ||
365 | |||
362 | /** | 366 | /** |
363 | * Communicates plugin data (library name, options) to the plugin | 367 | * Communicates plugin data (library name, options) to the plugin |
364 | * process. This is only necessary on W32, where this information | 368 | * process. This is only necessary on W32, where this information |
@@ -367,10 +371,10 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, | |||
367 | * @param plugin plugin context | 371 | * @param plugin plugin context |
368 | * | 372 | * |
369 | * @return 0 on success, -1 on failure | 373 | * @return 0 on success, -1 on failure |
370 | */ | 374 | */ |
371 | static int | 375 | static int |
372 | write_plugin_data (struct EXTRACTOR_PluginList *plugin, | 376 | write_plugin_data (struct EXTRACTOR_PluginList *plugin, |
373 | struct EXTRACTOR_Channel *channel) | 377 | struct EXTRACTOR_Channel *channel) |
374 | { | 378 | { |
375 | size_t libname_len, shortname_len, opts_len; | 379 | size_t libname_len, shortname_len, opts_len; |
376 | DWORD len; | 380 | DWORD len; |
@@ -418,6 +422,7 @@ write_plugin_data (struct EXTRACTOR_PluginList *plugin, | |||
418 | return total_len == write_result; | 422 | return total_len == write_result; |
419 | } | 423 | } |
420 | 424 | ||
425 | |||
421 | /** | 426 | /** |
422 | * Create a channel to communicate with a process wrapping | 427 | * Create a channel to communicate with a process wrapping |
423 | * the plugin of the given name. Starts the process as well. | 428 | * the plugin of the given name. Starts the process as well. |
@@ -425,10 +430,10 @@ write_plugin_data (struct EXTRACTOR_PluginList *plugin, | |||
425 | * @param plugin the plugin | 430 | * @param plugin the plugin |
426 | * @param shm memory to share with the process | 431 | * @param shm memory to share with the process |
427 | * @return NULL on error, otherwise IPC channel | 432 | * @return NULL on error, otherwise IPC channel |
428 | */ | 433 | */ |
429 | struct EXTRACTOR_Channel * | 434 | struct EXTRACTOR_Channel * |
430 | EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | 435 | EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, |
431 | struct EXTRACTOR_SharedMemory *shm) | 436 | struct EXTRACTOR_SharedMemory *shm) |
432 | { | 437 | { |
433 | struct EXTRACTOR_Channel *channel; | 438 | struct EXTRACTOR_Channel *channel; |
434 | HANDLE p1[2]; | 439 | HANDLE p1[2]; |
@@ -445,18 +450,19 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
445 | SECURITY_ATTRIBUTES sa; | 450 | SECURITY_ATTRIBUTES sa; |
446 | 451 | ||
447 | if (NULL == (channel = malloc (sizeof (struct EXTRACTOR_Channel)))) | 452 | if (NULL == (channel = malloc (sizeof (struct EXTRACTOR_Channel)))) |
448 | { | 453 | { |
449 | LOG_STRERROR ("malloc"); | 454 | LOG_STRERROR ("malloc"); |
450 | return NULL; | 455 | return NULL; |
451 | } | 456 | } |
452 | memset (channel, 0, sizeof (struct EXTRACTOR_Channel)); | 457 | memset (channel, 0, sizeof (struct EXTRACTOR_Channel)); |
453 | channel->mdata_size = 1024; | 458 | channel->mdata_size = 1024; |
454 | if (NULL == (channel->mdata = malloc (channel->mdata_size))) | 459 | if (NULL == (channel->mdata = malloc (channel->mdata_size))) |
455 | { | 460 | { |
456 | LOG_STRERROR ("malloc"); | 461 | LOG_STRERROR ("malloc"); |
457 | free (channel); | 462 | free (channel); |
458 | return NULL; | 463 | return NULL; |
459 | } channel->shm = shm; | 464 | } |
465 | channel->shm = shm; | ||
460 | channel->plugin = plugin; | 466 | channel->plugin = plugin; |
461 | channel->size = 0; | 467 | channel->size = 0; |
462 | 468 | ||
@@ -464,13 +470,15 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
464 | sa.lpSecurityDescriptor = NULL; | 470 | sa.lpSecurityDescriptor = NULL; |
465 | sa.bInheritHandle = FALSE; | 471 | sa.bInheritHandle = FALSE; |
466 | 472 | ||
467 | if (0 != create_selectable_pipe (&p1[0], &p1[1], &sa, 1024, FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED)) | 473 | if (0 != create_selectable_pipe (&p1[0], &p1[1], &sa, 1024, |
474 | FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED)) | ||
468 | { | 475 | { |
469 | LOG_STRERROR ("pipe"); | 476 | LOG_STRERROR ("pipe"); |
470 | free (channel); | 477 | free (channel); |
471 | return NULL; | 478 | return NULL; |
472 | } | 479 | } |
473 | if (0 != create_selectable_pipe (&p2[0], &p2[1], &sa, 1024, FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED)) | 480 | if (0 != create_selectable_pipe (&p2[0], &p2[1], &sa, 1024, |
481 | FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED)) | ||
474 | { | 482 | { |
475 | LOG_STRERROR ("pipe"); | 483 | LOG_STRERROR ("pipe"); |
476 | CloseHandle (p1[0]); | 484 | CloseHandle (p1[0]); |
@@ -479,10 +487,10 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
479 | return NULL; | 487 | return NULL; |
480 | } | 488 | } |
481 | 489 | ||
482 | if (!DuplicateHandle (GetCurrentProcess (), p1[0], GetCurrentProcess (), | 490 | if (! DuplicateHandle (GetCurrentProcess (), p1[0], GetCurrentProcess (), |
483 | &p10_os_inh, 0, TRUE, DUPLICATE_SAME_ACCESS) | 491 | &p10_os_inh, 0, TRUE, DUPLICATE_SAME_ACCESS) |
484 | || !DuplicateHandle (GetCurrentProcess (), p2[1], GetCurrentProcess (), | 492 | || ! DuplicateHandle (GetCurrentProcess (), p2[1], GetCurrentProcess (), |
485 | &p21_os_inh, 0, TRUE, DUPLICATE_SAME_ACCESS)) | 493 | &p21_os_inh, 0, TRUE, DUPLICATE_SAME_ACCESS)) |
486 | { | 494 | { |
487 | LOG_STRERROR ("DuplicateHandle"); | 495 | LOG_STRERROR ("DuplicateHandle"); |
488 | if (p10_os_inh != INVALID_HANDLE_VALUE) | 496 | if (p10_os_inh != INVALID_HANDLE_VALUE) |
@@ -506,13 +514,13 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
506 | * Also, users might freak out seeing over 9000 rundll32 processes (seeing over 9000 processes named | 514 | * Also, users might freak out seeing over 9000 rundll32 processes (seeing over 9000 processes named |
507 | * "libextractor_plugin_helper" is probably less confusing). | 515 | * "libextractor_plugin_helper" is probably less confusing). |
508 | */ | 516 | */ |
509 | snprintf(cmd, MAX_PATH, | 517 | snprintf (cmd, MAX_PATH, |
510 | "rundll32.exe libextractor-3.dll,RundllEntryPoint@16 %lu %lu", | 518 | "rundll32.exe libextractor-3.dll,RundllEntryPoint@16 %lu %lu", |
511 | p10_os_inh, p21_os_inh); | 519 | p10_os_inh, p21_os_inh); |
512 | cmd[MAX_PATH] = '\0'; | 520 | cmd[MAX_PATH] = '\0'; |
513 | startup.cb = sizeof (STARTUPINFOA); | 521 | startup.cb = sizeof (STARTUPINFOA); |
514 | if (CreateProcessA (NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, | 522 | if (CreateProcessA (NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, |
515 | &startup, &proc)) | 523 | &startup, &proc)) |
516 | { | 524 | { |
517 | channel->hProcess = proc.hProcess; | 525 | channel->hProcess = proc.hProcess; |
518 | ResumeThread (proc.hThread); | 526 | ResumeThread (proc.hThread); |
@@ -544,7 +552,7 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
544 | channel->ov_write.hEvent = CreateEvent (NULL, TRUE, TRUE, NULL); | 552 | channel->ov_write.hEvent = CreateEvent (NULL, TRUE, TRUE, NULL); |
545 | channel->ov_read.hEvent = CreateEvent (NULL, TRUE, TRUE, NULL); | 553 | channel->ov_read.hEvent = CreateEvent (NULL, TRUE, TRUE, NULL); |
546 | 554 | ||
547 | if (!write_plugin_data (plugin, channel)) | 555 | if (! write_plugin_data (plugin, channel)) |
548 | { | 556 | { |
549 | LOG_STRERROR ("write_plugin_data"); | 557 | LOG_STRERROR ("write_plugin_data"); |
550 | EXTRACTOR_IPC_channel_destroy_ (channel); | 558 | EXTRACTOR_IPC_channel_destroy_ (channel); |
@@ -553,11 +561,11 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
553 | 561 | ||
554 | slen = strlen (shm->shm_name) + 1; | 562 | slen = strlen (shm->shm_name) + 1; |
555 | if (NULL == (init = malloc (sizeof (struct InitMessage) + slen))) | 563 | if (NULL == (init = malloc (sizeof (struct InitMessage) + slen))) |
556 | { | 564 | { |
557 | LOG_STRERROR ("malloc"); | 565 | LOG_STRERROR ("malloc"); |
558 | EXTRACTOR_IPC_channel_destroy_ (channel); | 566 | EXTRACTOR_IPC_channel_destroy_ (channel); |
559 | return NULL; | 567 | return NULL; |
560 | } | 568 | } |
561 | init->opcode = MESSAGE_INIT_STATE; | 569 | init->opcode = MESSAGE_INIT_STATE; |
562 | init->reserved = 0; | 570 | init->reserved = 0; |
563 | init->reserved2 = 0; | 571 | init->reserved2 = 0; |
@@ -566,17 +574,18 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, | |||
566 | memcpy (&init[1], shm->shm_name, slen); | 574 | memcpy (&init[1], shm->shm_name, slen); |
567 | if (sizeof (struct InitMessage) + slen != | 575 | if (sizeof (struct InitMessage) + slen != |
568 | EXTRACTOR_IPC_channel_send_ (channel, init, | 576 | EXTRACTOR_IPC_channel_send_ (channel, init, |
569 | sizeof (struct InitMessage) + slen)) | 577 | sizeof (struct InitMessage) + slen)) |
570 | { | 578 | { |
571 | LOG ("Failed to send INIT_STATE message to plugin\n"); | 579 | LOG ("Failed to send INIT_STATE message to plugin\n"); |
572 | EXTRACTOR_IPC_channel_destroy_ (channel); | 580 | EXTRACTOR_IPC_channel_destroy_ (channel); |
573 | free (init); | 581 | free (init); |
574 | return NULL; | 582 | return NULL; |
575 | } | 583 | } |
576 | free (init); | 584 | free (init); |
577 | return channel; | 585 | return channel; |
578 | } | 586 | } |
579 | 587 | ||
588 | |||
580 | /** | 589 | /** |
581 | * Destroy communication channel with a plugin/process. Also | 590 | * Destroy communication channel with a plugin/process. Also |
582 | * destroys the process. | 591 | * destroys the process. |
@@ -606,6 +615,7 @@ EXTRACTOR_IPC_channel_destroy_ (struct EXTRACTOR_Channel *channel) | |||
606 | free (channel); | 615 | free (channel); |
607 | } | 616 | } |
608 | 617 | ||
618 | |||
609 | /** | 619 | /** |
610 | * Send data via the given IPC channel (blocking). | 620 | * Send data via the given IPC channel (blocking). |
611 | * | 621 | * |
@@ -617,8 +627,8 @@ EXTRACTOR_IPC_channel_destroy_ (struct EXTRACTOR_Channel *channel) | |||
617 | */ | 627 | */ |
618 | ssize_t | 628 | ssize_t |
619 | EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, | 629 | EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, |
620 | const void *data, | 630 | const void *data, |
621 | size_t size) | 631 | size_t size) |
622 | { | 632 | { |
623 | DWORD written; | 633 | DWORD written; |
624 | DWORD err; | 634 | DWORD err; |
@@ -644,7 +654,8 @@ EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, | |||
644 | channel->ov_write.Pointer = 0; | 654 | channel->ov_write.Pointer = 0; |
645 | channel->ov_write.Internal = 0; | 655 | channel->ov_write.Internal = 0; |
646 | channel->ov_write.InternalHigh = 0; | 656 | channel->ov_write.InternalHigh = 0; |
647 | bresult = WriteFile (channel->cpipe_in, channel->old_buf, size, &written, &channel->ov_write); | 657 | bresult = WriteFile (channel->cpipe_in, channel->old_buf, size, &written, |
658 | &channel->ov_write); | ||
648 | 659 | ||
649 | if (bresult == TRUE) | 660 | if (bresult == TRUE) |
650 | { | 661 | { |
@@ -682,9 +693,9 @@ EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, | |||
682 | */ | 693 | */ |
683 | int | 694 | int |
684 | EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, | 695 | EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, |
685 | unsigned int num_channels, | 696 | unsigned int num_channels, |
686 | EXTRACTOR_ChannelMessageProcessor proc, | 697 | EXTRACTOR_ChannelMessageProcessor proc, |
687 | void *proc_cls) | 698 | void *proc_cls) |
688 | { | 699 | { |
689 | DWORD ms; | 700 | DWORD ms; |
690 | DWORD first_ready; | 701 | DWORD first_ready; |
@@ -707,7 +718,8 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, | |||
707 | if (WaitForSingleObject (channels[i]->ov_read.hEvent, 0) == WAIT_OBJECT_0) | 718 | if (WaitForSingleObject (channels[i]->ov_read.hEvent, 0) == WAIT_OBJECT_0) |
708 | { | 719 | { |
709 | ResetEvent (channels[i]->ov_read.hEvent); | 720 | ResetEvent (channels[i]->ov_read.hEvent); |
710 | bresult = ReadFile (channels[i]->cpipe_out, &i, 0, &bytes_read, &channels[i]->ov_read); | 721 | bresult = ReadFile (channels[i]->cpipe_out, &i, 0, &bytes_read, |
722 | &channels[i]->ov_read); | ||
711 | if (bresult == TRUE) | 723 | if (bresult == TRUE) |
712 | { | 724 | { |
713 | SetEvent (channels[i]->ov_read.hEvent); | 725 | SetEvent (channels[i]->ov_read.hEvent); |
@@ -728,7 +740,7 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, | |||
728 | 740 | ||
729 | ms = 500; | 741 | ms = 500; |
730 | first_ready = WaitForMultipleObjects (c, events, FALSE, ms); | 742 | first_ready = WaitForMultipleObjects (c, events, FALSE, ms); |
731 | if (first_ready == WAIT_TIMEOUT || first_ready == WAIT_FAILED) | 743 | if ((first_ready == WAIT_TIMEOUT) || (first_ready == WAIT_FAILED)) |
732 | { | 744 | { |
733 | /* an error or timeout -> something's wrong or all plugins hung up */ | 745 | /* an error or timeout -> something's wrong or all plugins hung up */ |
734 | closed_channel = 0; | 746 | closed_channel = 0; |
@@ -765,37 +777,40 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, | |||
765 | { | 777 | { |
766 | int ret; | 778 | int ret; |
767 | if (channels[i]->mdata_size == channels[i]->size) | 779 | if (channels[i]->mdata_size == channels[i]->size) |
768 | { | 780 | { |
769 | /* not enough space, need to grow allocation (if allowed) */ | 781 | /* not enough space, need to grow allocation (if allowed) */ |
770 | if (MAX_META_DATA == channels[i]->mdata_size) | 782 | if (MAX_META_DATA == channels[i]->mdata_size) |
771 | { | 783 | { |
772 | LOG ("Inbound message from channel too large, aborting\n"); | 784 | LOG ("Inbound message from channel too large, aborting\n"); |
773 | EXTRACTOR_IPC_channel_destroy_ (channels[i]); | 785 | EXTRACTOR_IPC_channel_destroy_ (channels[i]); |
774 | channels[i] = NULL; | 786 | channels[i] = NULL; |
775 | } | 787 | } |
776 | channels[i]->mdata_size *= 2; | 788 | channels[i]->mdata_size *= 2; |
777 | if (channels[i]->mdata_size > MAX_META_DATA) | 789 | if (channels[i]->mdata_size > MAX_META_DATA) |
778 | channels[i]->mdata_size = MAX_META_DATA; | 790 | channels[i]->mdata_size = MAX_META_DATA; |
779 | if (NULL == (ndata = realloc (channels[i]->mdata, | 791 | if (NULL == (ndata = realloc (channels[i]->mdata, |
780 | channels[i]->mdata_size))) | 792 | channels[i]->mdata_size))) |
781 | { | 793 | { |
782 | LOG_STRERROR ("realloc"); | 794 | LOG_STRERROR ("realloc"); |
783 | EXTRACTOR_IPC_channel_destroy_ (channels[i]); | 795 | EXTRACTOR_IPC_channel_destroy_ (channels[i]); |
784 | channels[i] = NULL; | 796 | channels[i] = NULL; |
785 | } | 797 | } |
786 | channels[i]->mdata = ndata; | 798 | channels[i]->mdata = ndata; |
787 | } | 799 | } |
788 | bresult = ReadFile (channels[i]->cpipe_out, | 800 | bresult = ReadFile (channels[i]->cpipe_out, |
789 | &channels[i]->mdata[channels[i]->size], | 801 | &channels[i]->mdata[channels[i]->size], |
790 | channels[i]->mdata_size - channels[i]->size, &bytes_read, NULL); | 802 | channels[i]->mdata_size - channels[i]->size, |
803 | &bytes_read, NULL); | ||
791 | if (bresult) | 804 | if (bresult) |
792 | ret = EXTRACTOR_IPC_process_reply_ (channels[i]->plugin, | 805 | ret = EXTRACTOR_IPC_process_reply_ (channels[i]->plugin, |
793 | channels[i]->mdata, channels[i]->size + bytes_read, proc, proc_cls); | 806 | channels[i]->mdata, |
794 | if (!bresult || -1 == ret) | 807 | channels[i]->size + bytes_read, |
808 | proc, proc_cls); | ||
809 | if (! bresult || (-1 == ret)) | ||
795 | { | 810 | { |
796 | DWORD error = GetLastError (); | 811 | DWORD error = GetLastError (); |
797 | SetErrnoFromWinError (error); | 812 | SetErrnoFromWinError (error); |
798 | if (!bresult) | 813 | if (! bresult) |
799 | LOG_STRERROR ("ReadFile"); | 814 | LOG_STRERROR ("ReadFile"); |
800 | EXTRACTOR_IPC_channel_destroy_ (channels[i]); | 815 | EXTRACTOR_IPC_channel_destroy_ (channels[i]); |
801 | channels[i] = NULL; | 816 | channels[i] = NULL; |
@@ -803,12 +818,10 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, | |||
803 | else | 818 | else |
804 | { | 819 | { |
805 | memmove (channels[i]->mdata, &channels[i]->mdata[ret], | 820 | memmove (channels[i]->mdata, &channels[i]->mdata[ret], |
806 | channels[i]->size + bytes_read - ret); | 821 | channels[i]->size + bytes_read - ret); |
807 | channels[i]->size = channels[i]->size + bytes_read- ret; | 822 | channels[i]->size = channels[i]->size + bytes_read - ret; |
808 | } | 823 | } |
809 | } | 824 | } |
810 | } | 825 | } |
811 | return 1; | 826 | return 1; |
812 | } | 827 | } |
813 | |||
814 | |||
diff --git a/src/main/extractor_logging.c b/src/main/extractor_logging.c index b1518ae..17192fe 100644 --- a/src/main/extractor_logging.c +++ b/src/main/extractor_logging.c | |||
@@ -39,13 +39,15 @@ EXTRACTOR_log_ (const char *file, int line, const char *format, ...) | |||
39 | va_list va; | 39 | va_list va; |
40 | 40 | ||
41 | fprintf (stderr, | 41 | fprintf (stderr, |
42 | "EXTRACTOR %s:%d ", | 42 | "EXTRACTOR %s:%d ", |
43 | file, line); | 43 | file, line); |
44 | va_start (va, format); | 44 | va_start (va, format); |
45 | vfprintf (stderr, format, va); | 45 | vfprintf (stderr, format, va); |
46 | va_end (va); | 46 | va_end (va); |
47 | fflush (stderr); | 47 | fflush (stderr); |
48 | } | 48 | } |
49 | |||
50 | |||
49 | #endif | 51 | #endif |
50 | 52 | ||
51 | 53 | ||
@@ -57,7 +59,7 @@ EXTRACTOR_log_ (const char *file, int line, const char *format, ...) | |||
57 | */ | 59 | */ |
58 | void | 60 | void |
59 | EXTRACTOR_abort_ (const char *file, | 61 | EXTRACTOR_abort_ (const char *file, |
60 | int line) | 62 | int line) |
61 | { | 63 | { |
62 | #if DEBUG | 64 | #if DEBUG |
63 | EXTRACTOR_log_ (file, line, "Assertion failed.\n"); | 65 | EXTRACTOR_log_ (file, line, "Assertion failed.\n"); |
@@ -65,4 +67,5 @@ EXTRACTOR_abort_ (const char *file, | |||
65 | ABORT (); | 67 | ABORT (); |
66 | } | 68 | } |
67 | 69 | ||
70 | |||
68 | /* end of extractor_logging.c */ | 71 | /* end of extractor_logging.c */ |
diff --git a/src/main/extractor_logging.h b/src/main/extractor_logging.h index 5db9ae1..535a9a7 100644 --- a/src/main/extractor_logging.h +++ b/src/main/extractor_logging.h | |||
@@ -44,7 +44,7 @@ EXTRACTOR_log_ (const char *file, int line, const char *format, ...); | |||
44 | * | 44 | * |
45 | * @param ... format string and arguments for fmt (printf-style) | 45 | * @param ... format string and arguments for fmt (printf-style) |
46 | */ | 46 | */ |
47 | #define LOG(...) EXTRACTOR_log_(__FILE__, __LINE__, __VA_ARGS__) | 47 | #define LOG(...) EXTRACTOR_log_ (__FILE__, __LINE__, __VA_ARGS__) |
48 | 48 | ||
49 | #else | 49 | #else |
50 | 50 | ||
@@ -64,7 +64,8 @@ EXTRACTOR_log_ (const char *file, int line, const char *format, ...); | |||
64 | * | 64 | * |
65 | * @param syscall name of the syscall that failed | 65 | * @param syscall name of the syscall that failed |
66 | */ | 66 | */ |
67 | #define LOG_STRERROR(syscall) LOG("System call `%s' failed: %s\n", syscall, STRERROR (errno)) | 67 | #define LOG_STRERROR(syscall) LOG ("System call `%s' failed: %s\n", syscall, \ |
68 | STRERROR (errno)) | ||
68 | 69 | ||
69 | 70 | ||
70 | /** | 71 | /** |
@@ -74,7 +75,9 @@ EXTRACTOR_log_ (const char *file, int line, const char *format, ...); | |||
74 | * @param syscall name of the syscall that failed | 75 | * @param syscall name of the syscall that failed |
75 | * @param filename name of the file that was involved | 76 | * @param filename name of the file that was involved |
76 | */ | 77 | */ |
77 | #define LOG_STRERROR_FILE(syscall,filename) LOG("System call `%s' failed for file `%s': %s\n", syscall, filename, STRERROR (errno)) | 78 | #define LOG_STRERROR_FILE(syscall,filename) LOG ( \ |
79 | "System call `%s' failed for file `%s': %s\n", syscall, filename, STRERROR ( \ | ||
80 | errno)) | ||
78 | 81 | ||
79 | 82 | ||
80 | /** | 83 | /** |
@@ -85,7 +88,7 @@ EXTRACTOR_log_ (const char *file, int line, const char *format, ...); | |||
85 | */ | 88 | */ |
86 | void | 89 | void |
87 | EXTRACTOR_abort_ (const char *file, | 90 | EXTRACTOR_abort_ (const char *file, |
88 | int line); | 91 | int line); |
89 | 92 | ||
90 | 93 | ||
91 | /** | 94 | /** |
@@ -93,7 +96,8 @@ EXTRACTOR_abort_ (const char *file, | |||
93 | * | 96 | * |
94 | * @param cond assertion that must hold. | 97 | * @param cond assertion that must hold. |
95 | */ | 98 | */ |
96 | #define ASSERT(cond) do { if (! (cond)) EXTRACTOR_abort_ (__FILE__, __LINE__); } while (0) | 99 | #define ASSERT(cond) do { if (! (cond)) EXTRACTOR_abort_ (__FILE__, __LINE__); \ |
100 | } while (0) | ||
97 | 101 | ||
98 | 102 | ||
99 | #endif | 103 | #endif |
diff --git a/src/main/extractor_metatypes.c b/src/main/extractor_metatypes.c index 41d1061..277a39f 100644 --- a/src/main/extractor_metatypes.c +++ b/src/main/extractor_metatypes.c | |||
@@ -30,7 +30,7 @@ struct MetaTypeDescription | |||
30 | * Short (typically 1-word) description. | 30 | * Short (typically 1-word) description. |
31 | */ | 31 | */ |
32 | const char *short_description; | 32 | const char *short_description; |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * More detailed description. | 35 | * More detailed description. |
36 | */ | 36 | */ |
@@ -48,7 +48,8 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
48 | { gettext_noop ("mimetype"), | 48 | { gettext_noop ("mimetype"), |
49 | gettext_noop ("mime type") }, | 49 | gettext_noop ("mime type") }, |
50 | { gettext_noop ("embedded filename"), | 50 | { gettext_noop ("embedded filename"), |
51 | gettext_noop ("filename that was embedded (not necessarily the current filename)") }, | 51 | gettext_noop ( |
52 | "filename that was embedded (not necessarily the current filename)") }, | ||
52 | { gettext_noop ("comment"), | 53 | { gettext_noop ("comment"), |
53 | gettext_noop ("comment about the content") }, | 54 | gettext_noop ("comment about the content") }, |
54 | { gettext_noop ("title"), | 55 | { gettext_noop ("title"), |
@@ -62,15 +63,16 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
62 | gettext_noop ("chapter number") }, | 63 | gettext_noop ("chapter number") }, |
63 | { gettext_noop ("journal name"), | 64 | { gettext_noop ("journal name"), |
64 | gettext_noop ("journal or magazine the work was published in") }, | 65 | gettext_noop ("journal or magazine the work was published in") }, |
65 | { gettext_noop ("journal volume"), | 66 | { gettext_noop ("journal volume"), |
66 | gettext_noop ("volume of a journal or multi-volume book") }, | 67 | gettext_noop ("volume of a journal or multi-volume book") }, |
67 | /* 10 */ | 68 | /* 10 */ |
68 | { gettext_noop ("journal number"), | 69 | { gettext_noop ("journal number"), |
69 | gettext_noop ("number of a journal, magazine or tech-report") }, | 70 | gettext_noop ("number of a journal, magazine or tech-report") }, |
70 | { gettext_noop ("page count"), | 71 | { gettext_noop ("page count"), |
71 | gettext_noop ("total number of pages of the work") }, | 72 | gettext_noop ("total number of pages of the work") }, |
72 | { gettext_noop ("page range"), | 73 | { gettext_noop ("page range"), |
73 | gettext_noop ("page numbers of the publication in the respective journal or book") }, | 74 | gettext_noop ( |
75 | "page numbers of the publication in the respective journal or book") }, | ||
74 | { gettext_noop ("author name"), | 76 | { gettext_noop ("author name"), |
75 | gettext_noop ("name of the author(s)") }, | 77 | gettext_noop ("name of the author(s)") }, |
76 | { gettext_noop ("author email"), | 78 | { gettext_noop ("author email"), |
@@ -83,20 +85,25 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
83 | { gettext_noop ("publisher's address"), | 85 | { gettext_noop ("publisher's address"), |
84 | gettext_noop ("Address of the publisher (often only the city)") }, | 86 | gettext_noop ("Address of the publisher (often only the city)") }, |
85 | { gettext_noop ("publishing institution"), | 87 | { gettext_noop ("publishing institution"), |
86 | gettext_noop ("institution that was involved in the publishing, but not necessarily the publisher") }, | 88 | gettext_noop ( |
89 | "institution that was involved in the publishing, but not necessarily the publisher") }, | ||
87 | { gettext_noop ("publication series"), | 90 | { gettext_noop ("publication series"), |
88 | gettext_noop ("series of books the book was published in") }, | 91 | gettext_noop ("series of books the book was published in") }, |
89 | /* 20 */ | 92 | /* 20 */ |
90 | { gettext_noop ("publication type"), | 93 | { gettext_noop ("publication type"), |
91 | gettext_noop ("type of the tech-report") }, | 94 | gettext_noop ("type of the tech-report") }, |
92 | { gettext_noop ("publication year"), | 95 | { gettext_noop ("publication year"), |
93 | gettext_noop ("year of publication (or, if unpublished, the year of creation)") }, | 96 | gettext_noop ( |
97 | "year of publication (or, if unpublished, the year of creation)") }, | ||
94 | { gettext_noop ("publication month"), | 98 | { gettext_noop ("publication month"), |
95 | gettext_noop ("month of publication (or, if unpublished, the month of creation)") }, | 99 | gettext_noop ( |
100 | "month of publication (or, if unpublished, the month of creation)") }, | ||
96 | { gettext_noop ("publication day"), | 101 | { gettext_noop ("publication day"), |
97 | gettext_noop ("day of publication (or, if unpublished, the day of creation), relative to the given month") }, | 102 | gettext_noop ( |
103 | "day of publication (or, if unpublished, the day of creation), relative to the given month") }, | ||
98 | { gettext_noop ("publication date"), | 104 | { gettext_noop ("publication date"), |
99 | gettext_noop ("date of publication (or, if unpublished, the date of creation)") }, | 105 | gettext_noop ( |
106 | "date of publication (or, if unpublished, the date of creation)") }, | ||
100 | /* 25 */ | 107 | /* 25 */ |
101 | { gettext_noop ("bibtex eprint"), | 108 | { gettext_noop ("bibtex eprint"), |
102 | gettext_noop ("specification of an electronic publication") }, | 109 | gettext_noop ("specification of an electronic publication") }, |
@@ -107,7 +114,8 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
107 | { gettext_noop ("creation time"), | 114 | { gettext_noop ("creation time"), |
108 | gettext_noop ("time and date of creation") }, | 115 | gettext_noop ("time and date of creation") }, |
109 | { gettext_noop ("URL"), | 116 | { gettext_noop ("URL"), |
110 | gettext_noop ("universal resource location (where the work is made available)") }, | 117 | gettext_noop ( |
118 | "universal resource location (where the work is made available)") }, | ||
111 | /* 30 */ | 119 | /* 30 */ |
112 | { gettext_noop ("URI"), | 120 | { gettext_noop ("URI"), |
113 | gettext_noop ("universal resource identifier") }, | 121 | gettext_noop ("universal resource identifier") }, |
@@ -120,7 +128,7 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
120 | { gettext_noop ("SHA-0"), | 128 | { gettext_noop ("SHA-0"), |
121 | gettext_noop ("SHA-0 hash") }, | 129 | gettext_noop ("SHA-0 hash") }, |
122 | /* 35 */ | 130 | /* 35 */ |
123 | { gettext_noop ("SHA-1"), | 131 | { gettext_noop ("SHA-1"), |
124 | gettext_noop ("SHA-1 hash") }, | 132 | gettext_noop ("SHA-1 hash") }, |
125 | { gettext_noop ("RipeMD160"), | 133 | { gettext_noop ("RipeMD160"), |
126 | gettext_noop ("RipeMD150 hash") }, | 134 | gettext_noop ("RipeMD150 hash") }, |
@@ -135,7 +143,7 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
135 | gettext_noop ("GPS longitude") }, | 143 | gettext_noop ("GPS longitude") }, |
136 | { gettext_noop ("city"), | 144 | { gettext_noop ("city"), |
137 | gettext_noop ("name of the city where the document originated") }, | 145 | gettext_noop ("name of the city where the document originated") }, |
138 | { gettext_noop ("sublocation"), | 146 | { gettext_noop ("sublocation"), |
139 | gettext_noop ("more specific location of the geographic origin") }, | 147 | gettext_noop ("more specific location of the geographic origin") }, |
140 | { gettext_noop ("country"), | 148 | { gettext_noop ("country"), |
141 | gettext_noop ("name of the country where the document originated") }, | 149 | gettext_noop ("name of the country where the document originated") }, |
@@ -169,7 +177,8 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
169 | { gettext_noop ("created by software"), | 177 | { gettext_noop ("created by software"), |
170 | gettext_noop ("name of the software that created the document") }, | 178 | gettext_noop ("name of the software that created the document") }, |
171 | { gettext_noop ("unknown date"), | 179 | { gettext_noop ("unknown date"), |
172 | gettext_noop ("ambiguous date (could specify creation time, modification time or access time)") }, | 180 | gettext_noop ( |
181 | "ambiguous date (could specify creation time, modification time or access time)") }, | ||
173 | { gettext_noop ("creation date"), | 182 | { gettext_noop ("creation date"), |
174 | gettext_noop ("date the document was created") }, | 183 | gettext_noop ("date the document was created") }, |
175 | { gettext_noop ("modification date"), | 184 | { gettext_noop ("modification date"), |
@@ -189,7 +198,8 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
189 | { gettext_noop ("revision history"), | 198 | { gettext_noop ("revision history"), |
190 | gettext_noop ("information about the revision history") }, | 199 | gettext_noop ("information about the revision history") }, |
191 | { gettext_noop ("embedded file size"), | 200 | { gettext_noop ("embedded file size"), |
192 | gettext_noop ("size of the contents of the container as embedded in the file") }, | 201 | gettext_noop ( |
202 | "size of the contents of the container as embedded in the file") }, | ||
193 | { gettext_noop ("file type"), | 203 | { gettext_noop ("file type"), |
194 | gettext_noop ("standard Macintosh Finder file type information") }, | 204 | gettext_noop ("standard Macintosh Finder file type information") }, |
195 | { gettext_noop ("creator"), | 205 | { gettext_noop ("creator"), |
@@ -213,9 +223,11 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
213 | { gettext_noop ("provides"), | 223 | { gettext_noop ("provides"), |
214 | gettext_noop ("functionality provided by this package") }, | 224 | gettext_noop ("functionality provided by this package") }, |
215 | { gettext_noop ("recommendations"), | 225 | { gettext_noop ("recommendations"), |
216 | gettext_noop ("packages recommended for installation in conjunction with this package") }, | 226 | gettext_noop ( |
227 | "packages recommended for installation in conjunction with this package") }, | ||
217 | { gettext_noop ("suggestions"), | 228 | { gettext_noop ("suggestions"), |
218 | gettext_noop ("packages suggested for installation in conjunction with this package") }, | 229 | gettext_noop ( |
230 | "packages suggested for installation in conjunction with this package") }, | ||
219 | { gettext_noop ("maintainer"), | 231 | { gettext_noop ("maintainer"), |
220 | gettext_noop ("name of the maintainer") }, | 232 | gettext_noop ("name of the maintainer") }, |
221 | /* 80 */ | 233 | /* 80 */ |
@@ -228,208 +240,218 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
228 | { gettext_noop ("target architecture"), | 240 | { gettext_noop ("target architecture"), |
229 | gettext_noop ("hardware architecture the contents can be used for") }, | 241 | gettext_noop ("hardware architecture the contents can be used for") }, |
230 | { gettext_noop ("pre-dependency"), | 242 | { gettext_noop ("pre-dependency"), |
231 | gettext_noop ("dependency that must be satisfied before installation") }, | 243 | gettext_noop ("dependency that must be satisfied before installation") }, |
232 | /* 85 */ | 244 | /* 85 */ |
233 | { gettext_noop ("license"), | 245 | { gettext_noop ("license"), |
234 | gettext_noop ("applicable copyright license") }, | 246 | gettext_noop ("applicable copyright license") }, |
235 | { gettext_noop ("distribution"), | 247 | { gettext_noop ("distribution"), |
236 | gettext_noop ("distribution the package is a part of") }, | 248 | gettext_noop ("distribution the package is a part of") }, |
237 | { gettext_noop ("build host"), | 249 | { gettext_noop ("build host"), |
238 | gettext_noop ("machine the package was build on") }, | 250 | gettext_noop ("machine the package was build on") }, |
239 | { gettext_noop ("vendor"), | 251 | { gettext_noop ("vendor"), |
240 | gettext_noop ("name of the software vendor") }, | 252 | gettext_noop ("name of the software vendor") }, |
241 | { gettext_noop ("target operating system"), | 253 | { gettext_noop ("target operating system"), |
242 | gettext_noop ("operating system for which this package was made") }, | 254 | gettext_noop ("operating system for which this package was made") }, |
243 | /* 90 */ | 255 | /* 90 */ |
244 | { gettext_noop ("software version"), | 256 | { gettext_noop ("software version"), |
245 | gettext_noop ("version of the software contained in the file") }, | 257 | gettext_noop ("version of the software contained in the file") }, |
246 | { gettext_noop ("target platform"), | 258 | { gettext_noop ("target platform"), |
247 | gettext_noop ("name of the architecture, operating system and distribution this package is for") }, | 259 | gettext_noop ( |
260 | "name of the architecture, operating system and distribution this package is for") }, | ||
248 | { gettext_noop ("resource type"), | 261 | { gettext_noop ("resource type"), |
249 | gettext_noop ("categorization of the nature of the resource that is more specific than the file format") }, | 262 | gettext_noop ( |
263 | "categorization of the nature of the resource that is more specific than the file format") }, | ||
250 | { gettext_noop ("library search path"), | 264 | { gettext_noop ("library search path"), |
251 | gettext_noop ("path in the file system to be considered when looking for required libraries") }, | 265 | gettext_noop ( |
266 | "path in the file system to be considered when looking for required libraries") }, | ||
252 | { gettext_noop ("library dependency"), | 267 | { gettext_noop ("library dependency"), |
253 | gettext_noop ("name of a library that this file depends on") }, | 268 | gettext_noop ("name of a library that this file depends on") }, |
254 | /* 95 */ | 269 | /* 95 */ |
255 | { gettext_noop ("camera make"), | 270 | { gettext_noop ("camera make"), |
256 | gettext_noop ("camera make") }, | 271 | gettext_noop ("camera make") }, |
257 | { gettext_noop ("camera model"), | 272 | { gettext_noop ("camera model"), |
258 | gettext_noop ("camera model") }, | 273 | gettext_noop ("camera model") }, |
259 | { gettext_noop ("exposure"), | 274 | { gettext_noop ("exposure"), |
260 | gettext_noop ("exposure") }, | 275 | gettext_noop ("exposure") }, |
261 | { gettext_noop ("aperture"), | 276 | { gettext_noop ("aperture"), |
262 | gettext_noop ("aperture") }, | 277 | gettext_noop ("aperture") }, |
263 | { gettext_noop ("exposure bias"), | 278 | { gettext_noop ("exposure bias"), |
264 | gettext_noop ("exposure bias") }, | 279 | gettext_noop ("exposure bias") }, |
265 | /* 100 */ | 280 | /* 100 */ |
266 | { gettext_noop ("flash"), | 281 | { gettext_noop ("flash"), |
267 | gettext_noop ("flash") }, | 282 | gettext_noop ("flash") }, |
268 | { gettext_noop ("flash bias"), | 283 | { gettext_noop ("flash bias"), |
269 | gettext_noop ("flash bias") }, | 284 | gettext_noop ("flash bias") }, |
270 | { gettext_noop ("focal length"), | 285 | { gettext_noop ("focal length"), |
271 | gettext_noop ("focal length") }, | 286 | gettext_noop ("focal length") }, |
272 | { gettext_noop ("focal length 35mm"), | 287 | { gettext_noop ("focal length 35mm"), |
273 | gettext_noop ("focal length 35mm") }, | 288 | gettext_noop ("focal length 35mm") }, |
274 | { gettext_noop ("iso speed"), | 289 | { gettext_noop ("iso speed"), |
275 | gettext_noop ("iso speed") }, | 290 | gettext_noop ("iso speed") }, |
276 | /* 105 */ | 291 | /* 105 */ |
277 | { gettext_noop ("exposure mode"), | 292 | { gettext_noop ("exposure mode"), |
278 | gettext_noop ("exposure mode") }, | 293 | gettext_noop ("exposure mode") }, |
279 | { gettext_noop ("metering mode"), | 294 | { gettext_noop ("metering mode"), |
280 | gettext_noop ("metering mode") }, | 295 | gettext_noop ("metering mode") }, |
281 | { gettext_noop ("macro mode"), | 296 | { gettext_noop ("macro mode"), |
282 | gettext_noop ("macro mode") }, | 297 | gettext_noop ("macro mode") }, |
283 | { gettext_noop ("image quality"), | 298 | { gettext_noop ("image quality"), |
284 | gettext_noop ("image quality") }, | 299 | gettext_noop ("image quality") }, |
285 | { gettext_noop ("white balance"), | 300 | { gettext_noop ("white balance"), |
286 | gettext_noop ("white balance") }, | 301 | gettext_noop ("white balance") }, |
287 | /* 110 */ | 302 | /* 110 */ |
288 | { gettext_noop ("orientation"), | 303 | { gettext_noop ("orientation"), |
289 | gettext_noop ("orientation") }, | 304 | gettext_noop ("orientation") }, |
290 | { gettext_noop ("magnification"), | 305 | { gettext_noop ("magnification"), |
291 | gettext_noop ("magnification") }, | 306 | gettext_noop ("magnification") }, |
292 | { gettext_noop ("image dimensions"), | 307 | { gettext_noop ("image dimensions"), |
293 | gettext_noop ("size of the image in pixels (width times height)") }, | 308 | gettext_noop ("size of the image in pixels (width times height)") }, |
294 | { gettext_noop ("produced by software"), | 309 | { gettext_noop ("produced by software"), |
295 | gettext_noop ("produced by software") }, /* what is the exact difference between the software | 310 | gettext_noop ("produced by software") }, /* what is the exact difference between the software |
296 | creator and the software producer? PDF and DVI | 311 | creator and the software producer? PDF and DVI |
297 | both have this distinction (i.e., Writer vs. | 312 | both have this distinction (i.e., Writer vs. |
298 | OpenOffice) */ | 313 | OpenOffice) */ |
299 | { gettext_noop ("thumbnail"), | 314 | { gettext_noop ("thumbnail"), |
300 | gettext_noop ("smaller version of the image for previewing") }, | 315 | gettext_noop ("smaller version of the image for previewing") }, |
301 | /* 115 */ | 316 | /* 115 */ |
302 | { gettext_noop ("image resolution"), | 317 | { gettext_noop ("image resolution"), |
303 | gettext_noop ("resolution in dots per inch") }, | 318 | gettext_noop ("resolution in dots per inch") }, |
304 | { gettext_noop ("source"), | 319 | { gettext_noop ("source"), |
305 | gettext_noop ("Originating entity") }, | 320 | gettext_noop ("Originating entity") }, |
306 | { gettext_noop ("character set"), | 321 | { gettext_noop ("character set"), |
307 | gettext_noop ("character encoding used") }, | 322 | gettext_noop ("character encoding used") }, |
308 | { gettext_noop ("line count"), | 323 | { gettext_noop ("line count"), |
309 | gettext_noop ("number of lines") }, | 324 | gettext_noop ("number of lines") }, |
310 | { gettext_noop ("paragraph count"), | 325 | { gettext_noop ("paragraph count"), |
311 | gettext_noop ("number of paragraphs") }, | 326 | gettext_noop ("number of paragraphs") }, |
312 | /* 120 */ | 327 | /* 120 */ |
313 | { gettext_noop ("word count"), | 328 | { gettext_noop ("word count"), |
314 | gettext_noop ("number of words") }, | 329 | gettext_noop ("number of words") }, |
315 | { gettext_noop ("character count"), | 330 | { gettext_noop ("character count"), |
316 | gettext_noop ("number of characters") }, | 331 | gettext_noop ("number of characters") }, |
317 | { gettext_noop ("page orientation"), | 332 | { gettext_noop ("page orientation"), |
318 | gettext_noop ("page orientation") }, | 333 | gettext_noop ("page orientation") }, |
319 | { gettext_noop ("paper size"), | 334 | { gettext_noop ("paper size"), |
320 | gettext_noop ("paper size") }, | 335 | gettext_noop ("paper size") }, |
321 | { gettext_noop ("template"), | 336 | { gettext_noop ("template"), |
322 | gettext_noop ("template the document uses or is based on") }, | 337 | gettext_noop ("template the document uses or is based on") }, |
323 | /* 125 */ | 338 | /* 125 */ |
324 | { gettext_noop ("company"), | 339 | { gettext_noop ("company"), |
325 | gettext_noop ("company") }, | 340 | gettext_noop ("company") }, |
326 | { gettext_noop ("manager"), | 341 | { gettext_noop ("manager"), |
327 | gettext_noop ("manager") }, | 342 | gettext_noop ("manager") }, |
328 | { gettext_noop ("revision number"), | 343 | { gettext_noop ("revision number"), |
329 | gettext_noop ("revision number") }, | 344 | gettext_noop ("revision number") }, |
330 | { gettext_noop ("duration"), | 345 | { gettext_noop ("duration"), |
331 | gettext_noop ("play time for the medium") }, | 346 | gettext_noop ("play time for the medium") }, |
332 | { gettext_noop ("album"), | 347 | { gettext_noop ("album"), |
333 | gettext_noop ("name of the album") }, | 348 | gettext_noop ("name of the album") }, |
334 | /* 130 */ | 349 | /* 130 */ |
335 | { gettext_noop ("artist"), | 350 | { gettext_noop ("artist"), |
336 | gettext_noop ("name of the artist or band") }, | 351 | gettext_noop ("name of the artist or band") }, |
337 | { gettext_noop ("genre"), | 352 | { gettext_noop ("genre"), |
338 | gettext_noop ("genre") }, | 353 | gettext_noop ("genre") }, |
339 | { gettext_noop ("track number"), | 354 | { gettext_noop ("track number"), |
340 | gettext_noop ("original number of the track on the distribution medium") }, | 355 | gettext_noop ("original number of the track on the distribution medium") }, |
341 | { gettext_noop ("disk number"), | 356 | { gettext_noop ("disk number"), |
342 | gettext_noop ("number of the disk in a multi-disk (or volume) distribution") }, | 357 | gettext_noop ( |
358 | "number of the disk in a multi-disk (or volume) distribution") }, | ||
343 | { gettext_noop ("performer"), | 359 | { gettext_noop ("performer"), |
344 | gettext_noop ("The artist(s) who performed the work (conductor, orchestra, soloists, actor, etc.)") }, | 360 | gettext_noop ( |
361 | "The artist(s) who performed the work (conductor, orchestra, soloists, actor, etc.)") }, | ||
345 | /* 135 */ | 362 | /* 135 */ |
346 | { gettext_noop ("contact"), | 363 | { gettext_noop ("contact"), |
347 | gettext_noop ("Contact information for the creator or distributor") }, | 364 | gettext_noop ("Contact information for the creator or distributor") }, |
348 | { gettext_noop ("song version"), | 365 | { gettext_noop ("song version"), |
349 | gettext_noop ("name of the version of the song (i.e. remix information)") }, | 366 | gettext_noop ("name of the version of the song (i.e. remix information)") }, |
350 | { gettext_noop ("picture"), | 367 | { gettext_noop ("picture"), |
351 | gettext_noop ("associated misc. picture") }, | 368 | gettext_noop ("associated misc. picture") }, |
352 | { gettext_noop ("cover picture"), | 369 | { gettext_noop ("cover picture"), |
353 | gettext_noop ("picture of the cover of the distribution medium") }, | 370 | gettext_noop ("picture of the cover of the distribution medium") }, |
354 | { gettext_noop ("contributor picture"), | 371 | { gettext_noop ("contributor picture"), |
355 | gettext_noop ("picture of one of the contributors") }, | 372 | gettext_noop ("picture of one of the contributors") }, |
356 | /* 140 */ | 373 | /* 140 */ |
357 | { gettext_noop ("event picture"), | 374 | { gettext_noop ("event picture"), |
358 | gettext_noop ("picture of an associated event") }, | 375 | gettext_noop ("picture of an associated event") }, |
359 | { gettext_noop ("logo"), | 376 | { gettext_noop ("logo"), |
360 | gettext_noop ("logo of an associated organization") }, | 377 | gettext_noop ("logo of an associated organization") }, |
361 | { gettext_noop ("broadcast television system"), | 378 | { gettext_noop ("broadcast television system"), |
362 | gettext_noop ("name of the television system for which the data is coded") }, | 379 | gettext_noop ( |
380 | "name of the television system for which the data is coded") }, | ||
363 | { gettext_noop ("source device"), | 381 | { gettext_noop ("source device"), |
364 | gettext_noop ("device used to create the object") }, | 382 | gettext_noop ("device used to create the object") }, |
365 | { gettext_noop ("disclaimer"), | 383 | { gettext_noop ("disclaimer"), |
366 | gettext_noop ("legal disclaimer") }, | 384 | gettext_noop ("legal disclaimer") }, |
367 | /* 145 */ | 385 | /* 145 */ |
368 | { gettext_noop ("warning"), | 386 | { gettext_noop ("warning"), |
369 | gettext_noop ("warning about the nature of the content") }, | 387 | gettext_noop ("warning about the nature of the content") }, |
370 | { gettext_noop ("page order"), | 388 | { gettext_noop ("page order"), |
371 | gettext_noop ("order of the pages") }, | 389 | gettext_noop ("order of the pages") }, |
372 | { gettext_noop ("writer"), | 390 | { gettext_noop ("writer"), |
373 | gettext_noop ("contributing writer") }, | 391 | gettext_noop ("contributing writer") }, |
374 | { gettext_noop ("product version"), | 392 | { gettext_noop ("product version"), |
375 | gettext_noop ("product version") }, | 393 | gettext_noop ("product version") }, |
376 | { gettext_noop ("contributor"), | 394 | { gettext_noop ("contributor"), |
377 | gettext_noop ("name of a contributor") }, | 395 | gettext_noop ("name of a contributor") }, |
378 | /* 150 */ | 396 | /* 150 */ |
379 | { gettext_noop ("movie director"), | 397 | { gettext_noop ("movie director"), |
380 | gettext_noop ("name of the director") }, | 398 | gettext_noop ("name of the director") }, |
381 | { gettext_noop ("network"), | 399 | { gettext_noop ("network"), |
382 | gettext_noop ("name of the broadcasting network or station") }, | 400 | gettext_noop ("name of the broadcasting network or station") }, |
383 | { gettext_noop ("show"), | 401 | { gettext_noop ("show"), |
384 | gettext_noop ("name of the show") }, | 402 | gettext_noop ("name of the show") }, |
385 | { gettext_noop ("chapter name"), | 403 | { gettext_noop ("chapter name"), |
386 | gettext_noop ("name of the chapter") }, | 404 | gettext_noop ("name of the chapter") }, |
387 | { gettext_noop ("song count"), | 405 | { gettext_noop ("song count"), |
388 | gettext_noop ("number of songs") }, | 406 | gettext_noop ("number of songs") }, |
389 | /* 155 */ | 407 | /* 155 */ |
390 | { gettext_noop ("starting song"), | 408 | { gettext_noop ("starting song"), |
391 | gettext_noop ("number of the first song to play") }, | 409 | gettext_noop ("number of the first song to play") }, |
392 | { gettext_noop ("play counter"), | 410 | { gettext_noop ("play counter"), |
393 | gettext_noop ("number of times the media has been played") }, | 411 | gettext_noop ("number of times the media has been played") }, |
394 | { gettext_noop ("conductor"), | 412 | { gettext_noop ("conductor"), |
395 | gettext_noop ("name of the conductor") }, | 413 | gettext_noop ("name of the conductor") }, |
396 | { gettext_noop ("interpretation"), | 414 | { gettext_noop ("interpretation"), |
397 | gettext_noop ("information about the people behind interpretations of an existing piece") }, | 415 | gettext_noop ( |
416 | "information about the people behind interpretations of an existing piece") }, | ||
398 | { gettext_noop ("composer"), | 417 | { gettext_noop ("composer"), |
399 | gettext_noop ("name of the composer") }, | 418 | gettext_noop ("name of the composer") }, |
400 | /* 160 */ | 419 | /* 160 */ |
401 | { gettext_noop ("beats per minute"), | 420 | { gettext_noop ("beats per minute"), |
402 | gettext_noop ("beats per minute") }, | 421 | gettext_noop ("beats per minute") }, |
403 | { gettext_noop ("encoded by"), | 422 | { gettext_noop ("encoded by"), |
404 | gettext_noop ("name of person or organization that encoded the file") }, | 423 | gettext_noop ("name of person or organization that encoded the file") }, |
405 | { gettext_noop ("original title"), | 424 | { gettext_noop ("original title"), |
406 | gettext_noop ("title of the original work") }, | 425 | gettext_noop ("title of the original work") }, |
407 | { gettext_noop ("original artist"), | 426 | { gettext_noop ("original artist"), |
408 | gettext_noop ("name of the original artist") }, | 427 | gettext_noop ("name of the original artist") }, |
409 | { gettext_noop ("original writer"), | 428 | { gettext_noop ("original writer"), |
410 | gettext_noop ("name of the original lyricist or writer") }, | 429 | gettext_noop ("name of the original lyricist or writer") }, |
411 | /* 165 */ | 430 | /* 165 */ |
412 | { gettext_noop ("original release year"), | 431 | { gettext_noop ("original release year"), |
413 | gettext_noop ("year of the original release") }, | 432 | gettext_noop ("year of the original release") }, |
414 | { gettext_noop ("original performer"), | 433 | { gettext_noop ("original performer"), |
415 | gettext_noop ("name of the original performer") }, | 434 | gettext_noop ("name of the original performer") }, |
416 | { gettext_noop ("lyrics"), | 435 | { gettext_noop ("lyrics"), |
417 | gettext_noop ("lyrics of the song or text description of vocal activities") }, | 436 | gettext_noop ( |
437 | "lyrics of the song or text description of vocal activities") }, | ||
418 | { gettext_noop ("popularity"), | 438 | { gettext_noop ("popularity"), |
419 | gettext_noop ("information about the file's popularity") }, | 439 | gettext_noop ("information about the file's popularity") }, |
420 | { gettext_noop ("licensee"), | 440 | { gettext_noop ("licensee"), |
421 | gettext_noop ("name of the owner or licensee of the file") }, | 441 | gettext_noop ("name of the owner or licensee of the file") }, |
422 | /* 170 */ | 442 | /* 170 */ |
423 | { gettext_noop ("musician credit list"), | 443 | { gettext_noop ("musician credit list"), |
424 | gettext_noop ("names of contributing musicians") }, | 444 | gettext_noop ("names of contributing musicians") }, |
425 | { gettext_noop ("mood"), | 445 | { gettext_noop ("mood"), |
426 | gettext_noop ("keywords reflecting the mood of the piece") }, | 446 | gettext_noop ("keywords reflecting the mood of the piece") }, |
427 | { gettext_noop ("subtitle"), | 447 | { gettext_noop ("subtitle"), |
428 | gettext_noop ("subtitle of this part") }, | 448 | gettext_noop ("subtitle of this part") }, |
429 | { gettext_noop ("display type"), | 449 | { gettext_noop ("display type"), |
430 | gettext_noop ("what rendering method should be used to display this item") }, | 450 | gettext_noop ( |
451 | "what rendering method should be used to display this item") }, | ||
431 | { gettext_noop ("full data"), | 452 | { gettext_noop ("full data"), |
432 | gettext_noop ("entry that contains the full, original binary data (not really meta data)") }, | 453 | gettext_noop ( |
454 | "entry that contains the full, original binary data (not really meta data)") }, | ||
433 | /* 175 */ | 455 | /* 175 */ |
434 | { gettext_noop ("rating"), | 456 | { gettext_noop ("rating"), |
435 | gettext_noop ("rating of the content") }, | 457 | gettext_noop ("rating of the content") }, |
@@ -437,9 +459,9 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
437 | gettext_noop ("organization") }, | 459 | gettext_noop ("organization") }, |
438 | { gettext_noop ("ripper"), /* any difference to "encoded by"? */ | 460 | { gettext_noop ("ripper"), /* any difference to "encoded by"? */ |
439 | gettext_noop ("ripper") }, | 461 | gettext_noop ("ripper") }, |
440 | { gettext_noop ("producer"), | 462 | { gettext_noop ("producer"), |
441 | gettext_noop ("producer") }, | 463 | gettext_noop ("producer") }, |
442 | { gettext_noop ("group"), | 464 | { gettext_noop ("group"), |
443 | gettext_noop ("name of the group or band") }, | 465 | gettext_noop ("name of the group or band") }, |
444 | /* 180 */ | 466 | /* 180 */ |
445 | { gettext_noop ("original filename"), | 467 | { gettext_noop ("original filename"), |
@@ -460,7 +482,8 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
460 | { gettext_noop ("bitrate"), | 482 | { gettext_noop ("bitrate"), |
461 | gettext_noop ("exact or average bitrate in bits/s") }, | 483 | gettext_noop ("exact or average bitrate in bits/s") }, |
462 | { gettext_noop ("nominal bitrate"), | 484 | { gettext_noop ("nominal bitrate"), |
463 | gettext_noop ("nominal bitrate in bits/s. The actual bitrate might be different from this target bitrate.") }, | 485 | gettext_noop ( |
486 | "nominal bitrate in bits/s. The actual bitrate might be different from this target bitrate.") }, | ||
464 | { gettext_noop ("minimum bitrate"), | 487 | { gettext_noop ("minimum bitrate"), |
465 | gettext_noop ("minimum bitrate in bits/s") }, | 488 | gettext_noop ("minimum bitrate in bits/s") }, |
466 | /* 190 */ | 489 | /* 190 */ |
@@ -484,25 +507,32 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
484 | { gettext_noop ("reference level"), | 507 | { gettext_noop ("reference level"), |
485 | gettext_noop ("reference level of track and album gain values") }, | 508 | gettext_noop ("reference level of track and album gain values") }, |
486 | { gettext_noop ("location name"), | 509 | { gettext_noop ("location name"), |
487 | gettext_noop ("human readable descriptive location of where the media has been recorded or produced") }, | 510 | gettext_noop ( |
511 | "human readable descriptive location of where the media has been recorded or produced") }, | ||
488 | /* 200 */ | 512 | /* 200 */ |
489 | { gettext_noop ("location elevation"), | 513 | { gettext_noop ("location elevation"), |
490 | gettext_noop ("geo elevation of where the media has been recorded or produced in meters according to WGS84 (zero is average sea level)") }, | 514 | gettext_noop ( |
515 | "geo elevation of where the media has been recorded or produced in meters according to WGS84 (zero is average sea level)") }, | ||
491 | { gettext_noop ("location horizontal error"), | 516 | { gettext_noop ("location horizontal error"), |
492 | gettext_noop ("represents the expected error on the horizontal positioning in meters") }, | 517 | gettext_noop ( |
518 | "represents the expected error on the horizontal positioning in meters") }, | ||
493 | { gettext_noop ("location movement speed"), | 519 | { gettext_noop ("location movement speed"), |
494 | gettext_noop ("speed of the capturing device when performing the capture. Represented in m/s") }, | 520 | gettext_noop ( |
521 | "speed of the capturing device when performing the capture. Represented in m/s") }, | ||
495 | { gettext_noop ("location movement direction"), | 522 | { gettext_noop ("location movement direction"), |
496 | gettext_noop ("indicates the movement direction of the device performing the capture of a media. It is represented as degrees in floating point representation, 0 means the geographic north, and increases clockwise") }, | 523 | gettext_noop ( |
524 | "indicates the movement direction of the device performing the capture of a media. It is represented as degrees in floating point representation, 0 means the geographic north, and increases clockwise") }, | ||
497 | { gettext_noop ("location capture direction"), | 525 | { gettext_noop ("location capture direction"), |
498 | gettext_noop ("indicates the direction the device is pointing to when capturing a media. It is represented as degrees in floating point representation, 0 means the geographic north, and increases clockwise") }, | 526 | gettext_noop ( |
527 | "indicates the direction the device is pointing to when capturing a media. It is represented as degrees in floating point representation, 0 means the geographic north, and increases clockwise") }, | ||
499 | /* 205 */ | 528 | /* 205 */ |
500 | { gettext_noop ("show episode number"), | 529 | { gettext_noop ("show episode number"), |
501 | gettext_noop ("number of the episode within a season/show") }, | 530 | gettext_noop ("number of the episode within a season/show") }, |
502 | { gettext_noop ("show season number"), | 531 | { gettext_noop ("show season number"), |
503 | gettext_noop ("number of the season of a show/series") }, | 532 | gettext_noop ("number of the season of a show/series") }, |
504 | { gettext_noop ("grouping"), | 533 | { gettext_noop ("grouping"), |
505 | gettext_noop ("groups together media that are related and spans multiple tracks. An example are multiple pieces of a concerto") }, | 534 | gettext_noop ( |
535 | "groups together media that are related and spans multiple tracks. An example are multiple pieces of a concerto") }, | ||
506 | { gettext_noop ("device manufacturer"), | 536 | { gettext_noop ("device manufacturer"), |
507 | gettext_noop ("manufacturer of the device used to create the media") }, | 537 | gettext_noop ("manufacturer of the device used to create the media") }, |
508 | { gettext_noop ("device model"), | 538 | { gettext_noop ("device model"), |
@@ -552,7 +582,8 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
552 | gettext_noop ("a preview of the file audio stream") }, | 582 | gettext_noop ("a preview of the file audio stream") }, |
553 | 583 | ||
554 | { gettext_noop ("narinfo"), | 584 | { gettext_noop ("narinfo"), |
555 | gettext_noop ("file containing information about contents of a normalized archive (nar)") }, | 585 | gettext_noop ( |
586 | "file containing information about contents of a normalized archive (nar)") }, | ||
556 | /* 230 */ | 587 | /* 230 */ |
557 | { gettext_noop ("nar"), | 588 | { gettext_noop ("nar"), |
558 | gettext_noop ("normalized archive") }, | 589 | gettext_noop ("normalized archive") }, |
@@ -562,9 +593,10 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { | |||
562 | }; | 593 | }; |
563 | 594 | ||
564 | /** | 595 | /** |
565 | * Total number of keyword types (for bounds-checking) | 596 | * Total number of keyword types (for bounds-checking) |
566 | */ | 597 | */ |
567 | #define HIGHEST_METATYPE_NUMBER (sizeof (meta_type_descriptions) / sizeof(*meta_type_descriptions)) | 598 | #define HIGHEST_METATYPE_NUMBER (sizeof (meta_type_descriptions) \ |
599 | / sizeof(*meta_type_descriptions)) | ||
568 | 600 | ||
569 | 601 | ||
570 | /** | 602 | /** |
diff --git a/src/main/extractor_plugin_main.c b/src/main/extractor_plugin_main.c index 7b01140..fd4912f 100644 --- a/src/main/extractor_plugin_main.c +++ b/src/main/extractor_plugin_main.c | |||
@@ -116,8 +116,8 @@ struct ProcessingContext | |||
116 | */ | 116 | */ |
117 | static int64_t | 117 | static int64_t |
118 | plugin_env_seek (void *cls, | 118 | plugin_env_seek (void *cls, |
119 | int64_t pos, | 119 | int64_t pos, |
120 | int whence) | 120 | int whence) |
121 | { | 121 | { |
122 | struct ProcessingContext *pc = cls; | 122 | struct ProcessingContext *pc = cls; |
123 | struct SeekRequestMessage srm; | 123 | struct SeekRequestMessage srm; |
@@ -127,117 +127,118 @@ plugin_env_seek (void *cls, | |||
127 | uint16_t wval; | 127 | uint16_t wval; |
128 | 128 | ||
129 | switch (whence) | 129 | switch (whence) |
130 | { | ||
131 | case SEEK_CUR: | ||
132 | if ( (pos < 0) && (pc->read_position < -pos) ) | ||
130 | { | 133 | { |
131 | case SEEK_CUR: | 134 | LOG ("Invalid seek operation\n"); |
132 | if ( (pos < 0) && (pc->read_position < - pos) ) | 135 | return -1; |
133 | { | 136 | } |
134 | LOG ("Invalid seek operation\n"); | 137 | if ((pos > 0) && ((pc->read_position + pos < pc->read_position) || |
135 | return -1; | 138 | (pc->read_position + pos > pc->file_size))) |
136 | } | 139 | { |
137 | if ((pos > 0) && ((pc->read_position + pos < pc->read_position) || | 140 | LOG ("Invalid seek operation\n"); |
138 | (pc->read_position + pos > pc->file_size))) | 141 | return -1; |
139 | { | 142 | } |
140 | LOG ("Invalid seek operation\n"); | 143 | npos = (uint64_t) (pc->read_position + pos); |
141 | return -1; | 144 | wval = 0; |
142 | } | 145 | break; |
143 | npos = (uint64_t) (pc->read_position + pos); | 146 | case SEEK_END: |
144 | wval = 0; | 147 | if (pos > 0) |
145 | break; | 148 | { |
146 | case SEEK_END: | 149 | LOG ("Invalid seek operation\n"); |
147 | if (pos > 0) | 150 | return -1; |
148 | { | 151 | } |
149 | LOG ("Invalid seek operation\n"); | 152 | if (UINT64_MAX == pc->file_size) |
150 | return -1; | 153 | { |
151 | } | 154 | wval = 2; |
152 | if (UINT64_MAX == pc->file_size) | 155 | npos = (uint64_t) -pos; |
153 | { | ||
154 | wval = 2; | ||
155 | npos = (uint64_t) - pos; | ||
156 | break; | ||
157 | } | ||
158 | pos = (int64_t) (pc->file_size + pos); | ||
159 | /* fall-through! */ | ||
160 | case SEEK_SET: | ||
161 | if ( (pos < 0) || (pc->file_size < pos) ) | ||
162 | { | ||
163 | LOG ("Invalid seek operation\n"); | ||
164 | return -1; | ||
165 | } | ||
166 | npos = (uint64_t) pos; | ||
167 | wval = 0; | ||
168 | break; | 156 | break; |
169 | default: | 157 | } |
158 | pos = (int64_t) (pc->file_size + pos); | ||
159 | /* fall-through! */ | ||
160 | case SEEK_SET: | ||
161 | if ( (pos < 0) || (pc->file_size < pos) ) | ||
162 | { | ||
170 | LOG ("Invalid seek operation\n"); | 163 | LOG ("Invalid seek operation\n"); |
171 | return -1; | 164 | return -1; |
172 | } | 165 | } |
166 | npos = (uint64_t) pos; | ||
167 | wval = 0; | ||
168 | break; | ||
169 | default: | ||
170 | LOG ("Invalid seek operation\n"); | ||
171 | return -1; | ||
172 | } | ||
173 | if ( (pc->shm_off <= npos) && | 173 | if ( (pc->shm_off <= npos) && |
174 | (pc->shm_off + pc->shm_ready_bytes > npos) && | 174 | (pc->shm_off + pc->shm_ready_bytes > npos) && |
175 | (0 == wval) ) | 175 | (0 == wval) ) |
176 | { | 176 | { |
177 | pc->read_position = npos; | 177 | pc->read_position = npos; |
178 | return (int64_t) npos; | 178 | return (int64_t) npos; |
179 | } | 179 | } |
180 | /* need to seek */ | 180 | /* need to seek */ |
181 | srm.opcode = MESSAGE_SEEK; | 181 | srm.opcode = MESSAGE_SEEK; |
182 | srm.reserved = 0; | 182 | srm.reserved = 0; |
183 | srm.whence = wval; | 183 | srm.whence = wval; |
184 | srm.requested_bytes = pc->shm_map_size; | 184 | srm.requested_bytes = pc->shm_map_size; |
185 | if (0 == wval) | 185 | if (0 == wval) |
186 | { | 186 | { |
187 | if (srm.requested_bytes > pc->file_size - npos) | 187 | if (srm.requested_bytes > pc->file_size - npos) |
188 | srm.requested_bytes = pc->file_size - npos; | 188 | srm.requested_bytes = pc->file_size - npos; |
189 | } | 189 | } |
190 | else | 190 | else |
191 | { | 191 | { |
192 | srm.requested_bytes = npos; | 192 | srm.requested_bytes = npos; |
193 | } | 193 | } |
194 | srm.file_offset = npos; | 194 | srm.file_offset = npos; |
195 | if (-1 == EXTRACTOR_write_all_ (pc->out, &srm, sizeof (srm))) | 195 | if (-1 == EXTRACTOR_write_all_ (pc->out, &srm, sizeof (srm))) |
196 | { | 196 | { |
197 | LOG ("Failed to send MESSAGE_SEEK\n"); | 197 | LOG ("Failed to send MESSAGE_SEEK\n"); |
198 | return -1; | 198 | return -1; |
199 | } | 199 | } |
200 | if (-1 == | 200 | if (-1 == |
201 | EXTRACTOR_read_all_ (pc->in, | 201 | EXTRACTOR_read_all_ (pc->in, |
202 | &reply, sizeof (reply))) | 202 | &reply, sizeof (reply))) |
203 | { | 203 | { |
204 | LOG ("Plugin `%s' failed to read response to MESSAGE_SEEK\n", | 204 | LOG ("Plugin `%s' failed to read response to MESSAGE_SEEK\n", |
205 | pc->plugin->short_libname); | 205 | pc->plugin->short_libname); |
206 | return -1; | 206 | return -1; |
207 | } | 207 | } |
208 | if (MESSAGE_UPDATED_SHM != reply) | 208 | if (MESSAGE_UPDATED_SHM != reply) |
209 | { | 209 | { |
210 | LOG ("Unexpected reply %d to seek\n", reply); | 210 | LOG ("Unexpected reply %d to seek\n", reply); |
211 | return -1; /* was likely a MESSAGE_DISCARD_STATE */ | 211 | return -1; /* was likely a MESSAGE_DISCARD_STATE */ |
212 | } | 212 | } |
213 | if (-1 == EXTRACTOR_read_all_ (pc->in, &um.reserved, sizeof (um) - 1)) | 213 | if (-1 == EXTRACTOR_read_all_ (pc->in, &um.reserved, sizeof (um) - 1)) |
214 | { | 214 | { |
215 | LOG ("Failed to read MESSAGE_UPDATED_SHM\n"); | 215 | LOG ("Failed to read MESSAGE_UPDATED_SHM\n"); |
216 | return -1; | 216 | return -1; |
217 | } | 217 | } |
218 | pc->shm_off = um.shm_off; | 218 | pc->shm_off = um.shm_off; |
219 | pc->shm_ready_bytes = um.shm_ready_bytes; | 219 | pc->shm_ready_bytes = um.shm_ready_bytes; |
220 | pc->file_size = um.file_size; | 220 | pc->file_size = um.file_size; |
221 | if (2 == wval) | 221 | if (2 == wval) |
222 | { | 222 | { |
223 | /* convert offset to be absolute from beginning of the file */ | 223 | /* convert offset to be absolute from beginning of the file */ |
224 | npos = pc->file_size - npos; | 224 | npos = pc->file_size - npos; |
225 | } | 225 | } |
226 | if ( (pc->shm_off <= npos) && | 226 | if ( (pc->shm_off <= npos) && |
227 | ((pc->shm_off + pc->shm_ready_bytes > npos) || | 227 | ((pc->shm_off + pc->shm_ready_bytes > npos) || |
228 | (pc->file_size == pc->shm_off)) ) | 228 | (pc->file_size == pc->shm_off)) ) |
229 | { | 229 | { |
230 | pc->read_position = npos; | 230 | pc->read_position = npos; |
231 | return (int64_t) npos; | 231 | return (int64_t) npos; |
232 | } | 232 | } |
233 | /* oops, serious missunderstanding, we asked to seek | 233 | /* oops, serious missunderstanding, we asked to seek |
234 | and then were notified about a different position!? */ | 234 | and then were notified about a different position!? */ |
235 | LOG ("Plugin `%s' got invalid MESSAGE_UPDATED_SHM in response to my %d-seek (%llu not in %llu-%llu)\n", | 235 | LOG ( |
236 | pc->plugin->short_libname, | 236 | "Plugin `%s' got invalid MESSAGE_UPDATED_SHM in response to my %d-seek (%llu not in %llu-%llu)\n", |
237 | (int) wval, | 237 | pc->plugin->short_libname, |
238 | (unsigned long long) npos, | 238 | (int) wval, |
239 | (unsigned long long) pc->shm_off, | 239 | (unsigned long long) npos, |
240 | (unsigned long long) pc->shm_off + pc->shm_ready_bytes); | 240 | (unsigned long long) pc->shm_off, |
241 | (unsigned long long) pc->shm_off + pc->shm_ready_bytes); | ||
241 | return -1; | 242 | return -1; |
242 | } | 243 | } |
243 | 244 | ||
@@ -252,7 +253,7 @@ plugin_env_seek (void *cls, | |||
252 | */ | 253 | */ |
253 | static ssize_t | 254 | static ssize_t |
254 | plugin_env_read (void *cls, | 255 | plugin_env_read (void *cls, |
255 | void **data, | 256 | void **data, |
256 | size_t count) | 257 | size_t count) |
257 | { | 258 | { |
258 | struct ProcessingContext *pc = cls; | 259 | struct ProcessingContext *pc = cls; |
@@ -266,10 +267,10 @@ plugin_env_read (void *cls, | |||
266 | (pc->read_position < pc->file_size)) || | 267 | (pc->read_position < pc->file_size)) || |
267 | (pc->read_position < pc->shm_off) ) && | 268 | (pc->read_position < pc->shm_off) ) && |
268 | (-1 == plugin_env_seek (pc, pc->read_position, SEEK_SET) ) ) | 269 | (-1 == plugin_env_seek (pc, pc->read_position, SEEK_SET) ) ) |
269 | { | 270 | { |
270 | LOG ("Failed to seek to satisfy read\n"); | 271 | LOG ("Failed to seek to satisfy read\n"); |
271 | return -1; | 272 | return -1; |
272 | } | 273 | } |
273 | if (pc->read_position + count > pc->shm_off + pc->shm_ready_bytes) | 274 | if (pc->read_position + count > pc->shm_off + pc->shm_ready_bytes) |
274 | count = pc->shm_off + pc->shm_ready_bytes - pc->read_position; | 275 | count = pc->shm_off + pc->shm_ready_bytes - pc->read_position; |
275 | dp = pc->shm; | 276 | dp = pc->shm; |
@@ -313,12 +314,12 @@ plugin_env_get_size (void *cls) | |||
313 | */ | 314 | */ |
314 | static int | 315 | static int |
315 | plugin_env_send_proc (void *cls, | 316 | plugin_env_send_proc (void *cls, |
316 | const char *plugin_name, | 317 | const char *plugin_name, |
317 | enum EXTRACTOR_MetaType type, | 318 | enum EXTRACTOR_MetaType type, |
318 | enum EXTRACTOR_MetaFormat format, | 319 | enum EXTRACTOR_MetaFormat format, |
319 | const char *data_mime_type, | 320 | const char *data_mime_type, |
320 | const char *data, | 321 | const char *data, |
321 | size_t data_len) | 322 | size_t data_len) |
322 | { | 323 | { |
323 | struct ProcessingContext *pc = cls; | 324 | struct ProcessingContext *pc = cls; |
324 | struct MetaMessage mm; | 325 | struct MetaMessage mm; |
@@ -340,32 +341,32 @@ plugin_env_send_proc (void *cls, | |||
340 | mm.mime_length = (uint16_t) mime_len; | 341 | mm.mime_length = (uint16_t) mime_len; |
341 | mm.value_size = (uint32_t) data_len; | 342 | mm.value_size = (uint32_t) data_len; |
342 | if ( (sizeof (mm) != | 343 | if ( (sizeof (mm) != |
343 | EXTRACTOR_write_all_ (pc->out, | 344 | EXTRACTOR_write_all_ (pc->out, |
344 | &mm, sizeof (mm))) || | 345 | &mm, sizeof (mm))) || |
345 | (mime_len != | 346 | (mime_len != |
346 | EXTRACTOR_write_all_ (pc->out, | 347 | EXTRACTOR_write_all_ (pc->out, |
347 | data_mime_type, mime_len)) || | 348 | data_mime_type, mime_len)) || |
348 | (data_len != | 349 | (data_len != |
349 | EXTRACTOR_write_all_ (pc->out, | 350 | EXTRACTOR_write_all_ (pc->out, |
350 | data, data_len)) ) | 351 | data, data_len)) ) |
351 | { | 352 | { |
352 | LOG ("Failed to send meta message\n"); | 353 | LOG ("Failed to send meta message\n"); |
353 | return 1; | 354 | return 1; |
354 | } | 355 | } |
355 | if (-1 == | 356 | if (-1 == |
356 | EXTRACTOR_read_all_ (pc->in, | 357 | EXTRACTOR_read_all_ (pc->in, |
357 | &reply, sizeof (reply))) | 358 | &reply, sizeof (reply))) |
358 | { | 359 | { |
359 | LOG ("Failed to read response to meta message\n"); | 360 | LOG ("Failed to read response to meta message\n"); |
360 | return 1; | 361 | return 1; |
361 | } | 362 | } |
362 | if (MESSAGE_DISCARD_STATE == reply) | 363 | if (MESSAGE_DISCARD_STATE == reply) |
363 | return 1; | 364 | return 1; |
364 | if (MESSAGE_CONTINUE_EXTRACTING != reply) | 365 | if (MESSAGE_CONTINUE_EXTRACTING != reply) |
365 | { | 366 | { |
366 | LOG ("Received unexpected reply to meta data: %d\n", reply); | 367 | LOG ("Received unexpected reply to meta data: %d\n", reply); |
367 | return 1; | 368 | return 1; |
368 | } | 369 | } |
369 | return 0; | 370 | return 0; |
370 | } | 371 | } |
371 | 372 | ||
@@ -382,34 +383,34 @@ handle_init_message (struct ProcessingContext *pc) | |||
382 | struct InitMessage init; | 383 | struct InitMessage init; |
383 | 384 | ||
384 | if (NULL != pc->shm) | 385 | if (NULL != pc->shm) |
385 | { | 386 | { |
386 | LOG ("Cannot handle 'init' message, have already been initialized\n"); | 387 | LOG ("Cannot handle 'init' message, have already been initialized\n"); |
387 | return -1; | 388 | return -1; |
388 | } | 389 | } |
389 | if (sizeof (struct InitMessage) - 1 | 390 | if (sizeof (struct InitMessage) - 1 |
390 | != EXTRACTOR_read_all_ (pc->in, | 391 | != EXTRACTOR_read_all_ (pc->in, |
391 | &init.reserved, | 392 | &init.reserved, |
392 | sizeof (struct InitMessage) - 1)) | 393 | sizeof (struct InitMessage) - 1)) |
393 | { | 394 | { |
394 | LOG ("Failed to read 'init' message\n"); | 395 | LOG ("Failed to read 'init' message\n"); |
395 | return -1; | 396 | return -1; |
396 | } | 397 | } |
397 | if (init.shm_name_length > MAX_SHM_NAME) | 398 | if (init.shm_name_length > MAX_SHM_NAME) |
398 | { | 399 | { |
399 | LOG ("Invalid 'init' message\n"); | 400 | LOG ("Invalid 'init' message\n"); |
400 | return -1; | 401 | return -1; |
401 | } | 402 | } |
402 | { | 403 | { |
403 | char shm_name[init.shm_name_length + 1]; | 404 | char shm_name[init.shm_name_length + 1]; |
404 | 405 | ||
405 | if (init.shm_name_length | 406 | if (init.shm_name_length |
406 | != EXTRACTOR_read_all_ (pc->in, | 407 | != EXTRACTOR_read_all_ (pc->in, |
407 | shm_name, | 408 | shm_name, |
408 | init.shm_name_length)) | 409 | init.shm_name_length)) |
409 | { | 410 | { |
410 | LOG ("Failed to read 'init' message\n"); | 411 | LOG ("Failed to read 'init' message\n"); |
411 | return -1; | 412 | return -1; |
412 | } | 413 | } |
413 | shm_name[init.shm_name_length] = '\0'; | 414 | shm_name[init.shm_name_length] = '\0'; |
414 | 415 | ||
415 | pc->shm_map_size = init.shm_map_size; | 416 | pc->shm_map_size = init.shm_map_size; |
@@ -427,20 +428,20 @@ handle_init_message (struct ProcessingContext *pc) | |||
427 | #else | 428 | #else |
428 | pc->shm_id = shm_open (shm_name, O_RDONLY, 0); | 429 | pc->shm_id = shm_open (shm_name, O_RDONLY, 0); |
429 | if (-1 == pc->shm_id) | 430 | if (-1 == pc->shm_id) |
430 | { | 431 | { |
431 | LOG_STRERROR_FILE ("open", shm_name); | 432 | LOG_STRERROR_FILE ("open", shm_name); |
432 | return -1; | 433 | return -1; |
433 | } | 434 | } |
434 | pc->shm = mmap (NULL, | 435 | pc->shm = mmap (NULL, |
435 | pc->shm_map_size, | 436 | pc->shm_map_size, |
436 | PROT_READ, | 437 | PROT_READ, |
437 | MAP_SHARED, | 438 | MAP_SHARED, |
438 | pc->shm_id, 0); | 439 | pc->shm_id, 0); |
439 | if ( ((void*) -1) == pc->shm) | 440 | if ( ((void*) -1) == pc->shm) |
440 | { | 441 | { |
441 | LOG_STRERROR_FILE ("mmap", shm_name); | 442 | LOG_STRERROR_FILE ("mmap", shm_name); |
442 | return -1; | 443 | return -1; |
443 | } | 444 | } |
444 | #endif | 445 | #endif |
445 | } | 446 | } |
446 | return 0; | 447 | return 0; |
@@ -462,12 +463,12 @@ handle_start_message (struct ProcessingContext *pc) | |||
462 | 463 | ||
463 | if (sizeof (struct StartMessage) - 1 | 464 | if (sizeof (struct StartMessage) - 1 |
464 | != EXTRACTOR_read_all_ (pc->in, | 465 | != EXTRACTOR_read_all_ (pc->in, |
465 | &start.reserved, | 466 | &start.reserved, |
466 | sizeof (struct StartMessage) - 1)) | 467 | sizeof (struct StartMessage) - 1)) |
467 | { | 468 | { |
468 | LOG ("Failed to read 'start' message\n"); | 469 | LOG ("Failed to read 'start' message\n"); |
469 | return -1; | 470 | return -1; |
470 | } | 471 | } |
471 | pc->shm_ready_bytes = start.shm_ready_bytes; | 472 | pc->shm_ready_bytes = start.shm_ready_bytes; |
472 | pc->file_size = start.file_size; | 473 | pc->file_size = start.file_size; |
473 | pc->read_position = 0; | 474 | pc->read_position = 0; |
@@ -481,22 +482,22 @@ handle_start_message (struct ProcessingContext *pc) | |||
481 | pc->plugin->extract_method (&ec); | 482 | pc->plugin->extract_method (&ec); |
482 | done = MESSAGE_DONE; | 483 | done = MESSAGE_DONE; |
483 | if (-1 == EXTRACTOR_write_all_ (pc->out, &done, sizeof (done))) | 484 | if (-1 == EXTRACTOR_write_all_ (pc->out, &done, sizeof (done))) |
484 | { | 485 | { |
485 | LOG ("Failed to write 'done' message\n"); | 486 | LOG ("Failed to write 'done' message\n"); |
486 | return -1; | 487 | return -1; |
487 | } | 488 | } |
488 | if ( (NULL != pc->plugin->specials) && | 489 | if ( (NULL != pc->plugin->specials) && |
489 | (NULL != strstr (pc->plugin->specials, "force-kill")) ) | 490 | (NULL != strstr (pc->plugin->specials, "force-kill")) ) |
490 | { | 491 | { |
491 | /* we're required to die after each file since this | 492 | /* we're required to die after each file since this |
492 | plugin only supports a single file at a time */ | 493 | plugin only supports a single file at a time */ |
493 | #if !WINDOWS | 494 | #if ! WINDOWS |
494 | fsync (pc->out); | 495 | fsync (pc->out); |
495 | #else | 496 | #else |
496 | _commit (pc->out); | 497 | _commit (pc->out); |
497 | #endif | 498 | #endif |
498 | _exit (0); | 499 | _exit (0); |
499 | } | 500 | } |
500 | return 0; | 501 | return 0; |
501 | } | 502 | } |
502 | 503 | ||
@@ -511,43 +512,43 @@ static void | |||
511 | process_requests (struct ProcessingContext *pc) | 512 | process_requests (struct ProcessingContext *pc) |
512 | { | 513 | { |
513 | while (1) | 514 | while (1) |
515 | { | ||
516 | unsigned char code; | ||
517 | |||
518 | if (1 != EXTRACTOR_read_all_ (pc->in, &code, 1)) | ||
514 | { | 519 | { |
515 | unsigned char code; | 520 | LOG ("Failed to read next request\n"); |
516 | 521 | break; | |
517 | if (1 != EXTRACTOR_read_all_ (pc->in, &code, 1)) | ||
518 | { | ||
519 | LOG ("Failed to read next request\n"); | ||
520 | break; | ||
521 | } | ||
522 | switch (code) | ||
523 | { | ||
524 | case MESSAGE_INIT_STATE: | ||
525 | if (0 != handle_init_message (pc)) | ||
526 | { | ||
527 | LOG ("Failure to handle INIT\n"); | ||
528 | return; | ||
529 | } | ||
530 | break; | ||
531 | case MESSAGE_EXTRACT_START: | ||
532 | if (0 != handle_start_message (pc)) | ||
533 | { | ||
534 | LOG ("Failure to handle START\n"); | ||
535 | return; | ||
536 | } | ||
537 | break; | ||
538 | case MESSAGE_UPDATED_SHM: | ||
539 | LOG ("Illegal message\n"); | ||
540 | /* not allowed here, we're not waiting for SHM to move! */ | ||
541 | return; | ||
542 | case MESSAGE_DISCARD_STATE: | ||
543 | /* odd, we're already in the start state... */ | ||
544 | continue; | ||
545 | default: | ||
546 | LOG ("Received invalid messag %d\n", (int) code); | ||
547 | /* error, unexpected message */ | ||
548 | return; | ||
549 | } | ||
550 | } | 522 | } |
523 | switch (code) | ||
524 | { | ||
525 | case MESSAGE_INIT_STATE: | ||
526 | if (0 != handle_init_message (pc)) | ||
527 | { | ||
528 | LOG ("Failure to handle INIT\n"); | ||
529 | return; | ||
530 | } | ||
531 | break; | ||
532 | case MESSAGE_EXTRACT_START: | ||
533 | if (0 != handle_start_message (pc)) | ||
534 | { | ||
535 | LOG ("Failure to handle START\n"); | ||
536 | return; | ||
537 | } | ||
538 | break; | ||
539 | case MESSAGE_UPDATED_SHM: | ||
540 | LOG ("Illegal message\n"); | ||
541 | /* not allowed here, we're not waiting for SHM to move! */ | ||
542 | return; | ||
543 | case MESSAGE_DISCARD_STATE: | ||
544 | /* odd, we're already in the start state... */ | ||
545 | continue; | ||
546 | default: | ||
547 | LOG ("Received invalid messag %d\n", (int) code); | ||
548 | /* error, unexpected message */ | ||
549 | return; | ||
550 | } | ||
551 | } | ||
551 | } | 552 | } |
552 | 553 | ||
553 | 554 | ||
@@ -560,7 +561,7 @@ process_requests (struct ProcessingContext *pc) | |||
560 | */ | 561 | */ |
561 | static void | 562 | static void |
562 | open_dev_null (int target_fd, | 563 | open_dev_null (int target_fd, |
563 | int flags) | 564 | int flags) |
564 | { | 565 | { |
565 | int fd; | 566 | int fd; |
566 | 567 | ||
@@ -570,10 +571,10 @@ open_dev_null (int target_fd, | |||
570 | fd = open ("\\\\?\\NUL", flags); | 571 | fd = open ("\\\\?\\NUL", flags); |
571 | #endif | 572 | #endif |
572 | if (-1 == fd) | 573 | if (-1 == fd) |
573 | { | 574 | { |
574 | LOG_STRERROR_FILE ("open", "/dev/null"); | 575 | LOG_STRERROR_FILE ("open", "/dev/null"); |
575 | return; /* good luck */ | 576 | return; /* good luck */ |
576 | } | 577 | } |
577 | if (fd == target_fd) | 578 | if (fd == target_fd) |
578 | return; /* already done */ | 579 | return; /* already done */ |
579 | if (-1 == dup2 (fd, target_fd)) | 580 | if (-1 == dup2 (fd, target_fd)) |
@@ -598,32 +599,32 @@ open_dev_null (int target_fd, | |||
598 | */ | 599 | */ |
599 | void | 600 | void |
600 | EXTRACTOR_plugin_main_ (struct EXTRACTOR_PluginList *plugin, | 601 | EXTRACTOR_plugin_main_ (struct EXTRACTOR_PluginList *plugin, |
601 | int in, int out) | 602 | int in, int out) |
602 | { | 603 | { |
603 | struct ProcessingContext pc; | 604 | struct ProcessingContext pc; |
604 | 605 | ||
605 | if (0 != EXTRACTOR_plugin_load_ (plugin)) | 606 | if (0 != EXTRACTOR_plugin_load_ (plugin)) |
606 | { | 607 | { |
607 | #if DEBUG | 608 | #if DEBUG |
608 | fprintf (stderr, "Plugin `%s' failed to load!\n", | 609 | fprintf (stderr, "Plugin `%s' failed to load!\n", |
609 | plugin->short_libname); | 610 | plugin->short_libname); |
610 | #endif | 611 | #endif |
611 | return; | 612 | return; |
612 | } | 613 | } |
613 | if ( (NULL != plugin->specials) && | 614 | if ( (NULL != plugin->specials) && |
614 | (NULL != strstr (plugin->specials, "close-stderr"))) | 615 | (NULL != strstr (plugin->specials, "close-stderr"))) |
615 | { | 616 | { |
616 | if (0 != close (2)) | 617 | if (0 != close (2)) |
617 | LOG_STRERROR ("close"); | 618 | LOG_STRERROR ("close"); |
618 | open_dev_null (2, O_WRONLY); | 619 | open_dev_null (2, O_WRONLY); |
619 | } | 620 | } |
620 | if ( (NULL != plugin->specials) && | 621 | if ( (NULL != plugin->specials) && |
621 | (NULL != strstr (plugin->specials, "close-stdout"))) | 622 | (NULL != strstr (plugin->specials, "close-stdout"))) |
622 | { | 623 | { |
623 | if (0 != close (1)) | 624 | if (0 != close (1)) |
624 | LOG_STRERROR ("close"); | 625 | LOG_STRERROR ("close"); |
625 | open_dev_null (1, O_WRONLY); | 626 | open_dev_null (1, O_WRONLY); |
626 | } | 627 | } |
627 | pc.plugin = plugin; | 628 | pc.plugin = plugin; |
628 | pc.in = in; | 629 | pc.in = in; |
629 | pc.out = out; | 630 | pc.out = out; |
@@ -643,10 +644,10 @@ EXTRACTOR_plugin_main_ (struct EXTRACTOR_PluginList *plugin, | |||
643 | (((void*) 1) != pc.shm) ) | 644 | (((void*) 1) != pc.shm) ) |
644 | munmap (pc.shm, pc.shm_map_size); | 645 | munmap (pc.shm, pc.shm_map_size); |
645 | if (-1 != pc.shm_id) | 646 | if (-1 != pc.shm_id) |
646 | { | 647 | { |
647 | if (0 != close (pc.shm_id)) | 648 | if (0 != close (pc.shm_id)) |
648 | LOG_STRERROR ("close"); | 649 | LOG_STRERROR ("close"); |
649 | } | 650 | } |
650 | #endif | 651 | #endif |
651 | } | 652 | } |
652 | 653 | ||
@@ -668,43 +669,43 @@ read_plugin_data (int fd) | |||
668 | 669 | ||
669 | // FIXME: check for errors from 'EXTRACTOR_read_all_'! | 670 | // FIXME: check for errors from 'EXTRACTOR_read_all_'! |
670 | if (NULL == (ret = malloc (sizeof (struct EXTRACTOR_PluginList)))) | 671 | if (NULL == (ret = malloc (sizeof (struct EXTRACTOR_PluginList)))) |
671 | { | 672 | { |
672 | LOG_STRERROR ("malloc"); | 673 | LOG_STRERROR ("malloc"); |
673 | return NULL; | 674 | return NULL; |
674 | } | 675 | } |
675 | memset (ret, 0, sizeof (struct EXTRACTOR_PluginList)); | 676 | memset (ret, 0, sizeof (struct EXTRACTOR_PluginList)); |
676 | /*GetSystemInfo (&si); | 677 | /*GetSystemInfo (&si); |
677 | ret->allocation_granularity = si.dwAllocationGranularity;*/ | 678 | ret->allocation_granularity = si.dwAllocationGranularity;*/ |
678 | EXTRACTOR_read_all_ (fd, &i, sizeof (size_t)); | 679 | EXTRACTOR_read_all_ (fd, &i, sizeof (size_t)); |
679 | if (NULL == (ret->libname = malloc (i))) | 680 | if (NULL == (ret->libname = malloc (i))) |
680 | { | 681 | { |
681 | free (ret); | 682 | free (ret); |
682 | return NULL; | 683 | return NULL; |
683 | } | 684 | } |
684 | EXTRACTOR_read_all_ (fd, ret->libname, i); | 685 | EXTRACTOR_read_all_ (fd, ret->libname, i); |
685 | ret->libname[i - 1] = '\0'; | 686 | ret->libname[i - 1] = '\0'; |
686 | EXTRACTOR_read_all_ (fd, &i, sizeof (size_t)); | 687 | EXTRACTOR_read_all_ (fd, &i, sizeof (size_t)); |
687 | if (NULL == (ret->short_libname = malloc (i))) | 688 | if (NULL == (ret->short_libname = malloc (i))) |
688 | { | 689 | { |
689 | free (ret->libname); | 690 | free (ret->libname); |
690 | free (ret); | 691 | free (ret); |
691 | return NULL; | 692 | return NULL; |
692 | } | 693 | } |
693 | EXTRACTOR_read_all_ (fd, ret->short_libname, i); | 694 | EXTRACTOR_read_all_ (fd, ret->short_libname, i); |
694 | ret->short_libname[i - 1] = '\0'; | 695 | ret->short_libname[i - 1] = '\0'; |
695 | EXTRACTOR_read_all_ (fd, &i, sizeof (size_t)); | 696 | EXTRACTOR_read_all_ (fd, &i, sizeof (size_t)); |
696 | if (0 == i) | 697 | if (0 == i) |
697 | { | 698 | { |
698 | ret->plugin_options = NULL; | 699 | ret->plugin_options = NULL; |
699 | return ret; | 700 | return ret; |
700 | } | 701 | } |
701 | if (NULL == (ret->plugin_options = malloc (i))) | 702 | if (NULL == (ret->plugin_options = malloc (i))) |
702 | { | 703 | { |
703 | free (ret->short_libname); | 704 | free (ret->short_libname); |
704 | free (ret->libname); | 705 | free (ret->libname); |
705 | free (ret); | 706 | free (ret); |
706 | return NULL; | 707 | return NULL; |
707 | } | 708 | } |
708 | EXTRACTOR_read_all_ (fd, ret->plugin_options, i); | 709 | EXTRACTOR_read_all_ (fd, ret->plugin_options, i); |
709 | ret->plugin_options[i - 1] = '\0'; | 710 | ret->plugin_options[i - 1] = '\0'; |
710 | return ret; | 711 | return ret; |
@@ -716,9 +717,9 @@ read_plugin_data (int fd) | |||
716 | */ | 717 | */ |
717 | void CALLBACK | 718 | void CALLBACK |
718 | RundllEntryPoint (HWND hwnd, | 719 | RundllEntryPoint (HWND hwnd, |
719 | HINSTANCE hinst, | 720 | HINSTANCE hinst, |
720 | LPSTR lpszCmdLine, | 721 | LPSTR lpszCmdLine, |
721 | int nCmdShow) | 722 | int nCmdShow) |
722 | { | 723 | { |
723 | struct EXTRACTOR_PluginList *plugin; | 724 | struct EXTRACTOR_PluginList *plugin; |
724 | intptr_t in_h; | 725 | intptr_t in_h; |
@@ -732,11 +733,11 @@ RundllEntryPoint (HWND hwnd, | |||
732 | setmode (in, _O_BINARY); | 733 | setmode (in, _O_BINARY); |
733 | setmode (out, _O_BINARY); | 734 | setmode (out, _O_BINARY); |
734 | if (NULL == (plugin = read_plugin_data (in))) | 735 | if (NULL == (plugin = read_plugin_data (in))) |
735 | { | 736 | { |
736 | close (in); | 737 | close (in); |
737 | close (out); | 738 | close (out); |
738 | return; | 739 | return; |
739 | } | 740 | } |
740 | EXTRACTOR_plugin_main_ (plugin, in, out); | 741 | EXTRACTOR_plugin_main_ (plugin, in, out); |
741 | close (in); | 742 | close (in); |
742 | close (out); | 743 | close (out); |
@@ -745,8 +746,7 @@ RundllEntryPoint (HWND hwnd, | |||
745 | * called by the OS) or call FreeLibrary() on it directly or | 746 | * called by the OS) or call FreeLibrary() on it directly or |
746 | * indirectly. | 747 | * indirectly. |
747 | * By terminating here we alleviate that problem. | 748 | * By terminating here we alleviate that problem. |
748 | */ | 749 | */TerminateProcess (GetCurrentProcess (), 0); |
749 | TerminateProcess (GetCurrentProcess (), 0); | ||
750 | } | 750 | } |
751 | 751 | ||
752 | 752 | ||
@@ -755,9 +755,9 @@ RundllEntryPoint (HWND hwnd, | |||
755 | */ | 755 | */ |
756 | void CALLBACK | 756 | void CALLBACK |
757 | RundllEntryPointA (HWND hwnd, | 757 | RundllEntryPointA (HWND hwnd, |
758 | HINSTANCE hinst, | 758 | HINSTANCE hinst, |
759 | LPSTR lpszCmdLine, | 759 | LPSTR lpszCmdLine, |
760 | int nCmdShow) | 760 | int nCmdShow) |
761 | { | 761 | { |
762 | return RundllEntryPoint (hwnd, hinst, lpszCmdLine, nCmdShow); | 762 | return RundllEntryPoint (hwnd, hinst, lpszCmdLine, nCmdShow); |
763 | } | 763 | } |
diff --git a/src/main/extractor_plugin_main.h b/src/main/extractor_plugin_main.h index 1b33c8c..a683768 100644 --- a/src/main/extractor_plugin_main.h +++ b/src/main/extractor_plugin_main.h | |||
@@ -37,7 +37,7 @@ | |||
37 | * @param out stream to write to | 37 | * @param out stream to write to |
38 | */ | 38 | */ |
39 | void | 39 | void |
40 | EXTRACTOR_plugin_main_ (struct EXTRACTOR_PluginList *plugin, | 40 | EXTRACTOR_plugin_main_ (struct EXTRACTOR_PluginList *plugin, |
41 | int in, int out); | 41 | int in, int out); |
42 | 42 | ||
43 | #endif | 43 | #endif |
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 | } |
diff --git a/src/main/extractor_plugins.h b/src/main/extractor_plugins.h index 958ad94..8b0f5e6 100644 --- a/src/main/extractor_plugins.h +++ b/src/main/extractor_plugins.h | |||
@@ -59,7 +59,7 @@ struct EXTRACTOR_PluginList | |||
59 | * Short name of the plugin (i.e., 'foo') | 59 | * Short name of the plugin (i.e., 'foo') |
60 | */ | 60 | */ |
61 | char *short_libname; | 61 | char *short_libname; |
62 | 62 | ||
63 | /** | 63 | /** |
64 | * Pointer to the function used for meta data extraction. | 64 | * Pointer to the function used for meta data extraction. |
65 | */ | 65 | */ |
diff --git a/src/main/extractor_plugpath.c b/src/main/extractor_plugpath.c index 461f25e..4374bc5 100644 --- a/src/main/extractor_plugpath.c +++ b/src/main/extractor_plugpath.c | |||
@@ -41,7 +41,7 @@ | |||
41 | * @param path a directory path | 41 | * @param path a directory path |
42 | */ | 42 | */ |
43 | typedef void (*EXTRACTOR_PathProcessor) (void *cls, | 43 | typedef void (*EXTRACTOR_PathProcessor) (void *cls, |
44 | const char *path); | 44 | const char *path); |
45 | 45 | ||
46 | 46 | ||
47 | /** | 47 | /** |
@@ -51,7 +51,7 @@ typedef void (*EXTRACTOR_PathProcessor) (void *cls, | |||
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 | */ |
53 | static char * | 53 | static char * |
54 | cut_bin (char * in) | 54 | cut_bin (char *in) |
55 | { | 55 | { |
56 | size_t p; | 56 | size_t p; |
57 | 57 | ||
@@ -60,21 +60,21 @@ cut_bin (char * in) | |||
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 | ||
@@ -100,60 +100,62 @@ get_path_from_proc_exe () | |||
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 | { | ||
108 | while (NULL != fgets (line, 1024, f)) | ||
107 | { | 109 | { |
108 | while (NULL != fgets (line, 1024, f)) | 110 | if ( (1 == sscanf (line, |
109 | { | 111 | "%*x-%*x %*c%*c%*c%*c %*x %*2x:%*2x %*u%*[ ]%s", |
110 | if ( (1 == sscanf (line, | 112 | dir)) && |
111 | "%*x-%*x %*c%*c%*c%*c %*x %*2x:%*2x %*u%*[ ]%s", | 113 | (NULL != (lestr = strstr (dir, |
112 | dir)) && | 114 | "libextractor")) ) ) |
113 | (NULL != (lestr = strstr (dir, | 115 | { |
114 | "libextractor")) ) ) | 116 | lestr[0] = '\0'; |
115 | { | 117 | fclose (f); |
116 | lestr[0] = '\0'; | 118 | return strdup (dir); |
117 | fclose (f); | 119 | } |
118 | return strdup (dir); | ||
119 | } | ||
120 | } | ||
121 | fclose (f); | ||
122 | } | 120 | } |
121 | fclose (f); | ||
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 | |||
158 | |||
157 | #endif | 159 | #endif |
158 | 160 | ||
159 | 161 | ||
@@ -162,8 +164,8 @@ static HMODULE le_dll = NULL; | |||
162 | 164 | ||
163 | BOOL WINAPI | 165 | BOOL WINAPI |
164 | DllMain (HINSTANCE hinstDLL, | 166 | DllMain (HINSTANCE hinstDLL, |
165 | DWORD fdwReason, | 167 | DWORD fdwReason, |
166 | LPVOID lpvReserved) | 168 | LPVOID lpvReserved) |
167 | { | 169 | { |
168 | switch (fdwReason) | 170 | switch (fdwReason) |
169 | { | 171 | { |
@@ -175,6 +177,7 @@ DllMain (HINSTANCE hinstDLL, | |||
175 | return TRUE; | 177 | return TRUE; |
176 | } | 178 | } |
177 | 179 | ||
180 | |||
178 | /** | 181 | /** |
179 | * Try to determine path with win32-specific function | 182 | * Try to determine path with win32-specific function |
180 | */ | 183 | */ |
@@ -190,20 +193,22 @@ get_path_from_module_filename () | |||
190 | GetModuleFileName (le_dll, path, 4096); | 193 | GetModuleFileName (le_dll, path, 4096); |
191 | idx = path + strlen (path); | 194 | idx = path + strlen (path); |
192 | while ( (idx > path) && | 195 | while ( (idx > path) && |
193 | ('\\' != *idx) && | 196 | ('\\' != *idx) && |
194 | ('/' != *idx) ) | 197 | ('/' != *idx) ) |
195 | idx--; | 198 | idx--; |
196 | *idx = '\0'; | 199 | *idx = '\0'; |
197 | path = cut_bin (path); | 200 | path = cut_bin (path); |
198 | if (NULL == (ret = realloc (path, strlen(path) + 6))) | 201 | if (NULL == (ret = realloc (path, strlen (path) + 6))) |
199 | { | 202 | { |
200 | LOG_STRERROR ("realloc"); | 203 | LOG_STRERROR ("realloc"); |
201 | free (path); | 204 | free (path); |
202 | return NULL; | 205 | return NULL; |
203 | } | 206 | } |
204 | strcat (ret, "/lib/"); /* guess "lib/" as the library dir */ | 207 | strcat (ret, "/lib/"); /* guess "lib/" as the library dir */ |
205 | return ret; | 208 | return ret; |
206 | } | 209 | } |
210 | |||
211 | |||
207 | #endif | 212 | #endif |
208 | 213 | ||
209 | 214 | ||
@@ -239,8 +244,8 @@ get_path_from_NSGetExecutablePath () | |||
239 | 244 | ||
240 | path = NULL; | 245 | path = NULL; |
241 | if (NULL == (func = | 246 | if (NULL == (func = |
242 | (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, | 247 | (MyNSGetExecutablePathProto) dlsym (RTLD_DEFAULT, |
243 | "_NSGetExecutablePath"))) | 248 | "_NSGetExecutablePath"))) |
244 | return NULL; | 249 | return NULL; |
245 | path = &zero; | 250 | path = &zero; |
246 | len = 0; | 251 | len = 0; |
@@ -249,10 +254,10 @@ get_path_from_NSGetExecutablePath () | |||
249 | if (0 == len) | 254 | if (0 == len) |
250 | return NULL; | 255 | return NULL; |
251 | if (NULL == (path = malloc (len))) | 256 | if (NULL == (path = malloc (len))) |
252 | { | 257 | { |
253 | LOG_STRERROR ("malloc"); | 258 | LOG_STRERROR ("malloc"); |
254 | return NULL; | 259 | return NULL; |
255 | } | 260 | } |
256 | if (0 != func (path, &len)) | 261 | if (0 != func (path, &len)) |
257 | { | 262 | { |
258 | free (path); | 263 | free (path); |
@@ -267,9 +272,9 @@ get_path_from_NSGetExecutablePath () | |||
267 | path = cut_bin (path); | 272 | path = cut_bin (path); |
268 | if (NULL == (ret = realloc (path, strlen (path) + 5))) | 273 | if (NULL == (ret = realloc (path, strlen (path) + 5))) |
269 | { | 274 | { |
270 | LOG_STRERROR ("realloc"); | 275 | LOG_STRERROR ("realloc"); |
271 | free (path); | 276 | free (path); |
272 | return NULL; | 277 | return NULL; |
273 | } | 278 | } |
274 | strcat (ret, "/lib/"); | 279 | strcat (ret, "/lib/"); |
275 | return ret; | 280 | return ret; |
@@ -292,26 +297,28 @@ get_path_from_dyld_image () | |||
292 | 297 | ||
293 | c = _dyld_image_count (); | 298 | c = _dyld_image_count (); |
294 | for (i = 0; i < c; i++) | 299 | for (i = 0; i < c; i++) |
300 | { | ||
301 | if (((void *) _dyld_get_image_header (i)) != (void *) &_mh_dylib_header) | ||
302 | continue; | ||
303 | path = _dyld_get_image_name (i); | ||
304 | if ( (NULL == path) || (0 == strlen (path)) ) | ||
305 | continue; | ||
306 | if (NULL == (p = strdup (path))) | ||
295 | { | 307 | { |
296 | if (((void *) _dyld_get_image_header (i)) != (void *) &_mh_dylib_header) | 308 | LOG_STRERROR ("strdup"); |
297 | continue; | 309 | return NULL; |
298 | path = _dyld_get_image_name (i); | ||
299 | if ( (NULL == path) || (0 == strlen (path)) ) | ||
300 | continue; | ||
301 | if (NULL == (p = strdup (path))) | ||
302 | { | ||
303 | LOG_STRERROR ("strdup"); | ||
304 | return NULL; | ||
305 | } | ||
306 | s = p + strlen (p); | ||
307 | while ( (s > p) && ('/' != *s) ) | ||
308 | s--; | ||
309 | s++; | ||
310 | *s = '\0'; | ||
311 | return p; | ||
312 | } | 310 | } |
311 | s = p + strlen (p); | ||
312 | while ( (s > p) && ('/' != *s) ) | ||
313 | s--; | ||
314 | s++; | ||
315 | *s = '\0'; | ||
316 | return p; | ||
317 | } | ||
313 | return NULL; | 318 | return NULL; |
314 | } | 319 | } |
320 | |||
321 | |||
315 | #endif | 322 | #endif |
316 | 323 | ||
317 | 324 | ||
@@ -322,7 +329,7 @@ get_path_from_dyld_image () | |||
322 | * @return path to binary, NULL if not found | 329 | * @return path to binary, NULL if not found |
323 | */ | 330 | */ |
324 | static char * | 331 | static char * |
325 | get_path_from_PATH() | 332 | get_path_from_PATH () |
326 | { | 333 | { |
327 | struct stat sbuf; | 334 | struct stat sbuf; |
328 | char *path; | 335 | char *path; |
@@ -335,61 +342,61 @@ get_path_from_PATH() | |||
335 | if (NULL == (p = getenv ("PATH"))) | 342 | if (NULL == (p = getenv ("PATH"))) |
336 | return NULL; | 343 | return NULL; |
337 | if (NULL == (path = strdup (p))) /* because we write on it */ | 344 | if (NULL == (path = strdup (p))) /* because we write on it */ |
338 | { | 345 | { |
339 | LOG_STRERROR ("strdup"); | 346 | LOG_STRERROR ("strdup"); |
340 | return NULL; | 347 | return NULL; |
341 | } | 348 | } |
342 | if (NULL == (buf = malloc (strlen (path) + 20))) | 349 | if (NULL == (buf = malloc (strlen (path) + 20))) |
343 | { | 350 | { |
344 | LOG_STRERROR ("malloc"); | 351 | LOG_STRERROR ("malloc"); |
345 | free (path); | 352 | free (path); |
346 | return NULL; | 353 | return NULL; |
347 | } | 354 | } |
348 | pos = path; | 355 | pos = path; |
349 | while (NULL != (end = strchr(pos, ':'))) | 356 | while (NULL != (end = strchr (pos, ':'))) |
350 | { | 357 | { |
351 | *end = '\0'; | 358 | *end = '\0'; |
352 | sprintf (buf, "%s/%s", pos, "extract"); | 359 | sprintf (buf, "%s/%s", pos, "extract"); |
353 | if (0 == stat(buf, &sbuf)) | 360 | if (0 == stat (buf, &sbuf)) |
354 | { | ||
355 | free (buf); | ||
356 | if (NULL == (pos = strdup (pos))) | ||
357 | { | ||
358 | LOG_STRERROR ("strdup"); | ||
359 | free (path); | ||
360 | return NULL; | ||
361 | } | ||
362 | free (path); | ||
363 | pos = cut_bin (pos); | ||
364 | if (NULL == (ret = realloc (pos, strlen (pos) + 6))) | ||
365 | { | ||
366 | LOG_STRERROR ("realloc"); | ||
367 | free (pos); | ||
368 | return NULL; | ||
369 | } | ||
370 | strcat (ret, "/lib/"); | ||
371 | return ret; | ||
372 | } | ||
373 | pos = end + 1; | ||
374 | } | ||
375 | sprintf (buf, "%s/%s", pos, "extract"); | ||
376 | if (0 == stat (buf, &sbuf)) | ||
377 | { | 361 | { |
378 | pos = strdup (pos); | ||
379 | free (buf); | 362 | free (buf); |
363 | if (NULL == (pos = strdup (pos))) | ||
364 | { | ||
365 | LOG_STRERROR ("strdup"); | ||
366 | free (path); | ||
367 | return NULL; | ||
368 | } | ||
380 | free (path); | 369 | free (path); |
381 | if (NULL == pos) | ||
382 | return NULL; | ||
383 | pos = cut_bin (pos); | 370 | pos = cut_bin (pos); |
384 | if (NULL == (ret = realloc (pos, strlen (pos) + 6))) | 371 | if (NULL == (ret = realloc (pos, strlen (pos) + 6))) |
385 | { | 372 | { |
386 | LOG_STRERROR ("realloc"); | 373 | LOG_STRERROR ("realloc"); |
387 | free (pos); | 374 | free (pos); |
388 | return NULL; | 375 | return NULL; |
389 | } | 376 | } |
390 | strcat (ret, "/lib/"); | 377 | strcat (ret, "/lib/"); |
391 | return ret; | 378 | return ret; |
392 | } | 379 | } |
380 | pos = end + 1; | ||
381 | } | ||
382 | sprintf (buf, "%s/%s", pos, "extract"); | ||
383 | if (0 == stat (buf, &sbuf)) | ||
384 | { | ||
385 | pos = strdup (pos); | ||
386 | free (buf); | ||
387 | free (path); | ||
388 | if (NULL == pos) | ||
389 | return NULL; | ||
390 | pos = cut_bin (pos); | ||
391 | if (NULL == (ret = realloc (pos, strlen (pos) + 6))) | ||
392 | { | ||
393 | LOG_STRERROR ("realloc"); | ||
394 | free (pos); | ||
395 | return NULL; | ||
396 | } | ||
397 | strcat (ret, "/lib/"); | ||
398 | return ret; | ||
399 | } | ||
393 | free (buf); | 400 | free (buf); |
394 | free (path); | 401 | free (path); |
395 | return NULL; | 402 | return NULL; |
@@ -405,7 +412,7 @@ get_path_from_PATH() | |||
405 | */ | 412 | */ |
406 | static char * | 413 | static char * |
407 | append_to_dir (const char *path, | 414 | append_to_dir (const char *path, |
408 | const char *fname) | 415 | const char *fname) |
409 | { | 416 | { |
410 | char *ret; | 417 | char *ret; |
411 | size_t slen; | 418 | size_t slen; |
@@ -414,31 +421,31 @@ append_to_dir (const char *path, | |||
414 | return NULL; | 421 | return NULL; |
415 | if (DIR_SEPARATOR == fname[0]) | 422 | if (DIR_SEPARATOR == fname[0]) |
416 | fname++; | 423 | fname++; |
417 | ret = malloc (slen + strlen(fname) + 2); | 424 | ret = malloc (slen + strlen (fname) + 2); |
418 | if (NULL == ret) | 425 | if (NULL == ret) |
419 | return NULL; | 426 | return NULL; |
420 | #ifdef MINGW | 427 | #ifdef MINGW |
421 | if ('\\' == path[slen-1]) | 428 | if ('\\' == path[slen - 1]) |
422 | sprintf (ret, | 429 | sprintf (ret, |
423 | "%s%s", | 430 | "%s%s", |
424 | path, | 431 | path, |
425 | fname); | 432 | fname); |
426 | else | 433 | else |
427 | sprintf (ret, | 434 | sprintf (ret, |
428 | "%s\\%s", | 435 | "%s\\%s", |
429 | path, | 436 | path, |
430 | fname); | 437 | fname); |
431 | #else | 438 | #else |
432 | if ('/' == path[slen-1]) | 439 | if ('/' == path[slen - 1]) |
433 | sprintf (ret, | 440 | sprintf (ret, |
434 | "%s%s", | 441 | "%s%s", |
435 | path, | 442 | path, |
436 | fname); | 443 | fname); |
437 | else | 444 | else |
438 | sprintf (ret, | 445 | sprintf (ret, |
439 | "%s/%s", | 446 | "%s/%s", |
440 | path, | 447 | path, |
441 | fname); | 448 | fname); |
442 | #endif | 449 | #endif |
443 | return ret; | 450 | return ret; |
444 | } | 451 | } |
@@ -453,7 +460,7 @@ append_to_dir (const char *path, | |||
453 | */ | 460 | */ |
454 | static void | 461 | static void |
455 | get_installation_paths (EXTRACTOR_PathProcessor pp, | 462 | get_installation_paths (EXTRACTOR_PathProcessor pp, |
456 | void *pp_cls) | 463 | void *pp_cls) |
457 | { | 464 | { |
458 | const char *p; | 465 | const char *p; |
459 | char *path; | 466 | char *path; |
@@ -463,19 +470,19 @@ get_installation_paths (EXTRACTOR_PathProcessor pp, | |||
463 | 470 | ||
464 | prefix = NULL; | 471 | prefix = NULL; |
465 | if (NULL != (p = getenv ("LIBEXTRACTOR_PREFIX"))) | 472 | if (NULL != (p = getenv ("LIBEXTRACTOR_PREFIX"))) |
473 | { | ||
474 | if (NULL == (d = strdup (p))) | ||
466 | { | 475 | { |
467 | if (NULL == (d = strdup (p))) | 476 | LOG_STRERROR ("strdup"); |
468 | { | ||
469 | LOG_STRERROR ("strdup"); | ||
470 | return; | ||
471 | } | ||
472 | for (prefix = strtok_r (d, PATH_SEPARATOR_STR, &saveptr); | ||
473 | NULL != prefix; | ||
474 | prefix = strtok_r (NULL, PATH_SEPARATOR_STR, &saveptr)) | ||
475 | pp (pp_cls, prefix); | ||
476 | free (d); | ||
477 | return; | 477 | return; |
478 | } | 478 | } |
479 | for (prefix = strtok_r (d, PATH_SEPARATOR_STR, &saveptr); | ||
480 | NULL != prefix; | ||
481 | prefix = strtok_r (NULL, PATH_SEPARATOR_STR, &saveptr)) | ||
482 | pp (pp_cls, prefix); | ||
483 | free (d); | ||
484 | return; | ||
485 | } | ||
479 | #if GNU_LINUX | 486 | #if GNU_LINUX |
480 | if (NULL == prefix) | 487 | if (NULL == prefix) |
481 | prefix = get_path_from_proc_exe (); | 488 | prefix = get_path_from_proc_exe (); |
@@ -497,12 +504,12 @@ get_installation_paths (EXTRACTOR_PathProcessor pp, | |||
497 | return; | 504 | return; |
498 | path = append_to_dir (prefix, PLUGINDIR); | 505 | path = append_to_dir (prefix, PLUGINDIR); |
499 | if (NULL != path) | 506 | if (NULL != path) |
500 | { | 507 | { |
501 | if (0 != strcmp (path, | 508 | if (0 != strcmp (path, |
502 | PLUGININSTDIR)) | 509 | PLUGININSTDIR)) |
503 | pp (pp_cls, path); | 510 | pp (pp_cls, path); |
504 | free (path); | 511 | free (path); |
505 | } | 512 | } |
506 | free (prefix); | 513 | free (prefix); |
507 | } | 514 | } |
508 | 515 | ||
@@ -532,7 +539,7 @@ struct SearchContext | |||
532 | */ | 539 | */ |
533 | static void | 540 | static void |
534 | find_plugin_in_path (void *cls, | 541 | find_plugin_in_path (void *cls, |
535 | const char *path) | 542 | const char *path) |
536 | { | 543 | { |
537 | struct SearchContext *sc = cls; | 544 | struct SearchContext *sc = cls; |
538 | DIR *dir; | 545 | DIR *dir; |
@@ -547,34 +554,34 @@ find_plugin_in_path (void *cls, | |||
547 | if (NULL == (dir = OPENDIR (path))) | 554 | if (NULL == (dir = OPENDIR (path))) |
548 | return; | 555 | return; |
549 | while (NULL != (ent = READDIR (dir))) | 556 | while (NULL != (ent = READDIR (dir))) |
557 | { | ||
558 | if ('.' == ent->d_name[0]) | ||
559 | continue; | ||
560 | dlen = strlen (ent->d_name); | ||
561 | if ( (dlen < 4) || | ||
562 | ( (0 != strcmp (&ent->d_name[dlen - 3], ".so")) && | ||
563 | (0 != strcasecmp (&ent->d_name[dlen - 4], ".dll")) ) ) | ||
564 | continue; /* only load '.so' and '.dll' */ | ||
565 | if (NULL == (sym_name = strrchr (ent->d_name, '_'))) | ||
566 | continue; | ||
567 | sym_name++; | ||
568 | if (NULL == (sym = strdup (sym_name))) | ||
569 | { | ||
570 | LOG_STRERROR ("strdup"); | ||
571 | CLOSEDIR (dir); | ||
572 | return; | ||
573 | } | ||
574 | dot = strchr (sym, '.'); | ||
575 | if (NULL != dot) | ||
576 | *dot = '\0'; | ||
577 | if (0 == strcmp (sym, sc->short_name)) | ||
550 | { | 578 | { |
551 | if ('.' == ent->d_name[0]) | 579 | sc->path = append_to_dir (path, ent->d_name); |
552 | continue; | ||
553 | dlen = strlen (ent->d_name); | ||
554 | if ( (dlen < 4) || | ||
555 | ( (0 != strcmp (&ent->d_name[dlen-3], ".so")) && | ||
556 | (0 != strcasecmp (&ent->d_name[dlen-4], ".dll")) ) ) | ||
557 | continue; /* only load '.so' and '.dll' */ | ||
558 | if (NULL == (sym_name = strrchr (ent->d_name, '_'))) | ||
559 | continue; | ||
560 | sym_name++; | ||
561 | if (NULL == (sym = strdup (sym_name))) | ||
562 | { | ||
563 | LOG_STRERROR ("strdup"); | ||
564 | CLOSEDIR (dir); | ||
565 | return; | ||
566 | } | ||
567 | dot = strchr (sym, '.'); | ||
568 | if (NULL != dot) | ||
569 | *dot = '\0'; | ||
570 | if (0 == strcmp (sym, sc->short_name)) | ||
571 | { | ||
572 | sc->path = append_to_dir (path, ent->d_name); | ||
573 | free (sym); | ||
574 | break; | ||
575 | } | ||
576 | free (sym); | 580 | free (sym); |
581 | break; | ||
577 | } | 582 | } |
583 | free (sym); | ||
584 | } | ||
578 | CLOSEDIR (dir); | 585 | CLOSEDIR (dir); |
579 | } | 586 | } |
580 | 587 | ||
@@ -591,7 +598,7 @@ EXTRACTOR_find_plugin_ (const char *short_name) | |||
591 | sc.path = NULL; | 598 | sc.path = NULL; |
592 | sc.short_name = short_name; | 599 | sc.short_name = short_name; |
593 | get_installation_paths (&find_plugin_in_path, | 600 | get_installation_paths (&find_plugin_in_path, |
594 | &sc); | 601 | &sc); |
595 | return sc.path; | 602 | return sc.path; |
596 | } | 603 | } |
597 | 604 | ||
@@ -621,7 +628,7 @@ struct DefaultLoaderContext | |||
621 | */ | 628 | */ |
622 | static void | 629 | static void |
623 | load_plugins_from_dir (void *cls, | 630 | load_plugins_from_dir (void *cls, |
624 | const char *path) | 631 | const char *path) |
625 | { | 632 | { |
626 | struct DefaultLoaderContext *dlc = cls; | 633 | struct DefaultLoaderContext *dlc = cls; |
627 | DIR *dir; | 634 | DIR *dir; |
@@ -634,31 +641,31 @@ load_plugins_from_dir (void *cls, | |||
634 | if (NULL == (dir = opendir (path))) | 641 | if (NULL == (dir = opendir (path))) |
635 | return; | 642 | return; |
636 | while (NULL != (ent = readdir (dir))) | 643 | while (NULL != (ent = readdir (dir))) |
644 | { | ||
645 | if (ent->d_name[0] == '.') | ||
646 | continue; | ||
647 | dlen = strlen (ent->d_name); | ||
648 | if ( (dlen < 4) || | ||
649 | ( (0 != strcmp (&ent->d_name[dlen - 3], ".so")) && | ||
650 | (0 != strcasecmp (&ent->d_name[dlen - 4], ".dll")) ) ) | ||
651 | continue; /* only load '.so' and '.dll' */ | ||
652 | if (NULL == (sym_name = strrchr (ent->d_name, '_'))) | ||
653 | continue; | ||
654 | sym_name++; | ||
655 | if (NULL == (sym = strdup (sym_name))) | ||
637 | { | 656 | { |
638 | if (ent->d_name[0] == '.') | 657 | LOG_STRERROR ("strdup"); |
639 | continue; | 658 | closedir (dir); |
640 | dlen = strlen (ent->d_name); | 659 | return; |
641 | if ( (dlen < 4) || | ||
642 | ( (0 != strcmp (&ent->d_name[dlen-3], ".so")) && | ||
643 | (0 != strcasecmp (&ent->d_name[dlen-4], ".dll")) ) ) | ||
644 | continue; /* only load '.so' and '.dll' */ | ||
645 | if (NULL == (sym_name = strrchr (ent->d_name, '_'))) | ||
646 | continue; | ||
647 | sym_name++; | ||
648 | if (NULL == (sym = strdup (sym_name))) | ||
649 | { | ||
650 | LOG_STRERROR ("strdup"); | ||
651 | closedir (dir); | ||
652 | return; | ||
653 | } | ||
654 | if (NULL != (dot = strchr (sym, '.'))) | ||
655 | *dot = '\0'; | ||
656 | dlc->res = EXTRACTOR_plugin_add (dlc->res, | ||
657 | sym, | ||
658 | NULL, | ||
659 | dlc->flags); | ||
660 | free (sym); | ||
661 | } | 660 | } |
661 | if (NULL != (dot = strchr (sym, '.'))) | ||
662 | *dot = '\0'; | ||
663 | dlc->res = EXTRACTOR_plugin_add (dlc->res, | ||
664 | sym, | ||
665 | NULL, | ||
666 | dlc->flags); | ||
667 | free (sym); | ||
668 | } | ||
662 | closedir (dir); | 669 | closedir (dir); |
663 | } | 670 | } |
664 | 671 | ||
@@ -685,7 +692,7 @@ EXTRACTOR_plugin_add_defaults (enum EXTRACTOR_Options flags) | |||
685 | dlc.res = NULL; | 692 | dlc.res = NULL; |
686 | dlc.flags = flags; | 693 | dlc.flags = flags; |
687 | get_installation_paths (&load_plugins_from_dir, | 694 | get_installation_paths (&load_plugins_from_dir, |
688 | &dlc); | 695 | &dlc); |
689 | return dlc.res; | 696 | return dlc.res; |
690 | } | 697 | } |
691 | 698 | ||
diff --git a/src/main/extractor_plugpath.h b/src/main/extractor_plugpath.h index 848be52..3a3b217 100644 --- a/src/main/extractor_plugpath.h +++ b/src/main/extractor_plugpath.h | |||
@@ -29,9 +29,9 @@ | |||
29 | * Given a short name of a library (i.e. "mime"), find | 29 | * Given a short name of a library (i.e. "mime"), find |
30 | * the full path of the respective plugin. | 30 | * the full path of the respective plugin. |
31 | */ | 31 | */ |
32 | char * | 32 | char * |
33 | EXTRACTOR_find_plugin_ (const char *short_name); | 33 | EXTRACTOR_find_plugin_ (const char *short_name); |
34 | 34 | ||
35 | 35 | ||
36 | #endif | 36 | #endif |
37 | /* EXTRACTOR_PLUGPATH_H */ | 37 | /* EXTRACTOR_PLUGPATH_H */ |
diff --git a/src/main/extractor_print.c b/src/main/extractor_print.c index 3530430..a89b522 100644 --- a/src/main/extractor_print.c +++ b/src/main/extractor_print.c | |||
@@ -33,72 +33,73 @@ | |||
33 | * Simple EXTRACTOR_MetaDataProcessor implementation that simply | 33 | * Simple EXTRACTOR_MetaDataProcessor implementation that simply |
34 | * prints the extracted meta data to the given file. Only prints | 34 | * prints the extracted meta data to the given file. Only prints |
35 | * those keywords that are in UTF-8 format. | 35 | * those keywords that are in UTF-8 format. |
36 | * | 36 | * |
37 | * @param handle the file to write to (stdout, stderr), must NOT be NULL, | 37 | * @param handle the file to write to (stdout, stderr), must NOT be NULL, |
38 | * must be of type "FILE *". | 38 | * must be of type "FILE *". |
39 | * @param plugin_name name of the plugin that produced this value | 39 | * @param plugin_name name of the plugin that produced this value |
40 | * @param type libextractor-type describing the meta data | 40 | * @param type libextractor-type describing the meta data |
41 | * @param format basic format information about data | 41 | * @param format basic format information about data |
42 | * @param data_mime_type mime-type of data (not of the original file); | 42 | * @param data_mime_type mime-type of data (not of the original file); |
43 | * can be NULL (if mime-type is not known) | 43 | * can be NULL (if mime-type is not known) |
44 | * @param data actual meta-data found | 44 | * @param data actual meta-data found |
45 | * @param data_len number of bytes in data | 45 | * @param data_len number of bytes in data |
46 | * @return non-zero if printing failed, otherwise 0. | 46 | * @return non-zero if printing failed, otherwise 0. |
47 | */ | 47 | */ |
48 | int | 48 | int |
49 | EXTRACTOR_meta_data_print (void *handle, | 49 | EXTRACTOR_meta_data_print (void *handle, |
50 | const char *plugin_name, | 50 | const char *plugin_name, |
51 | enum EXTRACTOR_MetaType type, | 51 | enum EXTRACTOR_MetaType type, |
52 | enum EXTRACTOR_MetaFormat format, | 52 | enum EXTRACTOR_MetaFormat format, |
53 | const char *data_mime_type, | 53 | const char *data_mime_type, |
54 | const char *data, | 54 | const char *data, |
55 | size_t data_len) | 55 | size_t data_len) |
56 | { | 56 | { |
57 | #if HAVE_ICONV | 57 | #if HAVE_ICONV |
58 | iconv_t cd; | 58 | iconv_t cd; |
59 | #endif | 59 | #endif |
60 | char * buf; | 60 | char *buf; |
61 | int ret; | 61 | int ret; |
62 | const char *mt; | 62 | const char *mt; |
63 | 63 | ||
64 | if (EXTRACTOR_METAFORMAT_UTF8 != format) | 64 | if (EXTRACTOR_METAFORMAT_UTF8 != format) |
65 | return 0; | 65 | return 0; |
66 | #if HAVE_ICONV | 66 | #if HAVE_ICONV |
67 | cd = iconv_open (nl_langinfo(CODESET), | 67 | cd = iconv_open (nl_langinfo (CODESET), |
68 | "UTF-8"); | 68 | "UTF-8"); |
69 | if (((iconv_t) -1) == cd) | 69 | if (((iconv_t) -1) == cd) |
70 | { | 70 | { |
71 | LOG_STRERROR ("iconv_open"); | 71 | LOG_STRERROR ("iconv_open"); |
72 | return 1; | 72 | return 1; |
73 | } | 73 | } |
74 | buf = iconv_helper (cd, data, data_len); | 74 | buf = iconv_helper (cd, data, data_len); |
75 | if (NULL == buf) | 75 | if (NULL == buf) |
76 | { | 76 | { |
77 | LOG_STRERROR ("iconv_helper"); | 77 | LOG_STRERROR ("iconv_helper"); |
78 | ret = -1; | 78 | ret = -1; |
79 | } | 79 | } |
80 | else | 80 | else |
81 | { | 81 | { |
82 | mt = EXTRACTOR_metatype_to_string (type); | 82 | mt = EXTRACTOR_metatype_to_string (type); |
83 | ret = fprintf (handle, | 83 | ret = fprintf (handle, |
84 | "%s - %s\n", | 84 | "%s - %s\n", |
85 | (NULL == mt) | 85 | (NULL == mt) |
86 | ? dgettext ("libextractor", gettext_noop ("unknown")) | 86 | ? dgettext ("libextractor", gettext_noop ("unknown")) |
87 | : dgettext ("libextractor", mt), | 87 | : dgettext ("libextractor", mt), |
88 | buf); | 88 | buf); |
89 | free(buf); | 89 | free (buf); |
90 | } | 90 | } |
91 | iconv_close(cd); | 91 | iconv_close (cd); |
92 | #else | 92 | #else |
93 | ret = fprintf (handle, | 93 | ret = fprintf (handle, |
94 | "%s - %.*s\n", | 94 | "%s - %.*s\n", |
95 | (NULL == mt) | 95 | (NULL == mt) |
96 | ? dgettext ("libextractor", gettext_noop ("unknown")) | 96 | ? dgettext ("libextractor", gettext_noop ("unknown")) |
97 | : dgettext ("libextractor", mt), | 97 | : dgettext ("libextractor", mt), |
98 | (int) data_len, | 98 | (int) data_len, |
99 | data); | 99 | data); |
100 | #endif | 100 | #endif |
101 | return (ret < 0) ? 1 : 0; | 101 | return (ret < 0) ? 1 : 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | |||
104 | /* end of extractor_print.c */ | 105 | /* end of extractor_print.c */ |
diff --git a/src/main/getopt.c b/src/main/getopt.c index b64fdf5..890aa9b 100644 --- a/src/main/getopt.c +++ b/src/main/getopt.c | |||
@@ -4,7 +4,7 @@ | |||
4 | before changing it! | 4 | before changing it! |
5 | 5 | ||
6 | Copyright Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 | 6 | Copyright Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 |
7 | Free Software Foundation, Inc. | 7 | Free Software Foundation, Inc. |
8 | 8 | ||
9 | NOTE: The canonical source of this file is maintained with the GNU C Library. | 9 | NOTE: The canonical source of this file is maintained with the GNU C Library. |
10 | Bugs can be reported to bug-glibc@prep.ai.mit.edu. | 10 | Bugs can be reported to bug-glibc@prep.ai.mit.edu. |
@@ -32,7 +32,7 @@ USA. */ | |||
32 | 32 | ||
33 | #include "config.h" | 33 | #include "config.h" |
34 | 34 | ||
35 | #if !defined (__STDC__) || !__STDC__ | 35 | #if ! defined (__STDC__) || ! __STDC__ |
36 | /* This is a separate conditional since some stdc systems | 36 | /* This is a separate conditional since some stdc systems |
37 | reject `defined (const)'. */ | 37 | reject `defined (const)'. */ |
38 | #ifndef const | 38 | #ifndef const |
@@ -51,7 +51,7 @@ USA. */ | |||
51 | it is simpler to just do this in the source for each such file. */ | 51 | it is simpler to just do this in the source for each such file. */ |
52 | 52 | ||
53 | #define GETOPT_INTERFACE_VERSION 2 | 53 | #define GETOPT_INTERFACE_VERSION 2 |
54 | #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 | 54 | #if ! defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 |
55 | #include <gnu-versions.h> | 55 | #include <gnu-versions.h> |
56 | #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION | 56 | #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION |
57 | #define ELIDE_CODE | 57 | #define ELIDE_CODE |
@@ -63,7 +63,7 @@ USA. */ | |||
63 | 63 | ||
64 | /* This needs to come after some library #include | 64 | /* This needs to come after some library #include |
65 | to get __GNU_LIBRARY__ defined. */ | 65 | to get __GNU_LIBRARY__ defined. */ |
66 | #ifdef __GNU_LIBRARY__ | 66 | #ifdef __GNU_LIBRARY__ |
67 | /* Don't include stdlib.h for non-GNU C libraries because some of them | 67 | /* Don't include stdlib.h for non-GNU C libraries because some of them |
68 | contain conflicting prototypes for getopt. */ | 68 | contain conflicting prototypes for getopt. */ |
69 | #include <stdlib.h> | 69 | #include <stdlib.h> |
@@ -77,10 +77,10 @@ USA. */ | |||
77 | #include <string.h> | 77 | #include <string.h> |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | #if defined (WIN32) && !defined (__CYGWIN32__) | 80 | #if defined (WIN32) && ! defined (__CYGWIN32__) |
81 | /* It's not Unix, really. See? Capital letters. */ | 81 | /* It's not Unix, really. See? Capital letters. */ |
82 | #include <windows.h> | 82 | #include <windows.h> |
83 | #define getpid() GetCurrentProcessId() | 83 | #define getpid() GetCurrentProcessId () |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | #ifndef _ | 86 | #ifndef _ |
@@ -88,9 +88,9 @@ USA. */ | |||
88 | When compiling libc, the _ macro is predefined. */ | 88 | When compiling libc, the _ macro is predefined. */ |
89 | #ifdef NEVER_HAVE_LIBINTL_H | 89 | #ifdef NEVER_HAVE_LIBINTL_H |
90 | # include <libintl.h> | 90 | # include <libintl.h> |
91 | # define _(msgid) gettext (msgid) | 91 | # define _(msgid) gettext (msgid) |
92 | #else | 92 | #else |
93 | # define _(msgid) (msgid) | 93 | # define _(msgid) (msgid) |
94 | #endif | 94 | #endif |
95 | #endif | 95 | #endif |
96 | 96 | ||
@@ -195,14 +195,14 @@ static enum | |||
195 | 195 | ||
196 | /* Value of POSIXLY_CORRECT environment variable. */ | 196 | /* Value of POSIXLY_CORRECT environment variable. */ |
197 | static char *posixly_correct; | 197 | static char *posixly_correct; |
198 | 198 | ||
199 | #ifdef __GNU_LIBRARY__ | 199 | #ifdef __GNU_LIBRARY__ |
200 | /* We want to avoid inclusion of string.h with non-GNU libraries | 200 | /* We want to avoid inclusion of string.h with non-GNU libraries |
201 | because there are many ways it can cause trouble. | 201 | because there are many ways it can cause trouble. |
202 | On some systems, it contains special magic macros that don't work | 202 | On some systems, it contains special magic macros that don't work |
203 | in GCC. */ | 203 | in GCC. */ |
204 | #include <string.h> | 204 | #include <string.h> |
205 | #define my_index strchr | 205 | #define my_index strchr |
206 | #else | 206 | #else |
207 | 207 | ||
208 | /* Avoid depending on library functions or files | 208 | /* Avoid depending on library functions or files |
@@ -212,15 +212,16 @@ char *getenv (); | |||
212 | 212 | ||
213 | static char * | 213 | static char * |
214 | my_index (str, chr) | 214 | my_index (str, chr) |
215 | const char *str; | 215 | const char *str; |
216 | int chr; | 216 | |
217 | int chr; | ||
217 | { | 218 | { |
218 | while (*str) | 219 | while (*str) |
219 | { | 220 | { |
220 | if (*str == chr) | 221 | if (*str == chr) |
221 | return (char *) str; | 222 | return (char *) str; |
222 | str++; | 223 | str++; |
223 | } | 224 | } |
224 | return 0; | 225 | return 0; |
225 | } | 226 | } |
226 | 227 | ||
@@ -229,18 +230,20 @@ my_index (str, chr) | |||
229 | #ifdef __GNUC__ | 230 | #ifdef __GNUC__ |
230 | /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. | 231 | /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. |
231 | That was relevant to code that was here before. */ | 232 | That was relevant to code that was here before. */ |
232 | #if !defined (__STDC__) || !__STDC__ | 233 | #if ! defined (__STDC__) || ! __STDC__ |
233 | /* gcc with -traditional declares the built-in strlen to return int, | 234 | /* gcc with -traditional declares the built-in strlen to return int, |
234 | and has done so at least since version 2.4.5. -- rms. */ | 235 | and has done so at least since version 2.4.5. -- rms. */ |
235 | extern int strlen (const char *); | 236 | extern int strlen (const char *); |
237 | |||
236 | #endif /* not __STDC__ */ | 238 | #endif /* not __STDC__ */ |
237 | #if defined(__APPLE__) | 239 | #if defined(__APPLE__) |
238 | extern size_t strlen (const char *); | 240 | extern size_t strlen (const char *); |
241 | |||
239 | #endif | 242 | #endif |
240 | #endif /* __GNUC__ */ | 243 | #endif /* __GNUC__ */ |
241 | 244 | ||
242 | #endif /* not __GNU_LIBRARY__ */ | 245 | #endif /* not __GNU_LIBRARY__ */ |
243 | 246 | ||
244 | /* Handle permutation of arguments. */ | 247 | /* Handle permutation of arguments. */ |
245 | 248 | ||
246 | /* Describe the part of ARGV that contains non-options that have | 249 | /* Describe the part of ARGV that contains non-options that have |
@@ -269,7 +272,8 @@ extern pid_t __libc_pid; | |||
269 | is valid for the getopt call we must make sure that the ARGV passed | 272 | is valid for the getopt call we must make sure that the ARGV passed |
270 | to getopt is that one passed to the process. */ | 273 | to getopt is that one passed to the process. */ |
271 | static void | 274 | static void |
272 | __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv) | 275 | __attribute__ ((unused)) |
276 | store_args_and_env (int argc, char *const *argv) | ||
273 | { | 277 | { |
274 | /* XXX This is no good solution. We should rather copy the args so | 278 | /* XXX This is no good solution. We should rather copy the args so |
275 | that we can compare them later. But we must not use malloc(3). */ | 279 | that we can compare them later. But we must not use malloc(3). */ |
@@ -277,15 +281,16 @@ static void | |||
277 | original_argv = argv; | 281 | original_argv = argv; |
278 | } | 282 | } |
279 | 283 | ||
284 | |||
280 | text_set_element (__libc_subinit, store_args_and_env); | 285 | text_set_element (__libc_subinit, store_args_and_env); |
281 | 286 | ||
282 | # define SWAP_FLAGS(ch1, ch2) \ | 287 | # define SWAP_FLAGS(ch1, ch2) \ |
283 | if (nonoption_flags_len > 0) \ | 288 | if (nonoption_flags_len > 0) \ |
284 | { \ | 289 | { \ |
285 | char __tmp = __getopt_nonoption_flags[ch1]; \ | 290 | char __tmp = __getopt_nonoption_flags[ch1]; \ |
286 | __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ | 291 | __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ |
287 | __getopt_nonoption_flags[ch2] = __tmp; \ | 292 | __getopt_nonoption_flags[ch2] = __tmp; \ |
288 | } | 293 | } |
289 | #else /* !_LIBC */ | 294 | #else /* !_LIBC */ |
290 | # define SWAP_FLAGS(ch1, ch2) | 295 | # define SWAP_FLAGS(ch1, ch2) |
291 | #endif /* _LIBC */ | 296 | #endif /* _LIBC */ |
@@ -301,11 +306,13 @@ text_set_element (__libc_subinit, store_args_and_env); | |||
301 | 306 | ||
302 | #if defined (__STDC__) && __STDC__ | 307 | #if defined (__STDC__) && __STDC__ |
303 | static void exchange (char **); | 308 | static void exchange (char **); |
309 | |||
304 | #endif | 310 | #endif |
305 | 311 | ||
306 | static void | 312 | static void |
307 | exchange (argv) | 313 | exchange (argv) |
308 | char **argv; | 314 | char **argv; |
315 | |||
309 | { | 316 | { |
310 | int bottom = first_nonopt; | 317 | int bottom = first_nonopt; |
311 | int middle = last_nonopt; | 318 | int middle = last_nonopt; |
@@ -321,61 +328,61 @@ exchange (argv) | |||
321 | /* First make sure the handling of the `__getopt_nonoption_flags' | 328 | /* First make sure the handling of the `__getopt_nonoption_flags' |
322 | string can work normally. Our top argument must be in the range | 329 | string can work normally. Our top argument must be in the range |
323 | of the string. */ | 330 | of the string. */ |
324 | if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) | 331 | if ((nonoption_flags_len > 0) && (top >= nonoption_flags_max_len)) |
332 | { | ||
333 | /* We must extend the array. The user plays games with us and | ||
334 | presents new arguments. */ | ||
335 | char *new_str = malloc (top + 1); | ||
336 | if (new_str == NULL) | ||
337 | nonoption_flags_len = nonoption_flags_max_len = 0; | ||
338 | else | ||
325 | { | 339 | { |
326 | /* We must extend the array. The user plays games with us and | 340 | memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len); |
327 | presents new arguments. */ | 341 | memset (&new_str[nonoption_flags_max_len], '\0', |
328 | char *new_str = malloc (top + 1); | 342 | top + 1 - nonoption_flags_max_len); |
329 | if (new_str == NULL) | 343 | nonoption_flags_max_len = top + 1; |
330 | nonoption_flags_len = nonoption_flags_max_len = 0; | 344 | __getopt_nonoption_flags = new_str; |
331 | else | ||
332 | { | ||
333 | memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len); | ||
334 | memset (&new_str[nonoption_flags_max_len], '\0', | ||
335 | top + 1 - nonoption_flags_max_len); | ||
336 | nonoption_flags_max_len = top + 1; | ||
337 | __getopt_nonoption_flags = new_str; | ||
338 | } | ||
339 | } | 345 | } |
346 | } | ||
340 | #endif | 347 | #endif |
341 | 348 | ||
342 | while (top > middle && middle > bottom) | 349 | while (top > middle && middle > bottom) |
350 | { | ||
351 | if (top - middle > middle - bottom) | ||
343 | { | 352 | { |
344 | if (top - middle > middle - bottom) | 353 | /* Bottom segment is the short one. */ |
345 | { | 354 | int len = middle - bottom; |
346 | /* Bottom segment is the short one. */ | 355 | register int i; |
347 | int len = middle - bottom; | 356 | |
348 | register int i; | 357 | /* Swap it with the top part of the top segment. */ |
349 | 358 | for (i = 0; i < len; i++) | |
350 | /* Swap it with the top part of the top segment. */ | 359 | { |
351 | for (i = 0; i < len; i++) | 360 | tem = argv[bottom + i]; |
352 | { | 361 | argv[bottom + i] = argv[top - (middle - bottom) + i]; |
353 | tem = argv[bottom + i]; | 362 | argv[top - (middle - bottom) + i] = tem; |
354 | argv[bottom + i] = argv[top - (middle - bottom) + i]; | 363 | SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); |
355 | argv[top - (middle - bottom) + i] = tem; | 364 | } |
356 | SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); | 365 | /* Exclude the moved bottom segment from further swapping. */ |
357 | } | 366 | top -= len; |
358 | /* Exclude the moved bottom segment from further swapping. */ | 367 | } |
359 | top -= len; | 368 | else |
360 | } | 369 | { |
361 | else | 370 | /* Top segment is the short one. */ |
362 | { | 371 | int len = top - middle; |
363 | /* Top segment is the short one. */ | 372 | register int i; |
364 | int len = top - middle; | 373 | |
365 | register int i; | 374 | /* Swap it with the bottom part of the bottom segment. */ |
366 | 375 | for (i = 0; i < len; i++) | |
367 | /* Swap it with the bottom part of the bottom segment. */ | 376 | { |
368 | for (i = 0; i < len; i++) | 377 | tem = argv[bottom + i]; |
369 | { | 378 | argv[bottom + i] = argv[middle + i]; |
370 | tem = argv[bottom + i]; | 379 | argv[middle + i] = tem; |
371 | argv[bottom + i] = argv[middle + i]; | 380 | SWAP_FLAGS (bottom + i, middle + i); |
372 | argv[middle + i] = tem; | 381 | } |
373 | SWAP_FLAGS (bottom + i, middle + i); | 382 | /* Exclude the moved top segment from further swapping. */ |
374 | } | 383 | bottom += len; |
375 | /* Exclude the moved top segment from further swapping. */ | ||
376 | bottom += len; | ||
377 | } | ||
378 | } | 384 | } |
385 | } | ||
379 | 386 | ||
380 | /* Update records for the slots the non-options now occupy. */ | 387 | /* Update records for the slots the non-options now occupy. */ |
381 | 388 | ||
@@ -387,12 +394,14 @@ exchange (argv) | |||
387 | 394 | ||
388 | #if defined (__STDC__) && __STDC__ | 395 | #if defined (__STDC__) && __STDC__ |
389 | static const char *_getopt_initialize (int, char *const *, const char *); | 396 | static const char *_getopt_initialize (int, char *const *, const char *); |
397 | |||
390 | #endif | 398 | #endif |
391 | static const char * | 399 | static const char * |
392 | _getopt_initialize (argc, argv, optstring) | 400 | _getopt_initialize (argc, argv, optstring) |
393 | int argc; | 401 | int argc; |
394 | char *const *argv; | 402 | |
395 | const char *optstring; | 403 | char *const *argv; |
404 | const char *optstring; | ||
396 | { | 405 | { |
397 | /* Start processing options with ARGV-element 1 (since ARGV-element 0 | 406 | /* Start processing options with ARGV-element 1 (since ARGV-element 0 |
398 | is the program name); the sequence of previously skipped | 407 | is the program name); the sequence of previously skipped |
@@ -407,56 +416,56 @@ _getopt_initialize (argc, argv, optstring) | |||
407 | /* Determine how to handle the ordering of options and nonoptions. */ | 416 | /* Determine how to handle the ordering of options and nonoptions. */ |
408 | 417 | ||
409 | if (optstring[0] == '-') | 418 | if (optstring[0] == '-') |
410 | { | 419 | { |
411 | ordering = RETURN_IN_ORDER; | 420 | ordering = RETURN_IN_ORDER; |
412 | ++optstring; | 421 | ++optstring; |
413 | } | 422 | } |
414 | else if (optstring[0] == '+') | 423 | else if (optstring[0] == '+') |
415 | { | 424 | { |
416 | ordering = REQUIRE_ORDER; | 425 | ordering = REQUIRE_ORDER; |
417 | ++optstring; | 426 | ++optstring; |
418 | } | 427 | } |
419 | else if (posixly_correct != NULL) | 428 | else if (posixly_correct != NULL) |
420 | ordering = REQUIRE_ORDER; | 429 | ordering = REQUIRE_ORDER; |
421 | else | 430 | else |
422 | ordering = PERMUTE; | 431 | ordering = PERMUTE; |
423 | 432 | ||
424 | #ifdef _LIBC | 433 | #ifdef _LIBC |
425 | if (posixly_correct == NULL | 434 | if ((posixly_correct == NULL) |
426 | && argc == original_argc && argv == original_argv) | 435 | && (argc == original_argc) && (argv == original_argv)) |
436 | { | ||
437 | if (nonoption_flags_max_len == 0) | ||
427 | { | 438 | { |
428 | if (nonoption_flags_max_len == 0) | 439 | if ((__getopt_nonoption_flags == NULL) |
429 | { | 440 | || (__getopt_nonoption_flags[0] == '\0') ) |
430 | if (__getopt_nonoption_flags == NULL | 441 | nonoption_flags_max_len = -1; |
431 | || __getopt_nonoption_flags[0] == '\0') | 442 | else |
432 | nonoption_flags_max_len = -1; | 443 | { |
433 | else | 444 | const char *orig_str = __getopt_nonoption_flags; |
434 | { | 445 | int len = nonoption_flags_max_len = strlen (orig_str); |
435 | const char *orig_str = __getopt_nonoption_flags; | 446 | if (nonoption_flags_max_len < argc) |
436 | int len = nonoption_flags_max_len = strlen (orig_str); | 447 | nonoption_flags_max_len = argc; |
437 | if (nonoption_flags_max_len < argc) | 448 | __getopt_nonoption_flags = |
438 | nonoption_flags_max_len = argc; | 449 | (char *) malloc (nonoption_flags_max_len); |
439 | __getopt_nonoption_flags = | 450 | if (__getopt_nonoption_flags == NULL) |
440 | (char *) malloc (nonoption_flags_max_len); | 451 | nonoption_flags_max_len = -1; |
441 | if (__getopt_nonoption_flags == NULL) | 452 | else |
442 | nonoption_flags_max_len = -1; | 453 | { |
443 | else | 454 | memcpy (__getopt_nonoption_flags, orig_str, len); |
444 | { | 455 | memset (&__getopt_nonoption_flags[len], '\0', |
445 | memcpy (__getopt_nonoption_flags, orig_str, len); | 456 | nonoption_flags_max_len - len); |
446 | memset (&__getopt_nonoption_flags[len], '\0', | 457 | } |
447 | nonoption_flags_max_len - len); | 458 | } |
448 | } | ||
449 | } | ||
450 | } | ||
451 | nonoption_flags_len = nonoption_flags_max_len; | ||
452 | } | 459 | } |
460 | nonoption_flags_len = nonoption_flags_max_len; | ||
461 | } | ||
453 | else | 462 | else |
454 | nonoption_flags_len = 0; | 463 | nonoption_flags_len = 0; |
455 | #endif | 464 | #endif |
456 | 465 | ||
457 | return optstring; | 466 | return optstring; |
458 | } | 467 | } |
459 | 468 | ||
460 | /* Scan elements of ARGV (whose length is ARGC) for option characters | 469 | /* Scan elements of ARGV (whose length is ARGC) for option characters |
461 | given in OPTSTRING. | 470 | given in OPTSTRING. |
462 | 471 | ||
@@ -515,112 +524,113 @@ _getopt_initialize (argc, argv, optstring) | |||
515 | 524 | ||
516 | int | 525 | int |
517 | _getopt_internal (argc, argv, optstring, longopts, longind, long_only) | 526 | _getopt_internal (argc, argv, optstring, longopts, longind, long_only) |
518 | int argc; | 527 | int argc; |
519 | char *const *argv; | 528 | |
520 | const char *optstring; | 529 | char *const *argv; |
521 | const struct option *longopts; | 530 | const char *optstring; |
522 | int *longind; | 531 | const struct option *longopts; |
523 | int long_only; | 532 | int *longind; |
533 | int long_only; | ||
524 | { | 534 | { |
525 | optarg = NULL; | 535 | optarg = NULL; |
526 | 536 | ||
527 | if (optind == 0 || !__getopt_initialized) | 537 | if ((optind == 0) || ! __getopt_initialized) |
528 | { | 538 | { |
529 | if (optind == 0) | 539 | if (optind == 0) |
530 | optind = 1; /* Don't scan ARGV[0], the program name. */ | 540 | optind = 1; /* Don't scan ARGV[0], the program name. */ |
531 | optstring = _getopt_initialize (argc, argv, optstring); | 541 | optstring = _getopt_initialize (argc, argv, optstring); |
532 | __getopt_initialized = 1; | 542 | __getopt_initialized = 1; |
533 | } | 543 | } |
534 | 544 | ||
535 | /* Test whether ARGV[optind] points to a non-option argument. | 545 | /* Test whether ARGV[optind] points to a non-option argument. |
536 | Either it does not have option syntax, or there is an environment flag | 546 | Either it does not have option syntax, or there is an environment flag |
537 | from the shell indicating it is not an option. The later information | 547 | from the shell indicating it is not an option. The later information |
538 | is only used when the used in the GNU libc. */ | 548 | is only used when the used in the GNU libc. */ |
539 | #ifdef _LIBC | 549 | #ifdef _LIBC |
540 | #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ | 550 | #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ |
541 | || (optind < nonoption_flags_len \ | 551 | || (optind < nonoption_flags_len \ |
542 | && __getopt_nonoption_flags[optind] == '1')) | 552 | && __getopt_nonoption_flags[optind] == '1')) |
543 | #else | 553 | #else |
544 | #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') | 554 | #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') |
545 | #endif | 555 | #endif |
546 | 556 | ||
547 | if (nextchar == NULL || *nextchar == '\0') | 557 | if ((nextchar == NULL) || (*nextchar == '\0')) |
558 | { | ||
559 | /* Advance to the next ARGV-element. */ | ||
560 | |||
561 | /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been | ||
562 | moved back by the user (who may also have changed the arguments). */ | ||
563 | if (last_nonopt > optind) | ||
564 | last_nonopt = optind; | ||
565 | if (first_nonopt > optind) | ||
566 | first_nonopt = optind; | ||
567 | |||
568 | if (ordering == PERMUTE) | ||
548 | { | 569 | { |
549 | /* Advance to the next ARGV-element. */ | 570 | /* If we have just processed some options following some non-options, |
550 | 571 | exchange them so that the options come first. */ | |
551 | /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been | 572 | |
552 | moved back by the user (who may also have changed the arguments). */ | 573 | if ((first_nonopt != last_nonopt) && (last_nonopt != optind) ) |
553 | if (last_nonopt > optind) | 574 | exchange ((char **) argv); |
554 | last_nonopt = optind; | 575 | else if (last_nonopt != optind) |
555 | if (first_nonopt > optind) | 576 | first_nonopt = optind; |
556 | first_nonopt = optind; | 577 | |
557 | 578 | /* Skip any additional non-options | |
558 | if (ordering == PERMUTE) | 579 | and extend the range of non-options previously skipped. */ |
559 | { | 580 | |
560 | /* If we have just processed some options following some non-options, | 581 | while (optind < argc && NONOPTION_P) |
561 | exchange them so that the options come first. */ | 582 | optind++; |
562 | 583 | last_nonopt = optind; | |
563 | if (first_nonopt != last_nonopt && last_nonopt != optind) | ||
564 | exchange ((char **) argv); | ||
565 | else if (last_nonopt != optind) | ||
566 | first_nonopt = optind; | ||
567 | |||
568 | /* Skip any additional non-options | ||
569 | and extend the range of non-options previously skipped. */ | ||
570 | |||
571 | while (optind < argc && NONOPTION_P) | ||
572 | optind++; | ||
573 | last_nonopt = optind; | ||
574 | } | ||
575 | |||
576 | /* The special ARGV-element `--' means premature end of options. | ||
577 | Skip it like a null option, | ||
578 | then exchange with previous non-options as if it were an option, | ||
579 | then skip everything else like a non-option. */ | ||
580 | |||
581 | if (optind != argc && !strcmp (argv[optind], "--")) | ||
582 | { | ||
583 | optind++; | ||
584 | |||
585 | if (first_nonopt != last_nonopt && last_nonopt != optind) | ||
586 | exchange ((char **) argv); | ||
587 | else if (first_nonopt == last_nonopt) | ||
588 | first_nonopt = optind; | ||
589 | last_nonopt = argc; | ||
590 | |||
591 | optind = argc; | ||
592 | } | ||
593 | |||
594 | /* If we have done all the ARGV-elements, stop the scan | ||
595 | and back over any non-options that we skipped and permuted. */ | ||
596 | |||
597 | if (optind == argc) | ||
598 | { | ||
599 | /* Set the next-arg-index to point at the non-options | ||
600 | that we previously skipped, so the caller will digest them. */ | ||
601 | if (first_nonopt != last_nonopt) | ||
602 | optind = first_nonopt; | ||
603 | return -1; | ||
604 | } | ||
605 | |||
606 | /* If we have come to a non-option and did not permute it, | ||
607 | either stop the scan or describe it to the caller and pass it by. */ | ||
608 | |||
609 | if (NONOPTION_P) | ||
610 | { | ||
611 | if (ordering == REQUIRE_ORDER) | ||
612 | return -1; | ||
613 | optarg = argv[optind++]; | ||
614 | return 1; | ||
615 | } | ||
616 | |||
617 | /* We have found another option-ARGV-element. | ||
618 | Skip the initial punctuation. */ | ||
619 | |||
620 | nextchar = (argv[optind] + 1 | ||
621 | + (longopts != NULL && argv[optind][1] == '-')); | ||
622 | } | 584 | } |
623 | 585 | ||
586 | /* The special ARGV-element `--' means premature end of options. | ||
587 | Skip it like a null option, | ||
588 | then exchange with previous non-options as if it were an option, | ||
589 | then skip everything else like a non-option. */ | ||
590 | |||
591 | if ((optind != argc) && ! strcmp (argv[optind], "--")) | ||
592 | { | ||
593 | optind++; | ||
594 | |||
595 | if ((first_nonopt != last_nonopt) && (last_nonopt != optind) ) | ||
596 | exchange ((char **) argv); | ||
597 | else if (first_nonopt == last_nonopt) | ||
598 | first_nonopt = optind; | ||
599 | last_nonopt = argc; | ||
600 | |||
601 | optind = argc; | ||
602 | } | ||
603 | |||
604 | /* If we have done all the ARGV-elements, stop the scan | ||
605 | and back over any non-options that we skipped and permuted. */ | ||
606 | |||
607 | if (optind == argc) | ||
608 | { | ||
609 | /* Set the next-arg-index to point at the non-options | ||
610 | that we previously skipped, so the caller will digest them. */ | ||
611 | if (first_nonopt != last_nonopt) | ||
612 | optind = first_nonopt; | ||
613 | return -1; | ||
614 | } | ||
615 | |||
616 | /* If we have come to a non-option and did not permute it, | ||
617 | either stop the scan or describe it to the caller and pass it by. */ | ||
618 | |||
619 | if (NONOPTION_P) | ||
620 | { | ||
621 | if (ordering == REQUIRE_ORDER) | ||
622 | return -1; | ||
623 | optarg = argv[optind++]; | ||
624 | return 1; | ||
625 | } | ||
626 | |||
627 | /* We have found another option-ARGV-element. | ||
628 | Skip the initial punctuation. */ | ||
629 | |||
630 | nextchar = (argv[optind] + 1 | ||
631 | + (longopts != NULL && argv[optind][1] == '-')); | ||
632 | } | ||
633 | |||
624 | /* Decode the current option-ARGV-element. */ | 634 | /* Decode the current option-ARGV-element. */ |
625 | 635 | ||
626 | /* Check whether the ARGV-element is a long option. | 636 | /* Check whether the ARGV-element is a long option. |
@@ -636,141 +646,141 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) | |||
636 | 646 | ||
637 | This distinction seems to be the most useful approach. */ | 647 | This distinction seems to be the most useful approach. */ |
638 | 648 | ||
639 | if (longopts != NULL | 649 | if ((longopts != NULL) |
640 | && (argv[optind][1] == '-' | 650 | && ((argv[optind][1] == '-') |
641 | || (long_only | 651 | || (long_only |
642 | && (argv[optind][2] | 652 | && (argv[optind][2] |
643 | || !my_index (optstring, argv[optind][1]))))) | 653 | || ! my_index (optstring, argv[optind][1]))))) |
644 | { | 654 | { |
645 | char *nameend; | 655 | char *nameend; |
646 | const struct option *p; | 656 | const struct option *p; |
647 | const struct option *pfound = NULL; | 657 | const struct option *pfound = NULL; |
648 | int exact = 0; | 658 | int exact = 0; |
649 | int ambig = 0; | 659 | int ambig = 0; |
650 | int indfound = -1; | 660 | int indfound = -1; |
651 | int option_index; | 661 | int option_index; |
662 | |||
663 | for (nameend = nextchar; *nameend && *nameend != '='; nameend++) | ||
664 | /* Do nothing. */; | ||
665 | |||
666 | /* Test all long options for either exact match | ||
667 | or abbreviated matches. */ | ||
668 | for (p = longopts, option_index = 0; p->name; p++, option_index++) | ||
669 | if (! strncmp (p->name, nextchar, nameend - nextchar)) | ||
670 | { | ||
671 | if ((unsigned int) (nameend - nextchar) | ||
672 | == (unsigned int) strlen (p->name)) | ||
673 | { | ||
674 | /* Exact match found. */ | ||
675 | pfound = p; | ||
676 | indfound = option_index; | ||
677 | exact = 1; | ||
678 | break; | ||
679 | } | ||
680 | else if (pfound == NULL) | ||
681 | { | ||
682 | /* First nonexact match found. */ | ||
683 | pfound = p; | ||
684 | indfound = option_index; | ||
685 | } | ||
686 | else | ||
687 | /* Second or later nonexact match found. */ | ||
688 | ambig = 1; | ||
689 | } | ||
652 | 690 | ||
653 | for (nameend = nextchar; *nameend && *nameend != '='; nameend++) | 691 | if (ambig && ! exact) |
654 | /* Do nothing. */ ; | 692 | { |
693 | if (opterr) | ||
694 | fprintf (stderr, _ ("%s: option `%s' is ambiguous\n"), | ||
695 | argv[0], argv[optind]); | ||
696 | nextchar += strlen (nextchar); | ||
697 | optind++; | ||
698 | optopt = 0; | ||
699 | return '?'; | ||
700 | } | ||
655 | 701 | ||
656 | /* Test all long options for either exact match | 702 | if (pfound != NULL) |
657 | or abbreviated matches. */ | 703 | { |
658 | for (p = longopts, option_index = 0; p->name; p++, option_index++) | 704 | option_index = indfound; |
659 | if (!strncmp (p->name, nextchar, nameend - nextchar)) | 705 | optind++; |
660 | { | 706 | if (*nameend) |
661 | if ((unsigned int) (nameend - nextchar) | 707 | { |
662 | == (unsigned int) strlen (p->name)) | 708 | /* Don't test has_arg with >, because some C compilers don't |
663 | { | 709 | allow it to be used on enums. */ |
664 | /* Exact match found. */ | 710 | if (pfound->has_arg) |
665 | pfound = p; | 711 | optarg = nameend + 1; |
666 | indfound = option_index; | 712 | else |
667 | exact = 1; | 713 | { |
668 | break; | 714 | if (opterr) |
669 | } | 715 | if (argv[optind - 1][1] == '-') |
670 | else if (pfound == NULL) | 716 | /* --option */ |
671 | { | 717 | fprintf (stderr, |
672 | /* First nonexact match found. */ | 718 | _ |
673 | pfound = p; | 719 | ("%s: option `--%s' doesn't allow an argument\n"), |
674 | indfound = option_index; | 720 | argv[0], pfound->name); |
675 | } | 721 | else |
676 | else | 722 | /* +option or -option */ |
677 | /* Second or later nonexact match found. */ | 723 | fprintf (stderr, |
678 | ambig = 1; | 724 | _ |
679 | } | 725 | ("%s: option `%c%s' doesn't allow an argument\n"), |
680 | 726 | argv[0], argv[optind - 1][0], pfound->name); | |
681 | if (ambig && !exact) | 727 | |
682 | { | 728 | nextchar += strlen (nextchar); |
683 | if (opterr) | 729 | |
684 | fprintf (stderr, _("%s: option `%s' is ambiguous\n"), | 730 | optopt = pfound->val; |
685 | argv[0], argv[optind]); | 731 | return '?'; |
686 | nextchar += strlen (nextchar); | 732 | } |
687 | optind++; | 733 | } |
688 | optopt = 0; | 734 | else if (pfound->has_arg == 1) |
689 | return '?'; | 735 | { |
690 | } | 736 | if (optind < argc) |
737 | optarg = argv[optind++]; | ||
738 | else | ||
739 | { | ||
740 | if (opterr) | ||
741 | fprintf (stderr, | ||
742 | _ ("%s: option `%s' requires an argument\n"), | ||
743 | argv[0], argv[optind - 1]); | ||
744 | nextchar += strlen (nextchar); | ||
745 | optopt = pfound->val; | ||
746 | return optstring[0] == ':' ? ':' : '?'; | ||
747 | } | ||
748 | } | ||
749 | nextchar += strlen (nextchar); | ||
750 | if (longind != NULL) | ||
751 | *longind = option_index; | ||
752 | if (pfound->flag) | ||
753 | { | ||
754 | *(pfound->flag) = pfound->val; | ||
755 | return 0; | ||
756 | } | ||
757 | return pfound->val; | ||
758 | } | ||
691 | 759 | ||
692 | if (pfound != NULL) | 760 | /* Can't find it as a long option. If this is not getopt_long_only, |
693 | { | 761 | or the option starts with '--' or is not a valid short |
694 | option_index = indfound; | 762 | option, then it's an error. |
695 | optind++; | 763 | Otherwise interpret it as a short option. */ |
696 | if (*nameend) | 764 | if (! long_only || (argv[optind][1] == '-') |
697 | { | 765 | || (my_index (optstring, *nextchar) == NULL) ) |
698 | /* Don't test has_arg with >, because some C compilers don't | 766 | { |
699 | allow it to be used on enums. */ | 767 | if (opterr) |
700 | if (pfound->has_arg) | 768 | { |
701 | optarg = nameend + 1; | 769 | if (argv[optind][1] == '-') |
702 | else | 770 | /* --option */ |
703 | { | 771 | fprintf (stderr, _ ("%s: unrecognized option `--%s'\n"), |
704 | if (opterr) | 772 | argv[0], nextchar); |
705 | if (argv[optind - 1][1] == '-') | 773 | else |
706 | /* --option */ | 774 | /* +option or -option */ |
707 | fprintf (stderr, | 775 | fprintf (stderr, _ ("%s: unrecognized option `%c%s'\n"), |
708 | _ | 776 | argv[0], argv[optind][0], nextchar); |
709 | ("%s: option `--%s' doesn't allow an argument\n"), | 777 | } |
710 | argv[0], pfound->name); | 778 | nextchar = (char *) ""; |
711 | else | 779 | optind++; |
712 | /* +option or -option */ | 780 | optopt = 0; |
713 | fprintf (stderr, | 781 | return '?'; |
714 | _ | ||
715 | ("%s: option `%c%s' doesn't allow an argument\n"), | ||
716 | argv[0], argv[optind - 1][0], pfound->name); | ||
717 | |||
718 | nextchar += strlen (nextchar); | ||
719 | |||
720 | optopt = pfound->val; | ||
721 | return '?'; | ||
722 | } | ||
723 | } | ||
724 | else if (pfound->has_arg == 1) | ||
725 | { | ||
726 | if (optind < argc) | ||
727 | optarg = argv[optind++]; | ||
728 | else | ||
729 | { | ||
730 | if (opterr) | ||
731 | fprintf (stderr, | ||
732 | _("%s: option `%s' requires an argument\n"), | ||
733 | argv[0], argv[optind - 1]); | ||
734 | nextchar += strlen (nextchar); | ||
735 | optopt = pfound->val; | ||
736 | return optstring[0] == ':' ? ':' : '?'; | ||
737 | } | ||
738 | } | ||
739 | nextchar += strlen (nextchar); | ||
740 | if (longind != NULL) | ||
741 | *longind = option_index; | ||
742 | if (pfound->flag) | ||
743 | { | ||
744 | *(pfound->flag) = pfound->val; | ||
745 | return 0; | ||
746 | } | ||
747 | return pfound->val; | ||
748 | } | ||
749 | |||
750 | /* Can't find it as a long option. If this is not getopt_long_only, | ||
751 | or the option starts with '--' or is not a valid short | ||
752 | option, then it's an error. | ||
753 | Otherwise interpret it as a short option. */ | ||
754 | if (!long_only || argv[optind][1] == '-' | ||
755 | || my_index (optstring, *nextchar) == NULL) | ||
756 | { | ||
757 | if (opterr) | ||
758 | { | ||
759 | if (argv[optind][1] == '-') | ||
760 | /* --option */ | ||
761 | fprintf (stderr, _("%s: unrecognized option `--%s'\n"), | ||
762 | argv[0], nextchar); | ||
763 | else | ||
764 | /* +option or -option */ | ||
765 | fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), | ||
766 | argv[0], argv[optind][0], nextchar); | ||
767 | } | ||
768 | nextchar = (char *) ""; | ||
769 | optind++; | ||
770 | optopt = 0; | ||
771 | return '?'; | ||
772 | } | ||
773 | } | 782 | } |
783 | } | ||
774 | 784 | ||
775 | /* Look at and handle the next short option-character. */ | 785 | /* Look at and handle the next short option-character. */ |
776 | 786 | ||
@@ -782,205 +792,207 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) | |||
782 | if (*nextchar == '\0') | 792 | if (*nextchar == '\0') |
783 | ++optind; | 793 | ++optind; |
784 | 794 | ||
785 | if (temp == NULL || c == ':') | 795 | if ((temp == NULL) || (c == ':')) |
796 | { | ||
797 | if (opterr) | ||
786 | { | 798 | { |
787 | if (opterr) | 799 | if (posixly_correct) |
788 | { | 800 | /* 1003.2 specifies the format of this message. */ |
789 | if (posixly_correct) | 801 | fprintf (stderr, _ ("%s: illegal option -- %c\n"), argv[0], c); |
790 | /* 1003.2 specifies the format of this message. */ | 802 | else |
791 | fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); | 803 | fprintf (stderr, _ ("%s: invalid option -- %c\n"), argv[0], c); |
792 | else | ||
793 | fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); | ||
794 | } | ||
795 | optopt = c; | ||
796 | return '?'; | ||
797 | } | 804 | } |
805 | optopt = c; | ||
806 | return '?'; | ||
807 | } | ||
798 | /* Convenience. Treat POSIX -W foo same as long option --foo */ | 808 | /* Convenience. Treat POSIX -W foo same as long option --foo */ |
799 | if (temp[0] == 'W' && temp[1] == ';') | 809 | if ((temp[0] == 'W') && (temp[1] == ';')) |
810 | { | ||
811 | char *nameend; | ||
812 | const struct option *p; | ||
813 | const struct option *pfound = NULL; | ||
814 | int exact = 0; | ||
815 | int ambig = 0; | ||
816 | int indfound = 0; | ||
817 | int option_index; | ||
818 | |||
819 | /* This is an option that requires an argument. */ | ||
820 | if (*nextchar != '\0') | ||
821 | { | ||
822 | optarg = nextchar; | ||
823 | /* If we end this ARGV-element by taking the rest as an arg, | ||
824 | we must advance to the next element now. */ | ||
825 | optind++; | ||
826 | } | ||
827 | else if (optind == argc) | ||
828 | { | ||
829 | if (opterr) | ||
830 | { | ||
831 | /* 1003.2 specifies the format of this message. */ | ||
832 | fprintf (stderr, _ ("%s: option requires an argument -- %c\n"), | ||
833 | argv[0], c); | ||
834 | } | ||
835 | optopt = c; | ||
836 | if (optstring[0] == ':') | ||
837 | c = ':'; | ||
838 | else | ||
839 | c = '?'; | ||
840 | return c; | ||
841 | } | ||
842 | else | ||
843 | /* We already incremented `optind' once; | ||
844 | increment it again when taking next ARGV-elt as argument. */ | ||
845 | optarg = argv[optind++]; | ||
846 | |||
847 | /* optarg is now the argument, see if it's in the | ||
848 | table of longopts. */ | ||
849 | |||
850 | for (nextchar = nameend = optarg; *nameend && *nameend != '='; | ||
851 | nameend++) | ||
852 | /* Do nothing. */; | ||
853 | |||
854 | /* Test all long options for either exact match | ||
855 | or abbreviated matches. */ | ||
856 | for (p = longopts, option_index = 0; p->name; p++, option_index++) | ||
857 | if (! strncmp (p->name, nextchar, nameend - nextchar)) | ||
858 | { | ||
859 | if ((unsigned int) (nameend - nextchar) == strlen (p->name)) | ||
860 | { | ||
861 | /* Exact match found. */ | ||
862 | pfound = p; | ||
863 | indfound = option_index; | ||
864 | exact = 1; | ||
865 | break; | ||
866 | } | ||
867 | else if (pfound == NULL) | ||
868 | { | ||
869 | /* First nonexact match found. */ | ||
870 | pfound = p; | ||
871 | indfound = option_index; | ||
872 | } | ||
873 | else | ||
874 | /* Second or later nonexact match found. */ | ||
875 | ambig = 1; | ||
876 | } | ||
877 | if (ambig && ! exact) | ||
878 | { | ||
879 | if (opterr) | ||
880 | fprintf (stderr, _ ("%s: option `-W %s' is ambiguous\n"), | ||
881 | argv[0], argv[optind]); | ||
882 | nextchar += strlen (nextchar); | ||
883 | optind++; | ||
884 | return '?'; | ||
885 | } | ||
886 | if (pfound != NULL) | ||
800 | { | 887 | { |
801 | char *nameend; | 888 | option_index = indfound; |
802 | const struct option *p; | 889 | if (*nameend) |
803 | const struct option *pfound = NULL; | 890 | { |
804 | int exact = 0; | 891 | /* Don't test has_arg with >, because some C compilers don't |
805 | int ambig = 0; | 892 | allow it to be used on enums. */ |
806 | int indfound = 0; | 893 | if (pfound->has_arg) |
807 | int option_index; | 894 | optarg = nameend + 1; |
808 | 895 | else | |
809 | /* This is an option that requires an argument. */ | 896 | { |
810 | if (*nextchar != '\0') | 897 | if (opterr) |
811 | { | 898 | fprintf (stderr, _ ( |
812 | optarg = nextchar; | 899 | "\ |
813 | /* If we end this ARGV-element by taking the rest as an arg, | ||
814 | we must advance to the next element now. */ | ||
815 | optind++; | ||
816 | } | ||
817 | else if (optind == argc) | ||
818 | { | ||
819 | if (opterr) | ||
820 | { | ||
821 | /* 1003.2 specifies the format of this message. */ | ||
822 | fprintf (stderr, _("%s: option requires an argument -- %c\n"), | ||
823 | argv[0], c); | ||
824 | } | ||
825 | optopt = c; | ||
826 | if (optstring[0] == ':') | ||
827 | c = ':'; | ||
828 | else | ||
829 | c = '?'; | ||
830 | return c; | ||
831 | } | ||
832 | else | ||
833 | /* We already incremented `optind' once; | ||
834 | increment it again when taking next ARGV-elt as argument. */ | ||
835 | optarg = argv[optind++]; | ||
836 | |||
837 | /* optarg is now the argument, see if it's in the | ||
838 | table of longopts. */ | ||
839 | |||
840 | for (nextchar = nameend = optarg; *nameend && *nameend != '='; | ||
841 | nameend++) | ||
842 | /* Do nothing. */ ; | ||
843 | |||
844 | /* Test all long options for either exact match | ||
845 | or abbreviated matches. */ | ||
846 | for (p = longopts, option_index = 0; p->name; p++, option_index++) | ||
847 | if (!strncmp (p->name, nextchar, nameend - nextchar)) | ||
848 | { | ||
849 | if ((unsigned int) (nameend - nextchar) == strlen (p->name)) | ||
850 | { | ||
851 | /* Exact match found. */ | ||
852 | pfound = p; | ||
853 | indfound = option_index; | ||
854 | exact = 1; | ||
855 | break; | ||
856 | } | ||
857 | else if (pfound == NULL) | ||
858 | { | ||
859 | /* First nonexact match found. */ | ||
860 | pfound = p; | ||
861 | indfound = option_index; | ||
862 | } | ||
863 | else | ||
864 | /* Second or later nonexact match found. */ | ||
865 | ambig = 1; | ||
866 | } | ||
867 | if (ambig && !exact) | ||
868 | { | ||
869 | if (opterr) | ||
870 | fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), | ||
871 | argv[0], argv[optind]); | ||
872 | nextchar += strlen (nextchar); | ||
873 | optind++; | ||
874 | return '?'; | ||
875 | } | ||
876 | if (pfound != NULL) | ||
877 | { | ||
878 | option_index = indfound; | ||
879 | if (*nameend) | ||
880 | { | ||
881 | /* Don't test has_arg with >, because some C compilers don't | ||
882 | allow it to be used on enums. */ | ||
883 | if (pfound->has_arg) | ||
884 | optarg = nameend + 1; | ||
885 | else | ||
886 | { | ||
887 | if (opterr) | ||
888 | fprintf (stderr, _("\ | ||
889 | %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); | 900 | %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); |
890 | 901 | ||
891 | nextchar += strlen (nextchar); | 902 | nextchar += strlen (nextchar); |
892 | return '?'; | 903 | return '?'; |
893 | } | 904 | } |
894 | } | 905 | } |
895 | else if (pfound->has_arg == 1) | 906 | else if (pfound->has_arg == 1) |
896 | { | 907 | { |
897 | if (optind < argc) | 908 | if (optind < argc) |
898 | optarg = argv[optind++]; | 909 | optarg = argv[optind++]; |
899 | else | 910 | else |
900 | { | 911 | { |
901 | if (opterr) | 912 | if (opterr) |
902 | fprintf (stderr, | 913 | fprintf (stderr, |
903 | _("%s: option `%s' requires an argument\n"), | 914 | _ ("%s: option `%s' requires an argument\n"), |
904 | argv[0], argv[optind - 1]); | 915 | argv[0], argv[optind - 1]); |
905 | nextchar += strlen (nextchar); | 916 | nextchar += strlen (nextchar); |
906 | return optstring[0] == ':' ? ':' : '?'; | 917 | return optstring[0] == ':' ? ':' : '?'; |
907 | } | 918 | } |
908 | } | 919 | } |
909 | nextchar += strlen (nextchar); | 920 | nextchar += strlen (nextchar); |
910 | if (longind != NULL) | 921 | if (longind != NULL) |
911 | *longind = option_index; | 922 | *longind = option_index; |
912 | if (pfound->flag) | 923 | if (pfound->flag) |
913 | { | 924 | { |
914 | *(pfound->flag) = pfound->val; | 925 | *(pfound->flag) = pfound->val; |
915 | return 0; | 926 | return 0; |
916 | } | 927 | } |
917 | return pfound->val; | 928 | return pfound->val; |
918 | } | ||
919 | nextchar = NULL; | ||
920 | return 'W'; /* Let the application handle it. */ | ||
921 | } | 929 | } |
930 | nextchar = NULL; | ||
931 | return 'W'; /* Let the application handle it. */ | ||
932 | } | ||
922 | if (temp[1] == ':') | 933 | if (temp[1] == ':') |
934 | { | ||
935 | if (temp[2] == ':') | ||
936 | { | ||
937 | /* This is an option that accepts an argument optionally. */ | ||
938 | if (*nextchar != '\0') | ||
939 | { | ||
940 | optarg = nextchar; | ||
941 | optind++; | ||
942 | } | ||
943 | else | ||
944 | optarg = NULL; | ||
945 | nextchar = NULL; | ||
946 | } | ||
947 | else | ||
923 | { | 948 | { |
924 | if (temp[2] == ':') | 949 | /* This is an option that requires an argument. */ |
925 | { | 950 | if (*nextchar != '\0') |
926 | /* This is an option that accepts an argument optionally. */ | 951 | { |
927 | if (*nextchar != '\0') | 952 | optarg = nextchar; |
928 | { | 953 | /* If we end this ARGV-element by taking the rest as an arg, |
929 | optarg = nextchar; | 954 | we must advance to the next element now. */ |
930 | optind++; | 955 | optind++; |
931 | } | 956 | } |
932 | else | 957 | else if (optind == argc) |
933 | optarg = NULL; | 958 | { |
934 | nextchar = NULL; | 959 | if (opterr) |
935 | } | 960 | { |
936 | else | 961 | /* 1003.2 specifies the format of this message. */ |
937 | { | 962 | fprintf (stderr, |
938 | /* This is an option that requires an argument. */ | 963 | _ ("%s: option requires an argument -- %c\n"), |
939 | if (*nextchar != '\0') | 964 | argv[0], c); |
940 | { | 965 | } |
941 | optarg = nextchar; | 966 | optopt = c; |
942 | /* If we end this ARGV-element by taking the rest as an arg, | 967 | if (optstring[0] == ':') |
943 | we must advance to the next element now. */ | 968 | c = ':'; |
944 | optind++; | 969 | else |
945 | } | 970 | c = '?'; |
946 | else if (optind == argc) | 971 | } |
947 | { | 972 | else |
948 | if (opterr) | 973 | /* We already incremented `optind' once; |
949 | { | 974 | increment it again when taking next ARGV-elt as argument. */ |
950 | /* 1003.2 specifies the format of this message. */ | 975 | optarg = argv[optind++]; |
951 | fprintf (stderr, | 976 | nextchar = NULL; |
952 | _("%s: option requires an argument -- %c\n"), | ||
953 | argv[0], c); | ||
954 | } | ||
955 | optopt = c; | ||
956 | if (optstring[0] == ':') | ||
957 | c = ':'; | ||
958 | else | ||
959 | c = '?'; | ||
960 | } | ||
961 | else | ||
962 | /* We already incremented `optind' once; | ||
963 | increment it again when taking next ARGV-elt as argument. */ | ||
964 | optarg = argv[optind++]; | ||
965 | nextchar = NULL; | ||
966 | } | ||
967 | } | 977 | } |
978 | } | ||
968 | return c; | 979 | return c; |
969 | } | 980 | } |
970 | } | 981 | } |
971 | 982 | ||
972 | int | 983 | int |
973 | getopt (argc, argv, optstring) | 984 | getopt (argc, argv, optstring) |
974 | int argc; | 985 | int argc; |
975 | char *const *argv; | 986 | |
976 | const char *optstring; | 987 | char *const *argv; |
988 | const char *optstring; | ||
977 | { | 989 | { |
978 | return _getopt_internal (argc, argv, optstring, | 990 | return _getopt_internal (argc, argv, optstring, |
979 | (const struct option *) 0, (int *) 0, 0); | 991 | (const struct option *) 0, (int *) 0, 0); |
980 | } | 992 | } |
981 | 993 | ||
982 | #endif /* Not ELIDE_CODE. */ | 994 | #endif /* Not ELIDE_CODE. */ |
983 | 995 | ||
984 | #ifdef TEST | 996 | #ifdef TEST |
985 | 997 | ||
986 | /* Compile with -DTEST to make an executable for use in testing | 998 | /* Compile with -DTEST to make an executable for use in testing |
@@ -988,65 +1000,66 @@ getopt (argc, argv, optstring) | |||
988 | 1000 | ||
989 | int | 1001 | int |
990 | main (argc, argv) | 1002 | main (argc, argv) |
991 | int argc; | 1003 | int argc; |
992 | char **argv; | 1004 | |
1005 | char **argv; | ||
993 | { | 1006 | { |
994 | int c; | 1007 | int c; |
995 | int digit_optind = 0; | 1008 | int digit_optind = 0; |
996 | 1009 | ||
997 | while (1) | 1010 | while (1) |
1011 | { | ||
1012 | int this_option_optind = optind ? optind : 1; | ||
1013 | |||
1014 | c = getopt (argc, argv, "abc:d:0123456789"); | ||
1015 | if (c == -1) | ||
1016 | break; | ||
1017 | |||
1018 | switch (c) | ||
998 | { | 1019 | { |
999 | int this_option_optind = optind ? optind : 1; | 1020 | case '0': |
1000 | 1021 | case '1': | |
1001 | c = getopt (argc, argv, "abc:d:0123456789"); | 1022 | case '2': |
1002 | if (c == -1) | 1023 | case '3': |
1003 | break; | 1024 | case '4': |
1004 | 1025 | case '5': | |
1005 | switch (c) | 1026 | case '6': |
1006 | { | 1027 | case '7': |
1007 | case '0': | 1028 | case '8': |
1008 | case '1': | 1029 | case '9': |
1009 | case '2': | 1030 | if ((digit_optind != 0) && (digit_optind != this_option_optind) ) |
1010 | case '3': | 1031 | printf ("digits occur in two different argv-elements.\n"); |
1011 | case '4': | 1032 | digit_optind = this_option_optind; |
1012 | case '5': | 1033 | printf ("option %c\n", c); |
1013 | case '6': | 1034 | break; |
1014 | case '7': | 1035 | |
1015 | case '8': | 1036 | case 'a': |
1016 | case '9': | 1037 | printf ("option a\n"); |
1017 | if (digit_optind != 0 && digit_optind != this_option_optind) | 1038 | break; |
1018 | printf ("digits occur in two different argv-elements.\n"); | 1039 | |
1019 | digit_optind = this_option_optind; | 1040 | case 'b': |
1020 | printf ("option %c\n", c); | 1041 | printf ("option b\n"); |
1021 | break; | 1042 | break; |
1022 | 1043 | ||
1023 | case 'a': | 1044 | case 'c': |
1024 | printf ("option a\n"); | 1045 | printf ("option c with value `%s'\n", optarg); |
1025 | break; | 1046 | break; |
1026 | 1047 | ||
1027 | case 'b': | 1048 | case '?': |
1028 | printf ("option b\n"); | 1049 | break; |
1029 | break; | 1050 | |
1030 | 1051 | default: | |
1031 | case 'c': | 1052 | printf ("?? getopt returned character code 0%o ??\n", c); |
1032 | printf ("option c with value `%s'\n", optarg); | ||
1033 | break; | ||
1034 | |||
1035 | case '?': | ||
1036 | break; | ||
1037 | |||
1038 | default: | ||
1039 | printf ("?? getopt returned character code 0%o ??\n", c); | ||
1040 | } | ||
1041 | } | 1053 | } |
1054 | } | ||
1042 | 1055 | ||
1043 | if (optind < argc) | 1056 | if (optind < argc) |
1044 | { | 1057 | { |
1045 | printf ("non-option ARGV-elements: "); | 1058 | printf ("non-option ARGV-elements: "); |
1046 | while (optind < argc) | 1059 | while (optind < argc) |
1047 | printf ("%s ", argv[optind++]); | 1060 | printf ("%s ", argv[optind++]); |
1048 | printf ("\n"); | 1061 | printf ("\n"); |
1049 | } | 1062 | } |
1050 | 1063 | ||
1051 | exit (0); | 1064 | exit (0); |
1052 | } | 1065 | } |
diff --git a/src/main/getopt.h b/src/main/getopt.h index d50c90e..89fd8eb 100644 --- a/src/main/getopt.h +++ b/src/main/getopt.h | |||
@@ -24,7 +24,7 @@ USA. */ | |||
24 | 24 | ||
25 | #include "config.h" | 25 | #include "config.h" |
26 | 26 | ||
27 | #ifdef __cplusplus | 27 | #ifdef __cplusplus |
28 | extern "C" { | 28 | extern "C" { |
29 | #endif | 29 | #endif |
30 | 30 | ||
@@ -67,7 +67,7 @@ extern int optopt; | |||
67 | The field `has_arg' is: | 67 | The field `has_arg' is: |
68 | no_argument (or 0) if the option does not take an argument, | 68 | no_argument (or 0) if the option does not take an argument, |
69 | required_argument (or 1) if the option requires an argument, | 69 | required_argument (or 1) if the option requires an argument, |
70 | optional_argument (or 2) if the option takes an optional argument. | 70 | optional_argument (or 2) if the option takes an optional argument. |
71 | 71 | ||
72 | If the field `flag' is not NULL, it points to a variable that is set | 72 | If the field `flag' is not NULL, it points to a variable that is set |
73 | to the value given in the field `val' when the option is found, but | 73 | to the value given in the field `val' when the option is found, but |
@@ -96,9 +96,9 @@ struct option | |||
96 | 96 | ||
97 | /* Names for the values of the `has_arg' field of `struct option'. */ | 97 | /* Names for the values of the `has_arg' field of `struct option'. */ |
98 | 98 | ||
99 | #define no_argument 0 | 99 | #define no_argument 0 |
100 | #define required_argument 1 | 100 | #define required_argument 1 |
101 | #define optional_argument 2 | 101 | #define optional_argument 2 |
102 | 102 | ||
103 | #if defined (__STDC__) && __STDC__ | 103 | #if defined (__STDC__) && __STDC__ |
104 | #ifdef __GNU_LIBRARY__ | 104 | #ifdef __GNU_LIBRARY__ |
@@ -106,29 +106,36 @@ struct option | |||
106 | differences in the consts, in stdlib.h. To avoid compilation | 106 | differences in the consts, in stdlib.h. To avoid compilation |
107 | errors, only prototype getopt for the GNU C library. */ | 107 | errors, only prototype getopt for the GNU C library. */ |
108 | extern int getopt (int argc, char *const *argv, const char *shortopts); | 108 | extern int getopt (int argc, char *const *argv, const char *shortopts); |
109 | |||
109 | #else /* not __GNU_LIBRARY__ */ | 110 | #else /* not __GNU_LIBRARY__ */ |
110 | extern int getopt (); | 111 | extern int getopt (); |
112 | |||
111 | #endif /* __GNU_LIBRARY__ */ | 113 | #endif /* __GNU_LIBRARY__ */ |
112 | extern int getopt_long (int argc, char *const *argv, const char *shortopts, | 114 | extern int getopt_long (int argc, char *const *argv, const char *shortopts, |
113 | const struct option *longopts, int *longind); | 115 | const struct option *longopts, int *longind); |
116 | |||
114 | extern int getopt_long_only (int argc, char *const *argv, | 117 | extern int getopt_long_only (int argc, char *const *argv, |
115 | const char *shortopts, | 118 | const char *shortopts, |
116 | const struct option *longopts, int *longind); | 119 | const struct option *longopts, int *longind); |
117 | 120 | ||
118 | /* Internal only. Users should not call this directly. */ | 121 | /* Internal only. Users should not call this directly. */ |
119 | extern int _getopt_internal (int argc, char *const *argv, | 122 | extern int _getopt_internal (int argc, char *const *argv, |
120 | const char *shortopts, | 123 | const char *shortopts, |
121 | const struct option *longopts, int *longind, | 124 | const struct option *longopts, int *longind, |
122 | int long_only); | 125 | int long_only); |
126 | |||
123 | #else /* not __STDC__ */ | 127 | #else /* not __STDC__ */ |
124 | extern int getopt (); | 128 | extern int getopt (); |
129 | |||
125 | extern int getopt_long (); | 130 | extern int getopt_long (); |
131 | |||
126 | extern int getopt_long_only (); | 132 | extern int getopt_long_only (); |
127 | 133 | ||
128 | extern int _getopt_internal (); | 134 | extern int _getopt_internal (); |
135 | |||
129 | #endif /* __STDC__ */ | 136 | #endif /* __STDC__ */ |
130 | 137 | ||
131 | #ifdef __cplusplus | 138 | #ifdef __cplusplus |
132 | } | 139 | } |
133 | #endif | 140 | #endif |
134 | 141 | ||
diff --git a/src/main/getopt1.c b/src/main/getopt1.c index 6409986..d089fd4 100644 --- a/src/main/getopt1.c +++ b/src/main/getopt1.c | |||
@@ -21,7 +21,7 @@ USA. */ | |||
21 | #include "config.h" | 21 | #include "config.h" |
22 | #include "getopt.h" | 22 | #include "getopt.h" |
23 | 23 | ||
24 | #if !defined (__STDC__) || !__STDC__ | 24 | #if ! defined (__STDC__) || ! __STDC__ |
25 | /* This is a separate conditional since some stdc systems | 25 | /* This is a separate conditional since some stdc systems |
26 | reject `defined (const)'. */ | 26 | reject `defined (const)'. */ |
27 | #ifndef const | 27 | #ifndef const |
@@ -40,7 +40,7 @@ USA. */ | |||
40 | it is simpler to just do this in the source for each such file. */ | 40 | it is simpler to just do this in the source for each such file. */ |
41 | 41 | ||
42 | #define GETOPT_INTERFACE_VERSION 2 | 42 | #define GETOPT_INTERFACE_VERSION 2 |
43 | #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 | 43 | #if ! defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 |
44 | #include <gnu-versions.h> | 44 | #include <gnu-versions.h> |
45 | #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION | 45 | #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION |
46 | #define ELIDE_CODE | 46 | #define ELIDE_CODE |
@@ -56,17 +56,18 @@ USA. */ | |||
56 | #include <stdlib.h> | 56 | #include <stdlib.h> |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #ifndef NULL | 59 | #ifndef NULL |
60 | #define NULL 0 | 60 | #define NULL 0 |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | int | 63 | int |
64 | getopt_long (argc, argv, options, long_options, opt_index) | 64 | getopt_long (argc, argv, options, long_options, opt_index) |
65 | int argc; | 65 | int argc; |
66 | char *const *argv; | 66 | |
67 | const char *options; | 67 | char *const *argv; |
68 | const struct option *long_options; | 68 | const char *options; |
69 | int *opt_index; | 69 | const struct option *long_options; |
70 | int *opt_index; | ||
70 | { | 71 | { |
71 | return _getopt_internal (argc, argv, options, long_options, opt_index, 0); | 72 | return _getopt_internal (argc, argv, options, long_options, opt_index, 0); |
72 | } | 73 | } |
@@ -78,105 +79,107 @@ getopt_long (argc, argv, options, long_options, opt_index) | |||
78 | 79 | ||
79 | int | 80 | int |
80 | getopt_long_only (argc, argv, options, long_options, opt_index) | 81 | getopt_long_only (argc, argv, options, long_options, opt_index) |
81 | int argc; | 82 | int argc; |
82 | char *const *argv; | 83 | |
83 | const char *options; | 84 | char *const *argv; |
84 | const struct option *long_options; | 85 | const char *options; |
85 | int *opt_index; | 86 | const struct option *long_options; |
87 | int *opt_index; | ||
86 | { | 88 | { |
87 | return _getopt_internal (argc, argv, options, long_options, opt_index, 1); | 89 | return _getopt_internal (argc, argv, options, long_options, opt_index, 1); |
88 | } | 90 | } |
89 | 91 | ||
90 | 92 | ||
91 | #endif /* Not ELIDE_CODE. */ | 93 | #endif /* Not ELIDE_CODE. */ |
92 | 94 | ||
93 | #ifdef TEST | 95 | #ifdef TEST |
94 | 96 | ||
95 | #include <stdio.h> | 97 | #include <stdio.h> |
96 | 98 | ||
97 | int | 99 | int |
98 | main (argc, argv) | 100 | main (argc, argv) |
99 | int argc; | 101 | int argc; |
100 | char **argv; | 102 | |
103 | char **argv; | ||
101 | { | 104 | { |
102 | int c; | 105 | int c; |
103 | int digit_optind = 0; | 106 | int digit_optind = 0; |
104 | 107 | ||
105 | while (1) | 108 | while (1) |
109 | { | ||
110 | int this_option_optind = optind ? optind : 1; | ||
111 | int option_index = 0; | ||
112 | static struct option long_options[] = { | ||
113 | {"add", 1, 0, 0}, | ||
114 | {"append", 0, 0, 0}, | ||
115 | {"delete", 1, 0, 0}, | ||
116 | {"verbose", 0, 0, 0}, | ||
117 | {"create", 0, 0, 0}, | ||
118 | {"file", 1, 0, 0}, | ||
119 | {0, 0, 0, 0} | ||
120 | }; | ||
121 | |||
122 | c = getopt_long (argc, argv, "abc:d:0123456789", | ||
123 | long_options, &option_index); | ||
124 | if (c == -1) | ||
125 | break; | ||
126 | |||
127 | switch (c) | ||
106 | { | 128 | { |
107 | int this_option_optind = optind ? optind : 1; | 129 | case 0: |
108 | int option_index = 0; | 130 | printf ("option %s", long_options[option_index].name); |
109 | static struct option long_options[] = { | 131 | if (optarg) |
110 | {"add", 1, 0, 0}, | 132 | printf (" with arg %s", optarg); |
111 | {"append", 0, 0, 0}, | 133 | printf ("\n"); |
112 | {"delete", 1, 0, 0}, | 134 | break; |
113 | {"verbose", 0, 0, 0}, | 135 | |
114 | {"create", 0, 0, 0}, | 136 | case '0': |
115 | {"file", 1, 0, 0}, | 137 | case '1': |
116 | {0, 0, 0, 0} | 138 | case '2': |
117 | }; | 139 | case '3': |
118 | 140 | case '4': | |
119 | c = getopt_long (argc, argv, "abc:d:0123456789", | 141 | case '5': |
120 | long_options, &option_index); | 142 | case '6': |
121 | if (c == -1) | 143 | case '7': |
122 | break; | 144 | case '8': |
123 | 145 | case '9': | |
124 | switch (c) | 146 | if ((digit_optind != 0) && (digit_optind != this_option_optind) ) |
125 | { | 147 | printf ("digits occur in two different argv-elements.\n"); |
126 | case 0: | 148 | digit_optind = this_option_optind; |
127 | printf ("option %s", long_options[option_index].name); | 149 | printf ("option %c\n", c); |
128 | if (optarg) | 150 | break; |
129 | printf (" with arg %s", optarg); | 151 | |
130 | printf ("\n"); | 152 | case 'a': |
131 | break; | 153 | printf ("option a\n"); |
132 | 154 | break; | |
133 | case '0': | 155 | |
134 | case '1': | 156 | case 'b': |
135 | case '2': | 157 | printf ("option b\n"); |
136 | case '3': | 158 | break; |
137 | case '4': | 159 | |
138 | case '5': | 160 | case 'c': |
139 | case '6': | 161 | printf ("option c with value `%s'\n", optarg); |
140 | case '7': | 162 | break; |
141 | case '8': | 163 | |
142 | case '9': | 164 | case 'd': |
143 | if (digit_optind != 0 && digit_optind != this_option_optind) | 165 | printf ("option d with value `%s'\n", optarg); |
144 | printf ("digits occur in two different argv-elements.\n"); | 166 | break; |
145 | digit_optind = this_option_optind; | 167 | |
146 | printf ("option %c\n", c); | 168 | case '?': |
147 | break; | 169 | break; |
148 | 170 | ||
149 | case 'a': | 171 | default: |
150 | printf ("option a\n"); | 172 | printf ("?? getopt returned character code 0%o ??\n", c); |
151 | break; | ||
152 | |||
153 | case 'b': | ||
154 | printf ("option b\n"); | ||
155 | break; | ||
156 | |||
157 | case 'c': | ||
158 | printf ("option c with value `%s'\n", optarg); | ||
159 | break; | ||
160 | |||
161 | case 'd': | ||
162 | printf ("option d with value `%s'\n", optarg); | ||
163 | break; | ||
164 | |||
165 | case '?': | ||
166 | break; | ||
167 | |||
168 | default: | ||
169 | printf ("?? getopt returned character code 0%o ??\n", c); | ||
170 | } | ||
171 | } | 173 | } |
174 | } | ||
172 | 175 | ||
173 | if (optind < argc) | 176 | if (optind < argc) |
174 | { | 177 | { |
175 | printf ("non-option ARGV-elements: "); | 178 | printf ("non-option ARGV-elements: "); |
176 | while (optind < argc) | 179 | while (optind < argc) |
177 | printf ("%s ", argv[optind++]); | 180 | printf ("%s ", argv[optind++]); |
178 | printf ("\n"); | 181 | printf ("\n"); |
179 | } | 182 | } |
180 | 183 | ||
181 | exit (0); | 184 | exit (0); |
182 | } | 185 | } |
diff --git a/src/main/iconv.c b/src/main/iconv.c index 3f95d44..7daa017 100644 --- a/src/main/iconv.c +++ b/src/main/iconv.c | |||
@@ -33,10 +33,10 @@ | |||
33 | * @param inSize number of bytes in 'in' | 33 | * @param inSize number of bytes in 'in' |
34 | * @return NULL on error, otherwise the converted string (to be free'd by caller) | 34 | * @return NULL on error, otherwise the converted string (to be free'd by caller) |
35 | */ | 35 | */ |
36 | static char * | 36 | static char * |
37 | iconv_helper (iconv_t cd, | 37 | iconv_helper (iconv_t cd, |
38 | const char *in, | 38 | const char *in, |
39 | size_t inSize) | 39 | size_t inSize) |
40 | { | 40 | { |
41 | #if HAVE_ICONV | 41 | #if HAVE_ICONV |
42 | char *buf; | 42 | char *buf; |
@@ -57,24 +57,25 @@ iconv_helper (iconv_t cd, | |||
57 | ibuf = buf; | 57 | ibuf = buf; |
58 | memset (buf, 0, outSize); | 58 | memset (buf, 0, outSize); |
59 | if (iconv (cd, | 59 | if (iconv (cd, |
60 | (char**) &in, | 60 | (char**) &in, |
61 | &inSize, | 61 | &inSize, |
62 | &ibuf, | 62 | &ibuf, |
63 | &outLeft) == SIZE_MAX) | 63 | &outLeft) == SIZE_MAX) |
64 | { | 64 | { |
65 | /* conversion failed */ | 65 | /* conversion failed */ |
66 | free (buf); | 66 | free (buf); |
67 | return strdup (i); | 67 | return strdup (i); |
68 | } | 68 | } |
69 | return buf; | 69 | return buf; |
70 | #else | 70 | #else |
71 | /* good luck, just copying string... */ | 71 | /* good luck, just copying string... */ |
72 | char *buf; | 72 | char *buf; |
73 | 73 | ||
74 | buf = malloc (inSize + 1); | 74 | buf = malloc (inSize + 1); |
75 | memcpy (buf, in, inSize); | 75 | memcpy (buf, in, inSize); |
76 | buf[inSize] = '\0'; | 76 | buf[inSize] = '\0'; |
77 | #endif | 77 | #endif |
78 | } | 78 | } |
79 | 79 | ||
80 | |||
80 | /* end of iconv.c */ | 81 | /* end of iconv.c */ |
diff --git a/src/main/test2_extractor.c b/src/main/test2_extractor.c index 4d55dc3..a2c1d53 100644 --- a/src/main/test2_extractor.c +++ b/src/main/test2_extractor.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <unistd.h> | 36 | #include <unistd.h> |
37 | #include <stdlib.h> | 37 | #include <stdlib.h> |
38 | 38 | ||
39 | |||
40 | 39 | ||
41 | /** | 40 | /** |
42 | * Signature of the extract method that each plugin | 41 | * Signature of the extract method that each plugin |
@@ -52,77 +51,78 @@ EXTRACTOR_test2_extract_method (struct EXTRACTOR_ExtractContext *ec) | |||
52 | if ((NULL == ec->config) || (0 != strcmp (ec->config, "test2"))) | 51 | if ((NULL == ec->config) || (0 != strcmp (ec->config, "test2"))) |
53 | return; /* only run in test mode */ | 52 | return; /* only run in test mode */ |
54 | if (4 != ec->read (ec->cls, &dp, 4)) | 53 | if (4 != ec->read (ec->cls, &dp, 4)) |
55 | { | 54 | { |
56 | fprintf (stderr, "Reading at offset 0 failed\n"); | 55 | fprintf (stderr, "Reading at offset 0 failed\n"); |
57 | ABORT (); | 56 | ABORT (); |
58 | } | 57 | } |
59 | if (0 != strncmp ("test", dp, 4)) | 58 | if (0 != strncmp ("test", dp, 4)) |
60 | { | 59 | { |
61 | fprintf (stderr, "Unexpected data at offset 0\n"); | 60 | fprintf (stderr, "Unexpected data at offset 0\n"); |
62 | ABORT (); | 61 | ABORT (); |
63 | } | 62 | } |
64 | if ( (1024 * 150 != ec->get_size (ec->cls)) && | 63 | if ( (1024 * 150 != ec->get_size (ec->cls)) && |
65 | (UINT64_MAX != ec->get_size (ec->cls)) ) | 64 | (UINT64_MAX != ec->get_size (ec->cls)) ) |
66 | { | 65 | { |
67 | fprintf (stderr, "Unexpected file size returned (expected 150k)\n"); | 66 | fprintf (stderr, "Unexpected file size returned (expected 150k)\n"); |
68 | ABORT (); | 67 | ABORT (); |
69 | } | 68 | } |
70 | if (1024 * 100 + 4 != ec->seek (ec->cls, 1024 * 100 + 4, SEEK_SET)) | 69 | if (1024 * 100 + 4 != ec->seek (ec->cls, 1024 * 100 + 4, SEEK_SET)) |
71 | { | 70 | { |
72 | fprintf (stderr, "Failure to seek (SEEK_SET)\n"); | 71 | fprintf (stderr, "Failure to seek (SEEK_SET)\n"); |
73 | ABORT (); | 72 | ABORT (); |
74 | } | 73 | } |
75 | if (1 != ec->read (ec->cls, &dp, 1)) | 74 | if (1 != ec->read (ec->cls, &dp, 1)) |
76 | { | 75 | { |
77 | fprintf (stderr, "Failure to read at 100k + 4\n"); | 76 | fprintf (stderr, "Failure to read at 100k + 4\n"); |
78 | ABORT (); | 77 | ABORT (); |
79 | } | 78 | } |
80 | if ((1024 * 100 + 4) % 256 != * (unsigned char *) dp) | 79 | if ((1024 * 100 + 4) % 256 != *(unsigned char *) dp) |
81 | { | 80 | { |
82 | fprintf (stderr, "Unexpected data at offset 100k + 4\n"); | 81 | fprintf (stderr, "Unexpected data at offset 100k + 4\n"); |
83 | ABORT (); | 82 | ABORT (); |
84 | } | 83 | } |
85 | if (((1024 * 100 + 4) + 1 - (1024 * 50 + 7)) != | 84 | if (((1024 * 100 + 4) + 1 - (1024 * 50 + 7)) != |
86 | ec->seek (ec->cls, - (1024 * 50 + 7), SEEK_CUR)) | 85 | ec->seek (ec->cls, -(1024 * 50 + 7), SEEK_CUR)) |
87 | { | 86 | { |
88 | fprintf (stderr, "Failure to seek (SEEK_SET)\n"); | 87 | fprintf (stderr, "Failure to seek (SEEK_SET)\n"); |
89 | ABORT (); | 88 | ABORT (); |
90 | } | 89 | } |
91 | if (1 != ec->read (ec->cls, &dp, 1)) | 90 | if (1 != ec->read (ec->cls, &dp, 1)) |
92 | { | 91 | { |
93 | fprintf (stderr, "Failure to read at 50k - 3\n"); | 92 | fprintf (stderr, "Failure to read at 50k - 3\n"); |
94 | ABORT (); | 93 | ABORT (); |
95 | } | 94 | } |
96 | if (((1024 * 100 + 4) + 1 - (1024 * 50 + 7)) % 256 != * (unsigned char *) dp) | 95 | if (((1024 * 100 + 4) + 1 - (1024 * 50 + 7)) % 256 != *(unsigned char *) dp) |
97 | { | 96 | { |
98 | fprintf (stderr, "Unexpected data at offset 100k - 3\n"); | 97 | fprintf (stderr, "Unexpected data at offset 100k - 3\n"); |
99 | ABORT (); | 98 | ABORT (); |
100 | } | 99 | } |
101 | if (1024 * 150 != ec->seek (ec->cls, 0, SEEK_END)) | 100 | if (1024 * 150 != ec->seek (ec->cls, 0, SEEK_END)) |
102 | { | 101 | { |
103 | fprintf (stderr, "Failure to seek (SEEK_END)\n"); | 102 | fprintf (stderr, "Failure to seek (SEEK_END)\n"); |
104 | ABORT (); | 103 | ABORT (); |
105 | } | 104 | } |
106 | if (0 != ec->read (ec->cls, &dp, 1)) | 105 | if (0 != ec->read (ec->cls, &dp, 1)) |
107 | { | 106 | { |
108 | fprintf (stderr, "Failed to receive EOF at 150k\n"); | 107 | fprintf (stderr, "Failed to receive EOF at 150k\n"); |
109 | ABORT (); | 108 | ABORT (); |
110 | } | 109 | } |
111 | if (1024 * 150 - 2 != ec->seek (ec->cls, -2, SEEK_END)) | 110 | if (1024 * 150 - 2 != ec->seek (ec->cls, -2, SEEK_END)) |
112 | { | 111 | { |
113 | fprintf (stderr, "Failure to seek (SEEK_END - 2)\n"); | 112 | fprintf (stderr, "Failure to seek (SEEK_END - 2)\n"); |
114 | ABORT (); | 113 | ABORT (); |
115 | } | 114 | } |
116 | if (1 != ec->read (ec->cls, &dp, 1)) | 115 | if (1 != ec->read (ec->cls, &dp, 1)) |
117 | { | 116 | { |
118 | fprintf (stderr, "Failure to read at 150k - 3\n"); | 117 | fprintf (stderr, "Failure to read at 150k - 3\n"); |
119 | ABORT (); | 118 | ABORT (); |
120 | } | 119 | } |
121 | if ((1024 * 150 - 2) % 256 != * (unsigned char *) dp) | 120 | if ((1024 * 150 - 2) % 256 != *(unsigned char *) dp) |
122 | { | 121 | { |
123 | fprintf (stderr, "Unexpected data at offset 150k - 3\n"); | 122 | fprintf (stderr, "Unexpected data at offset 150k - 3\n"); |
124 | ABORT (); | 123 | ABORT (); |
125 | } | 124 | } |
126 | } | 125 | } |
127 | 126 | ||
127 | |||
128 | /* end of test2_extractor.c */ | 128 | /* end of test2_extractor.c */ |
diff --git a/src/main/test_bzip2.c b/src/main/test_bzip2.c index 37c9aed..598e913 100644 --- a/src/main/test_bzip2.c +++ b/src/main/test_bzip2.c | |||
@@ -46,74 +46,74 @@ static int ret = 2; | |||
46 | * @param data hello world or good bye | 46 | * @param data hello world or good bye |
47 | * @param data_len number of bytes in data | 47 | * @param data_len number of bytes in data |
48 | * @return 0 on hello world, 1 on goodbye | 48 | * @return 0 on hello world, 1 on goodbye |
49 | */ | 49 | */ |
50 | static int | 50 | static int |
51 | process_replies (void *cls, | 51 | process_replies (void *cls, |
52 | const char *plugin_name, | 52 | const char *plugin_name, |
53 | enum EXTRACTOR_MetaType type, | 53 | enum EXTRACTOR_MetaType type, |
54 | enum EXTRACTOR_MetaFormat format, | 54 | enum EXTRACTOR_MetaFormat format, |
55 | const char *data_mime_type, | 55 | const char *data_mime_type, |
56 | const char *data, | 56 | const char *data, |
57 | size_t data_len) | 57 | size_t data_len) |
58 | { | 58 | { |
59 | if (0 != strcmp (cls, | 59 | if (0 != strcmp (cls, |
60 | "main-cls")) | 60 | "main-cls")) |
61 | { | 61 | { |
62 | fprintf (stderr, "closure invalid\n"); | 62 | fprintf (stderr, "closure invalid\n"); |
63 | ret = 3; | 63 | ret = 3; |
64 | return 1; | 64 | return 1; |
65 | } | 65 | } |
66 | if (0 != strcmp (plugin_name, | 66 | if (0 != strcmp (plugin_name, |
67 | "test")) | 67 | "test")) |
68 | { | 68 | { |
69 | fprintf (stderr, "plugin name invalid\n"); | 69 | fprintf (stderr, "plugin name invalid\n"); |
70 | ret = 4; | 70 | ret = 4; |
71 | return 1; | 71 | return 1; |
72 | } | 72 | } |
73 | if (EXTRACTOR_METATYPE_COMMENT != type) | 73 | if (EXTRACTOR_METATYPE_COMMENT != type) |
74 | { | 74 | { |
75 | fprintf (stderr, "type invalid\n"); | 75 | fprintf (stderr, "type invalid\n"); |
76 | ret = 5; | 76 | ret = 5; |
77 | return 1; | 77 | return 1; |
78 | } | 78 | } |
79 | if (EXTRACTOR_METAFORMAT_UTF8 != format) | 79 | if (EXTRACTOR_METAFORMAT_UTF8 != format) |
80 | { | 80 | { |
81 | fprintf (stderr, "format invalid\n"); | 81 | fprintf (stderr, "format invalid\n"); |
82 | ret = 6; | 82 | ret = 6; |
83 | return 1; | 83 | return 1; |
84 | } | 84 | } |
85 | if ( (NULL == data_mime_type) || | 85 | if ( (NULL == data_mime_type) || |
86 | (0 != strcmp ("<no mime>", | 86 | (0 != strcmp ("<no mime>", |
87 | data_mime_type) ) ) | 87 | data_mime_type) ) ) |
88 | { | 88 | { |
89 | fprintf (stderr, "bad mime type\n"); | 89 | fprintf (stderr, "bad mime type\n"); |
90 | ret = 7; | 90 | ret = 7; |
91 | return 1; | 91 | return 1; |
92 | } | 92 | } |
93 | if ( (2 == ret) && | 93 | if ( (2 == ret) && |
94 | (data_len == strlen (HLO) + 1) && | 94 | (data_len == strlen (HLO) + 1) && |
95 | (0 == strncmp (data, | 95 | (0 == strncmp (data, |
96 | HLO, | 96 | HLO, |
97 | strlen (HLO))) ) | 97 | strlen (HLO))) ) |
98 | { | 98 | { |
99 | #if 0 | 99 | #if 0 |
100 | fprintf (stderr, "Received '%s'\n", HLO); | 100 | fprintf (stderr, "Received '%s'\n", HLO); |
101 | #endif | 101 | #endif |
102 | ret = 1; | 102 | ret = 1; |
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | if ( (1 == ret) && | 105 | if ( (1 == ret) && |
106 | (data_len == strlen (GOB) + 1) && | 106 | (data_len == strlen (GOB) + 1) && |
107 | (0 == strncmp (data, | 107 | (0 == strncmp (data, |
108 | GOB, | 108 | GOB, |
109 | strlen (GOB))) ) | 109 | strlen (GOB))) ) |
110 | { | 110 | { |
111 | #if 0 | 111 | #if 0 |
112 | fprintf (stderr, "Received '%s'\n", GOB); | 112 | fprintf (stderr, "Received '%s'\n", GOB); |
113 | #endif | 113 | #endif |
114 | ret = 0; | 114 | ret = 0; |
115 | return 1; | 115 | return 1; |
116 | } | 116 | } |
117 | fprintf (stderr, "Invalid meta data\n"); | 117 | fprintf (stderr, "Invalid meta data\n"); |
118 | ret = 8; | 118 | ret = 8; |
119 | return 1; | 119 | return 1; |
@@ -132,23 +132,25 @@ main (int argc, char *argv[]) | |||
132 | { | 132 | { |
133 | struct EXTRACTOR_PluginList *pl; | 133 | struct EXTRACTOR_PluginList *pl; |
134 | 134 | ||
135 | /* change environment to find 'extractor_test' plugin which is | 135 | /* change environment to find 'extractor_test' plugin which is |
136 | not installed but should be in the current directory (or .libs) | 136 | not installed but should be in the current directory (or .libs) |
137 | on 'make check' */ | 137 | on 'make check' */ |
138 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) | 138 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) |
139 | fprintf (stderr, | 139 | fprintf (stderr, |
140 | "Failed to update my environment, plugin loading may fail: %s\n", | 140 | "Failed to update my environment, plugin loading may fail: %s\n", |
141 | strerror (errno)); | 141 | strerror (errno)); |
142 | pl = EXTRACTOR_plugin_add_config (NULL, "test(test)", | 142 | pl = EXTRACTOR_plugin_add_config (NULL, "test(test)", |
143 | EXTRACTOR_OPTION_DEFAULT_POLICY); | 143 | EXTRACTOR_OPTION_DEFAULT_POLICY); |
144 | if (NULL == pl) | 144 | if (NULL == pl) |
145 | { | 145 | { |
146 | fprintf (stderr, "failed to load test plugin\n"); | 146 | fprintf (stderr, "failed to load test plugin\n"); |
147 | return 1; | 147 | return 1; |
148 | } | 148 | } |
149 | EXTRACTOR_extract (pl, "test_file.dat.bz2", NULL, 0, &process_replies, "main-cls"); | 149 | EXTRACTOR_extract (pl, "test_file.dat.bz2", NULL, 0, &process_replies, |
150 | "main-cls"); | ||
150 | EXTRACTOR_plugin_remove_all (pl); | 151 | EXTRACTOR_plugin_remove_all (pl); |
151 | return ret; | 152 | return ret; |
152 | } | 153 | } |
153 | 154 | ||
155 | |||
154 | /* end of test_bzip2.c */ | 156 | /* end of test_bzip2.c */ |
diff --git a/src/main/test_extractor.c b/src/main/test_extractor.c index 8c15fca..dd1376f 100644 --- a/src/main/test_extractor.c +++ b/src/main/test_extractor.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <stdlib.h> | 37 | #include <stdlib.h> |
38 | 38 | ||
39 | 39 | ||
40 | |||
41 | /** | 40 | /** |
42 | * Signature of the extract method that each plugin | 41 | * Signature of the extract method that each plugin |
43 | * must provide. | 42 | * must provide. |
@@ -52,94 +51,95 @@ EXTRACTOR_test_extract_method (struct EXTRACTOR_ExtractContext *ec) | |||
52 | if ((NULL == ec->config) || (0 != strcmp (ec->config, "test"))) | 51 | if ((NULL == ec->config) || (0 != strcmp (ec->config, "test"))) |
53 | return; /* only run in test mode */ | 52 | return; /* only run in test mode */ |
54 | if (4 != ec->read (ec->cls, &dp, 4)) | 53 | if (4 != ec->read (ec->cls, &dp, 4)) |
55 | { | 54 | { |
56 | fprintf (stderr, "Reading at offset 0 failed\n"); | 55 | fprintf (stderr, "Reading at offset 0 failed\n"); |
57 | ABORT (); | 56 | ABORT (); |
58 | } | 57 | } |
59 | if (0 != strncmp ("test", dp, 4)) | 58 | if (0 != strncmp ("test", dp, 4)) |
60 | { | 59 | { |
61 | fprintf (stderr, "Unexpected data at offset 0\n"); | 60 | fprintf (stderr, "Unexpected data at offset 0\n"); |
62 | ABORT (); | 61 | ABORT (); |
63 | } | 62 | } |
64 | if ( (1024 * 150 != ec->get_size (ec->cls)) && | 63 | if ( (1024 * 150 != ec->get_size (ec->cls)) && |
65 | (UINT64_MAX != ec->get_size (ec->cls)) ) | 64 | (UINT64_MAX != ec->get_size (ec->cls)) ) |
66 | { | 65 | { |
67 | fprintf (stderr, "Unexpected file size returned (expected 150k)\n"); | 66 | fprintf (stderr, "Unexpected file size returned (expected 150k)\n"); |
68 | ABORT (); | 67 | ABORT (); |
69 | } | 68 | } |
70 | if (1024 * 100 + 4 != ec->seek (ec->cls, 1024 * 100 + 4, SEEK_SET)) | 69 | if (1024 * 100 + 4 != ec->seek (ec->cls, 1024 * 100 + 4, SEEK_SET)) |
71 | { | 70 | { |
72 | fprintf (stderr, "Failure to seek (SEEK_SET)\n"); | 71 | fprintf (stderr, "Failure to seek (SEEK_SET)\n"); |
73 | ABORT (); | 72 | ABORT (); |
74 | } | 73 | } |
75 | if (1 != ec->read (ec->cls, &dp, 1)) | 74 | if (1 != ec->read (ec->cls, &dp, 1)) |
76 | { | 75 | { |
77 | fprintf (stderr, "Failure to read at 100k + 4\n"); | 76 | fprintf (stderr, "Failure to read at 100k + 4\n"); |
78 | ABORT (); | 77 | ABORT (); |
79 | } | 78 | } |
80 | if ((1024 * 100 + 4) % 256 != * (unsigned char *) dp) | 79 | if ((1024 * 100 + 4) % 256 != *(unsigned char *) dp) |
81 | { | 80 | { |
82 | fprintf (stderr, "Unexpected data at offset 100k + 4\n"); | 81 | fprintf (stderr, "Unexpected data at offset 100k + 4\n"); |
83 | ABORT (); | 82 | ABORT (); |
84 | } | 83 | } |
85 | if (((1024 * 100 + 4) + 1 - (1024 * 50 + 7)) != | 84 | if (((1024 * 100 + 4) + 1 - (1024 * 50 + 7)) != |
86 | ec->seek (ec->cls, - (1024 * 50 + 7), SEEK_CUR)) | 85 | ec->seek (ec->cls, -(1024 * 50 + 7), SEEK_CUR)) |
87 | { | 86 | { |
88 | fprintf (stderr, "Failure to seek (SEEK_SET)\n"); | 87 | fprintf (stderr, "Failure to seek (SEEK_SET)\n"); |
89 | ABORT (); | 88 | ABORT (); |
90 | } | 89 | } |
91 | if (1 != ec->read (ec->cls, &dp, 1)) | 90 | if (1 != ec->read (ec->cls, &dp, 1)) |
92 | { | 91 | { |
93 | fprintf (stderr, "Failure to read at 50k - 3\n"); | 92 | fprintf (stderr, "Failure to read at 50k - 3\n"); |
94 | ABORT (); | 93 | ABORT (); |
95 | } | 94 | } |
96 | if (((1024 * 100 + 4) + 1 - (1024 * 50 + 7)) % 256 != * (unsigned char *) dp) | 95 | if (((1024 * 100 + 4) + 1 - (1024 * 50 + 7)) % 256 != *(unsigned char *) dp) |
97 | { | 96 | { |
98 | fprintf (stderr, "Unexpected data at offset 100k - 3\n"); | 97 | fprintf (stderr, "Unexpected data at offset 100k - 3\n"); |
99 | ABORT (); | 98 | ABORT (); |
100 | } | 99 | } |
101 | if (1024 * 150 != ec->seek (ec->cls, 0, SEEK_END)) | 100 | if (1024 * 150 != ec->seek (ec->cls, 0, SEEK_END)) |
102 | { | 101 | { |
103 | fprintf (stderr, "Failure to seek (SEEK_END)\n"); | 102 | fprintf (stderr, "Failure to seek (SEEK_END)\n"); |
104 | ABORT (); | 103 | ABORT (); |
105 | } | 104 | } |
106 | if (0 != ec->read (ec->cls, &dp, 1)) | 105 | if (0 != ec->read (ec->cls, &dp, 1)) |
107 | { | 106 | { |
108 | fprintf (stderr, "Failed to receive EOF at 150k\n"); | 107 | fprintf (stderr, "Failed to receive EOF at 150k\n"); |
109 | ABORT (); | 108 | ABORT (); |
110 | } | 109 | } |
111 | if (1024 * 150 - 2 != ec->seek (ec->cls, -2, SEEK_END)) | 110 | if (1024 * 150 - 2 != ec->seek (ec->cls, -2, SEEK_END)) |
112 | { | 111 | { |
113 | fprintf (stderr, "Failure to seek (SEEK_END - 2)\n"); | 112 | fprintf (stderr, "Failure to seek (SEEK_END - 2)\n"); |
114 | ABORT (); | 113 | ABORT (); |
115 | } | 114 | } |
116 | if (1 != ec->read (ec->cls, &dp, 1)) | 115 | if (1 != ec->read (ec->cls, &dp, 1)) |
117 | { | 116 | { |
118 | fprintf (stderr, "Failure to read at 150k - 3\n"); | 117 | fprintf (stderr, "Failure to read at 150k - 3\n"); |
119 | ABORT (); | 118 | ABORT (); |
120 | } | 119 | } |
121 | if ((1024 * 150 - 2) % 256 != * (unsigned char *) dp) | 120 | if ((1024 * 150 - 2) % 256 != *(unsigned char *) dp) |
122 | { | 121 | { |
123 | fprintf (stderr, "Unexpected data at offset 150k - 3\n"); | 122 | fprintf (stderr, "Unexpected data at offset 150k - 3\n"); |
124 | ABORT (); | 123 | ABORT (); |
125 | } | 124 | } |
126 | if (0 != ec->proc (ec->cls, "test", EXTRACTOR_METATYPE_COMMENT, | 125 | if (0 != ec->proc (ec->cls, "test", EXTRACTOR_METATYPE_COMMENT, |
127 | EXTRACTOR_METAFORMAT_UTF8, "<no mime>", "Hello world!", | 126 | EXTRACTOR_METAFORMAT_UTF8, "<no mime>", "Hello world!", |
128 | strlen ("Hello world!") + 1)) | 127 | strlen ("Hello world!") + 1)) |
129 | { | 128 | { |
130 | fprintf (stderr, "Unexpected return value from 'proc'\n"); | 129 | fprintf (stderr, "Unexpected return value from 'proc'\n"); |
131 | ABORT (); | 130 | ABORT (); |
132 | } | 131 | } |
133 | /* The test assumes that client orders us to stop extraction | 132 | /* The test assumes that client orders us to stop extraction |
134 | * after seeing "Goodbye!". | 133 | * after seeing "Goodbye!". |
135 | */ | 134 | */ |
136 | if (1 != ec->proc (ec->cls, "test", EXTRACTOR_METATYPE_COMMENT, | 135 | if (1 != ec->proc (ec->cls, "test", EXTRACTOR_METATYPE_COMMENT, |
137 | EXTRACTOR_METAFORMAT_UTF8, "<no mime>", "Goodbye!", | 136 | EXTRACTOR_METAFORMAT_UTF8, "<no mime>", "Goodbye!", |
138 | strlen ("Goodbye!") + 1)) | 137 | strlen ("Goodbye!") + 1)) |
139 | { | 138 | { |
140 | fprintf (stderr, "Unexpected return value from 'proc'\n"); | 139 | fprintf (stderr, "Unexpected return value from 'proc'\n"); |
141 | ABORT (); | 140 | ABORT (); |
142 | } | 141 | } |
143 | } | 142 | } |
144 | 143 | ||
144 | |||
145 | /* end of test_extractor.c */ | 145 | /* end of test_extractor.c */ |
diff --git a/src/main/test_file.c b/src/main/test_file.c index 52803c9..a2d6a5e 100644 --- a/src/main/test_file.c +++ b/src/main/test_file.c | |||
@@ -46,74 +46,74 @@ static int ret = 2; | |||
46 | * @param data hello world or good bye | 46 | * @param data hello world or good bye |
47 | * @param data_len number of bytes in data | 47 | * @param data_len number of bytes in data |
48 | * @return 0 on hello world, 1 on goodbye | 48 | * @return 0 on hello world, 1 on goodbye |
49 | */ | 49 | */ |
50 | static int | 50 | static int |
51 | process_replies (void *cls, | 51 | process_replies (void *cls, |
52 | const char *plugin_name, | 52 | const char *plugin_name, |
53 | enum EXTRACTOR_MetaType type, | 53 | enum EXTRACTOR_MetaType type, |
54 | enum EXTRACTOR_MetaFormat format, | 54 | enum EXTRACTOR_MetaFormat format, |
55 | const char *data_mime_type, | 55 | const char *data_mime_type, |
56 | const char *data, | 56 | const char *data, |
57 | size_t data_len) | 57 | size_t data_len) |
58 | { | 58 | { |
59 | if (0 != strcmp (cls, | 59 | if (0 != strcmp (cls, |
60 | "main-cls")) | 60 | "main-cls")) |
61 | { | 61 | { |
62 | fprintf (stderr, "closure invalid\n"); | 62 | fprintf (stderr, "closure invalid\n"); |
63 | ret = 3; | 63 | ret = 3; |
64 | return 1; | 64 | return 1; |
65 | } | 65 | } |
66 | if (0 != strcmp (plugin_name, | 66 | if (0 != strcmp (plugin_name, |
67 | "test")) | 67 | "test")) |
68 | { | 68 | { |
69 | fprintf (stderr, "plugin name invalid\n"); | 69 | fprintf (stderr, "plugin name invalid\n"); |
70 | ret = 4; | 70 | ret = 4; |
71 | return 1; | 71 | return 1; |
72 | } | 72 | } |
73 | if (EXTRACTOR_METATYPE_COMMENT != type) | 73 | if (EXTRACTOR_METATYPE_COMMENT != type) |
74 | { | 74 | { |
75 | fprintf (stderr, "type invalid\n"); | 75 | fprintf (stderr, "type invalid\n"); |
76 | ret = 5; | 76 | ret = 5; |
77 | return 1; | 77 | return 1; |
78 | } | 78 | } |
79 | if (EXTRACTOR_METAFORMAT_UTF8 != format) | 79 | if (EXTRACTOR_METAFORMAT_UTF8 != format) |
80 | { | 80 | { |
81 | fprintf (stderr, "format invalid\n"); | 81 | fprintf (stderr, "format invalid\n"); |
82 | ret = 6; | 82 | ret = 6; |
83 | return 1; | 83 | return 1; |
84 | } | 84 | } |
85 | if ( (NULL == data_mime_type) || | 85 | if ( (NULL == data_mime_type) || |
86 | (0 != strcmp ("<no mime>", | 86 | (0 != strcmp ("<no mime>", |
87 | data_mime_type) ) ) | 87 | data_mime_type) ) ) |
88 | { | 88 | { |
89 | fprintf (stderr, "bad mime type\n"); | 89 | fprintf (stderr, "bad mime type\n"); |
90 | ret = 7; | 90 | ret = 7; |
91 | return 1; | 91 | return 1; |
92 | } | 92 | } |
93 | if ( (2 == ret) && | 93 | if ( (2 == ret) && |
94 | (data_len == strlen (HLO) + 1) && | 94 | (data_len == strlen (HLO) + 1) && |
95 | (0 == strncmp (data, | 95 | (0 == strncmp (data, |
96 | HLO, | 96 | HLO, |
97 | strlen (HLO))) ) | 97 | strlen (HLO))) ) |
98 | { | 98 | { |
99 | #if 0 | 99 | #if 0 |
100 | fprintf (stderr, "Received '%s'\n", HLO); | 100 | fprintf (stderr, "Received '%s'\n", HLO); |
101 | #endif | 101 | #endif |
102 | ret = 1; | 102 | ret = 1; |
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | if ( (1 == ret) && | 105 | if ( (1 == ret) && |
106 | (data_len == strlen (GOB) + 1) && | 106 | (data_len == strlen (GOB) + 1) && |
107 | (0 == strncmp (data, | 107 | (0 == strncmp (data, |
108 | GOB, | 108 | GOB, |
109 | strlen (GOB))) ) | 109 | strlen (GOB))) ) |
110 | { | 110 | { |
111 | #if 0 | 111 | #if 0 |
112 | fprintf (stderr, "Received '%s'\n", GOB); | 112 | fprintf (stderr, "Received '%s'\n", GOB); |
113 | #endif | 113 | #endif |
114 | ret = 0; | 114 | ret = 0; |
115 | return 1; | 115 | return 1; |
116 | } | 116 | } |
117 | fprintf (stderr, "Invalid meta data\n"); | 117 | fprintf (stderr, "Invalid meta data\n"); |
118 | ret = 8; | 118 | ret = 8; |
119 | return 1; | 119 | return 1; |
@@ -132,23 +132,25 @@ main (int argc, char *argv[]) | |||
132 | { | 132 | { |
133 | struct EXTRACTOR_PluginList *pl; | 133 | struct EXTRACTOR_PluginList *pl; |
134 | 134 | ||
135 | /* change environment to find 'extractor_test' plugin which is | 135 | /* change environment to find 'extractor_test' plugin which is |
136 | not installed but should be in the current directory (or .libs) | 136 | not installed but should be in the current directory (or .libs) |
137 | on 'make check' */ | 137 | on 'make check' */ |
138 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) | 138 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) |
139 | fprintf (stderr, | 139 | fprintf (stderr, |
140 | "Failed to update my environment, plugin loading may fail: %s\n", | 140 | "Failed to update my environment, plugin loading may fail: %s\n", |
141 | strerror (errno)); | 141 | strerror (errno)); |
142 | pl = EXTRACTOR_plugin_add_config (NULL, "test(test)", | 142 | pl = EXTRACTOR_plugin_add_config (NULL, "test(test)", |
143 | EXTRACTOR_OPTION_DEFAULT_POLICY); | 143 | EXTRACTOR_OPTION_DEFAULT_POLICY); |
144 | if (NULL == pl) | 144 | if (NULL == pl) |
145 | { | 145 | { |
146 | fprintf (stderr, "failed to load test plugin\n"); | 146 | fprintf (stderr, "failed to load test plugin\n"); |
147 | return 1; | 147 | return 1; |
148 | } | 148 | } |
149 | EXTRACTOR_extract (pl, "test_file.dat", NULL, 0, &process_replies, "main-cls"); | 149 | EXTRACTOR_extract (pl, "test_file.dat", NULL, 0, &process_replies, |
150 | "main-cls"); | ||
150 | EXTRACTOR_plugin_remove_all (pl); | 151 | EXTRACTOR_plugin_remove_all (pl); |
151 | return ret; | 152 | return ret; |
152 | } | 153 | } |
153 | 154 | ||
155 | |||
154 | /* end of test_file.c */ | 156 | /* end of test_file.c */ |
diff --git a/src/main/test_gzip.c b/src/main/test_gzip.c index 87a61cb..071c74c 100644 --- a/src/main/test_gzip.c +++ b/src/main/test_gzip.c | |||
@@ -46,78 +46,78 @@ static int ret = 2; | |||
46 | * @param data hello world or good bye | 46 | * @param data hello world or good bye |
47 | * @param data_len number of bytes in data | 47 | * @param data_len number of bytes in data |
48 | * @return 0 on hello world, 1 on goodbye | 48 | * @return 0 on hello world, 1 on goodbye |
49 | */ | 49 | */ |
50 | static int | 50 | static int |
51 | process_replies (void *cls, | 51 | process_replies (void *cls, |
52 | const char *plugin_name, | 52 | const char *plugin_name, |
53 | enum EXTRACTOR_MetaType type, | 53 | enum EXTRACTOR_MetaType type, |
54 | enum EXTRACTOR_MetaFormat format, | 54 | enum EXTRACTOR_MetaFormat format, |
55 | const char *data_mime_type, | 55 | const char *data_mime_type, |
56 | const char *data, | 56 | const char *data, |
57 | size_t data_len) | 57 | size_t data_len) |
58 | { | 58 | { |
59 | if (0 != strcmp (cls, | 59 | if (0 != strcmp (cls, |
60 | "main-cls")) | 60 | "main-cls")) |
61 | { | 61 | { |
62 | fprintf (stderr, "closure invalid\n"); | 62 | fprintf (stderr, "closure invalid\n"); |
63 | ret = 3; | 63 | ret = 3; |
64 | return 1; | 64 | return 1; |
65 | } | 65 | } |
66 | if (0 == strcmp (plugin_name, | 66 | if (0 == strcmp (plugin_name, |
67 | "<zlib>")) | 67 | "<zlib>")) |
68 | return 0; /* skip this one */ | 68 | return 0; /* skip this one */ |
69 | if (0 != strcmp (plugin_name, | 69 | if (0 != strcmp (plugin_name, |
70 | "test")) | 70 | "test")) |
71 | { | 71 | { |
72 | fprintf (stderr, "plugin name invalid: `%s'\n", | 72 | fprintf (stderr, "plugin name invalid: `%s'\n", |
73 | plugin_name); | 73 | plugin_name); |
74 | ret = 4; | 74 | ret = 4; |
75 | return 1; | 75 | return 1; |
76 | } | 76 | } |
77 | if (EXTRACTOR_METATYPE_COMMENT != type) | 77 | if (EXTRACTOR_METATYPE_COMMENT != type) |
78 | { | 78 | { |
79 | fprintf (stderr, "type invalid\n"); | 79 | fprintf (stderr, "type invalid\n"); |
80 | ret = 5; | 80 | ret = 5; |
81 | return 1; | 81 | return 1; |
82 | } | 82 | } |
83 | if (EXTRACTOR_METAFORMAT_UTF8 != format) | 83 | if (EXTRACTOR_METAFORMAT_UTF8 != format) |
84 | { | 84 | { |
85 | fprintf (stderr, "format invalid\n"); | 85 | fprintf (stderr, "format invalid\n"); |
86 | ret = 6; | 86 | ret = 6; |
87 | return 1; | 87 | return 1; |
88 | } | 88 | } |
89 | if ( (NULL == data_mime_type) || | 89 | if ( (NULL == data_mime_type) || |
90 | (0 != strcmp ("<no mime>", | 90 | (0 != strcmp ("<no mime>", |
91 | data_mime_type) ) ) | 91 | data_mime_type) ) ) |
92 | { | 92 | { |
93 | fprintf (stderr, "bad mime type\n"); | 93 | fprintf (stderr, "bad mime type\n"); |
94 | ret = 7; | 94 | ret = 7; |
95 | return 1; | 95 | return 1; |
96 | } | 96 | } |
97 | if ( (2 == ret) && | 97 | if ( (2 == ret) && |
98 | (data_len == strlen (HLO) + 1) && | 98 | (data_len == strlen (HLO) + 1) && |
99 | (0 == strncmp (data, | 99 | (0 == strncmp (data, |
100 | HLO, | 100 | HLO, |
101 | strlen (HLO))) ) | 101 | strlen (HLO))) ) |
102 | { | 102 | { |
103 | #if 0 | 103 | #if 0 |
104 | fprintf (stderr, "Received '%s'\n", HLO); | 104 | fprintf (stderr, "Received '%s'\n", HLO); |
105 | #endif | 105 | #endif |
106 | ret = 1; | 106 | ret = 1; |
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | if ( (1 == ret) && | 109 | if ( (1 == ret) && |
110 | (data_len == strlen (GOB) + 1) && | 110 | (data_len == strlen (GOB) + 1) && |
111 | (0 == strncmp (data, | 111 | (0 == strncmp (data, |
112 | GOB, | 112 | GOB, |
113 | strlen (GOB))) ) | 113 | strlen (GOB))) ) |
114 | { | 114 | { |
115 | #if 0 | 115 | #if 0 |
116 | fprintf (stderr, "Received '%s'\n", GOB); | 116 | fprintf (stderr, "Received '%s'\n", GOB); |
117 | #endif | 117 | #endif |
118 | ret = 0; | 118 | ret = 0; |
119 | return 1; | 119 | return 1; |
120 | } | 120 | } |
121 | fprintf (stderr, "Invalid meta data\n"); | 121 | fprintf (stderr, "Invalid meta data\n"); |
122 | ret = 8; | 122 | ret = 8; |
123 | return 1; | 123 | return 1; |
@@ -136,23 +136,25 @@ main (int argc, char *argv[]) | |||
136 | { | 136 | { |
137 | struct EXTRACTOR_PluginList *pl; | 137 | struct EXTRACTOR_PluginList *pl; |
138 | 138 | ||
139 | /* change environment to find 'extractor_test' plugin which is | 139 | /* change environment to find 'extractor_test' plugin which is |
140 | not installed but should be in the current directory (or .libs) | 140 | not installed but should be in the current directory (or .libs) |
141 | on 'make check' */ | 141 | on 'make check' */ |
142 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) | 142 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) |
143 | fprintf (stderr, | 143 | fprintf (stderr, |
144 | "Failed to update my environment, plugin loading may fail: %s\n", | 144 | "Failed to update my environment, plugin loading may fail: %s\n", |
145 | strerror (errno)); | 145 | strerror (errno)); |
146 | pl = EXTRACTOR_plugin_add_config (NULL, "test(test)", | 146 | pl = EXTRACTOR_plugin_add_config (NULL, "test(test)", |
147 | EXTRACTOR_OPTION_DEFAULT_POLICY); | 147 | EXTRACTOR_OPTION_DEFAULT_POLICY); |
148 | if (NULL == pl) | 148 | if (NULL == pl) |
149 | { | 149 | { |
150 | fprintf (stderr, "failed to load test plugin\n"); | 150 | fprintf (stderr, "failed to load test plugin\n"); |
151 | return 1; | 151 | return 1; |
152 | } | 152 | } |
153 | EXTRACTOR_extract (pl, "test_file.dat.gz", NULL, 0, &process_replies, "main-cls"); | 153 | EXTRACTOR_extract (pl, "test_file.dat.gz", NULL, 0, &process_replies, |
154 | "main-cls"); | ||
154 | EXTRACTOR_plugin_remove_all (pl); | 155 | EXTRACTOR_plugin_remove_all (pl); |
155 | return ret; | 156 | return ret; |
156 | } | 157 | } |
157 | 158 | ||
159 | |||
158 | /* end of test_gzip.c */ | 160 | /* end of test_gzip.c */ |
diff --git a/src/main/test_ipc.c b/src/main/test_ipc.c index 5e118fd..4da3ef5 100644 --- a/src/main/test_ipc.c +++ b/src/main/test_ipc.c | |||
@@ -46,77 +46,77 @@ static int ret = 2; | |||
46 | * @param data hello world or good bye | 46 | * @param data hello world or good bye |
47 | * @param data_len number of bytes in data | 47 | * @param data_len number of bytes in data |
48 | * @return 0 on hello world, 1 on goodbye | 48 | * @return 0 on hello world, 1 on goodbye |
49 | */ | 49 | */ |
50 | static int | 50 | static int |
51 | process_replies (void *cls, | 51 | process_replies (void *cls, |
52 | const char *plugin_name, | 52 | const char *plugin_name, |
53 | enum EXTRACTOR_MetaType type, | 53 | enum EXTRACTOR_MetaType type, |
54 | enum EXTRACTOR_MetaFormat format, | 54 | enum EXTRACTOR_MetaFormat format, |
55 | const char *data_mime_type, | 55 | const char *data_mime_type, |
56 | const char *data, | 56 | const char *data, |
57 | size_t data_len) | 57 | size_t data_len) |
58 | { | 58 | { |
59 | if (0 != strcmp (cls, | 59 | if (0 != strcmp (cls, |
60 | "main-cls")) | 60 | "main-cls")) |
61 | { | 61 | { |
62 | fprintf (stderr, "closure invalid\n"); | 62 | fprintf (stderr, "closure invalid\n"); |
63 | ret = 3; | 63 | ret = 3; |
64 | return 1; | 64 | return 1; |
65 | } | 65 | } |
66 | if (0 == strcmp (plugin_name, | 66 | if (0 == strcmp (plugin_name, |
67 | "test2")) | 67 | "test2")) |
68 | return 0; /* ignore 'test2' plugins */ | 68 | return 0; /* ignore 'test2' plugins */ |
69 | if (0 != strcmp (plugin_name, | 69 | if (0 != strcmp (plugin_name, |
70 | "test")) | 70 | "test")) |
71 | { | 71 | { |
72 | fprintf (stderr, "plugin name invalid\n"); | 72 | fprintf (stderr, "plugin name invalid\n"); |
73 | ret = 4; | 73 | ret = 4; |
74 | return 1; | 74 | return 1; |
75 | } | 75 | } |
76 | if (EXTRACTOR_METATYPE_COMMENT != type) | 76 | if (EXTRACTOR_METATYPE_COMMENT != type) |
77 | { | 77 | { |
78 | fprintf (stderr, "type invalid\n"); | 78 | fprintf (stderr, "type invalid\n"); |
79 | ret = 5; | 79 | ret = 5; |
80 | return 1; | 80 | return 1; |
81 | } | 81 | } |
82 | if (EXTRACTOR_METAFORMAT_UTF8 != format) | 82 | if (EXTRACTOR_METAFORMAT_UTF8 != format) |
83 | { | 83 | { |
84 | fprintf (stderr, "format invalid\n"); | 84 | fprintf (stderr, "format invalid\n"); |
85 | ret = 6; | 85 | ret = 6; |
86 | return 1; | 86 | return 1; |
87 | } | 87 | } |
88 | if ( (NULL == data_mime_type) || | 88 | if ( (NULL == data_mime_type) || |
89 | (0 != strcmp ("<no mime>", | 89 | (0 != strcmp ("<no mime>", |
90 | data_mime_type) ) ) | 90 | data_mime_type) ) ) |
91 | { | 91 | { |
92 | fprintf (stderr, "bad mime type\n"); | 92 | fprintf (stderr, "bad mime type\n"); |
93 | ret = 7; | 93 | ret = 7; |
94 | return 1; | 94 | return 1; |
95 | } | 95 | } |
96 | if ( (2 == ret) && | 96 | if ( (2 == ret) && |
97 | (data_len == strlen (HLO) + 1) && | 97 | (data_len == strlen (HLO) + 1) && |
98 | (0 == strncmp (data, | 98 | (0 == strncmp (data, |
99 | HLO, | 99 | HLO, |
100 | strlen (HLO))) ) | 100 | strlen (HLO))) ) |
101 | { | 101 | { |
102 | #if 0 | 102 | #if 0 |
103 | fprintf (stderr, "Received '%s'\n", HLO); | 103 | fprintf (stderr, "Received '%s'\n", HLO); |
104 | #endif | 104 | #endif |
105 | ret = 1; | 105 | ret = 1; |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | if ( (1 == ret) && | 108 | if ( (1 == ret) && |
109 | (data_len == strlen (GOB) + 1) && | 109 | (data_len == strlen (GOB) + 1) && |
110 | (0 == strncmp (data, | 110 | (0 == strncmp (data, |
111 | GOB, | 111 | GOB, |
112 | strlen (GOB))) ) | 112 | strlen (GOB))) ) |
113 | { | 113 | { |
114 | #if 0 | 114 | #if 0 |
115 | fprintf (stderr, "Received '%s'\n", GOB); | 115 | fprintf (stderr, "Received '%s'\n", GOB); |
116 | #endif | 116 | #endif |
117 | ret = 0; | 117 | ret = 0; |
118 | return 1; | 118 | return 1; |
119 | } | 119 | } |
120 | fprintf (stderr, "Invalid meta data\n"); | 120 | fprintf (stderr, "Invalid meta data\n"); |
121 | ret = 8; | 121 | ret = 8; |
122 | return 1; | 122 | return 1; |
@@ -138,35 +138,37 @@ main (int argc, char *argv[]) | |||
138 | size_t i; | 138 | size_t i; |
139 | 139 | ||
140 | /* initialize test buffer as expected by test plugin */ | 140 | /* initialize test buffer as expected by test plugin */ |
141 | for (i=0;i<sizeof(buf);i++) | 141 | for (i = 0; i<sizeof(buf); i++) |
142 | buf[i] = (unsigned char) (i % 256); | 142 | buf[i] = (unsigned char) (i % 256); |
143 | memcpy (buf, "test", 4); | 143 | memcpy (buf, "test", 4); |
144 | 144 | ||
145 | /* change environment to find 'extractor_test' plugin which is | 145 | /* change environment to find 'extractor_test' plugin which is |
146 | not installed but should be in the current directory (or .libs) | 146 | not installed but should be in the current directory (or .libs) |
147 | on 'make check' */ | 147 | on 'make check' */ |
148 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) | 148 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) |
149 | fprintf (stderr, | 149 | fprintf (stderr, |
150 | "Failed to update my environment, plugin loading may fail: %s\n", | 150 | "Failed to update my environment, plugin loading may fail: %s\n", |
151 | strerror (errno)); | 151 | strerror (errno)); |
152 | pl = EXTRACTOR_plugin_add_config (NULL, "test(test)", | 152 | pl = EXTRACTOR_plugin_add_config (NULL, "test(test)", |
153 | EXTRACTOR_OPTION_DEFAULT_POLICY); | 153 | EXTRACTOR_OPTION_DEFAULT_POLICY); |
154 | pl = EXTRACTOR_plugin_add_config (pl, "test2(test2)", | 154 | pl = EXTRACTOR_plugin_add_config (pl, "test2(test2)", |
155 | EXTRACTOR_OPTION_DEFAULT_POLICY); | 155 | EXTRACTOR_OPTION_DEFAULT_POLICY); |
156 | if (NULL == pl) | 156 | if (NULL == pl) |
157 | { | 157 | { |
158 | fprintf (stderr, "failed to load test plugin\n"); | 158 | fprintf (stderr, "failed to load test plugin\n"); |
159 | return 1; | 159 | return 1; |
160 | } | 160 | } |
161 | EXTRACTOR_extract (pl, NULL, buf, sizeof (buf), &process_replies, "main-cls"); | 161 | EXTRACTOR_extract (pl, NULL, buf, sizeof (buf), &process_replies, "main-cls"); |
162 | if (0 == ret) | 162 | if (0 == ret) |
163 | { | 163 | { |
164 | /* do it again... */ | 164 | /* do it again... */ |
165 | ret = 2; | 165 | ret = 2; |
166 | EXTRACTOR_extract (pl, NULL, buf, sizeof (buf), &process_replies, "main-cls"); | 166 | EXTRACTOR_extract (pl, NULL, buf, sizeof (buf), &process_replies, |
167 | } | 167 | "main-cls"); |
168 | } | ||
168 | EXTRACTOR_plugin_remove_all (pl); | 169 | EXTRACTOR_plugin_remove_all (pl); |
169 | return ret; | 170 | return ret; |
170 | } | 171 | } |
171 | 172 | ||
173 | |||
172 | /* end of test_ipc.c */ | 174 | /* end of test_ipc.c */ |
diff --git a/src/main/test_plugin_load_multi.c b/src/main/test_plugin_load_multi.c index b7958f2..6b30390 100644 --- a/src/main/test_plugin_load_multi.c +++ b/src/main/test_plugin_load_multi.c | |||
@@ -37,15 +37,15 @@ testLoadPlugins () | |||
37 | el1 = EXTRACTOR_plugin_add_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY); | 37 | el1 = EXTRACTOR_plugin_add_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY); |
38 | el2 = EXTRACTOR_plugin_add_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY); | 38 | el2 = EXTRACTOR_plugin_add_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY); |
39 | if ((NULL == el1) || (NULL == el2)) | 39 | if ((NULL == el1) || (NULL == el2)) |
40 | { | 40 | { |
41 | fprintf (stderr, | 41 | fprintf (stderr, |
42 | "Failed to load default plugins!\n"); | 42 | "Failed to load default plugins!\n"); |
43 | if (NULL != el1) | 43 | if (NULL != el1) |
44 | EXTRACTOR_plugin_remove_all (el1); | 44 | EXTRACTOR_plugin_remove_all (el1); |
45 | if (NULL != el2) | 45 | if (NULL != el2) |
46 | EXTRACTOR_plugin_remove_all (el2); | 46 | EXTRACTOR_plugin_remove_all (el2); |
47 | return 1; | 47 | return 1; |
48 | } | 48 | } |
49 | EXTRACTOR_plugin_remove_all (el1); | 49 | EXTRACTOR_plugin_remove_all (el1); |
50 | EXTRACTOR_plugin_remove_all (el2); | 50 | EXTRACTOR_plugin_remove_all (el2); |
51 | return 0; | 51 | return 0; |
@@ -57,16 +57,17 @@ main (int argc, char *argv[]) | |||
57 | { | 57 | { |
58 | int ret = 0; | 58 | int ret = 0; |
59 | 59 | ||
60 | /* change environment to find 'extractor_test' plugin which is | 60 | /* change environment to find 'extractor_test' plugin which is |
61 | not installed but should be in the current directory (or .libs) | 61 | not installed but should be in the current directory (or .libs) |
62 | on 'make check' */ | 62 | on 'make check' */ |
63 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) | 63 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) |
64 | fprintf (stderr, | 64 | fprintf (stderr, |
65 | "Failed to update my environment, plugin loading may fail: %s\n", | 65 | "Failed to update my environment, plugin loading may fail: %s\n", |
66 | strerror (errno)); | 66 | strerror (errno)); |
67 | ret += testLoadPlugins (); | 67 | ret += testLoadPlugins (); |
68 | ret += testLoadPlugins (); | 68 | ret += testLoadPlugins (); |
69 | return ret; | 69 | return ret; |
70 | } | 70 | } |
71 | 71 | ||
72 | |||
72 | /* end of test_plugin_load_multi.c */ | 73 | /* end of test_plugin_load_multi.c */ |
diff --git a/src/main/test_plugin_loading.c b/src/main/test_plugin_loading.c index ddcfb92..537b703 100644 --- a/src/main/test_plugin_loading.c +++ b/src/main/test_plugin_loading.c | |||
@@ -30,29 +30,32 @@ main (int argc, char *argv[]) | |||
30 | { | 30 | { |
31 | struct EXTRACTOR_PluginList *arg; | 31 | struct EXTRACTOR_PluginList *arg; |
32 | 32 | ||
33 | /* change environment to find 'extractor_test' plugin which is | 33 | /* change environment to find 'extractor_test' plugin which is |
34 | not installed but should be in the current directory (or .libs) | 34 | not installed but should be in the current directory (or .libs) |
35 | on 'make check' */ | 35 | on 'make check' */ |
36 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) | 36 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) |
37 | fprintf (stderr, | 37 | fprintf (stderr, |
38 | "Failed to update my environment, plugin loading may fail: %s\n", | 38 | "Failed to update my environment, plugin loading may fail: %s\n", |
39 | strerror (errno)); | 39 | strerror (errno)); |
40 | 40 | ||
41 | /* do some load/unload tests */ | 41 | /* do some load/unload tests */ |
42 | arg = EXTRACTOR_plugin_add (NULL, "test", NULL, EXTRACTOR_OPTION_DEFAULT_POLICY); | 42 | arg = EXTRACTOR_plugin_add (NULL, "test", NULL, |
43 | if (arg != EXTRACTOR_plugin_add (arg, "test", NULL, EXTRACTOR_OPTION_DEFAULT_POLICY)) | 43 | EXTRACTOR_OPTION_DEFAULT_POLICY); |
44 | { | 44 | if (arg != EXTRACTOR_plugin_add (arg, "test", NULL, |
45 | fprintf (stderr, | 45 | EXTRACTOR_OPTION_DEFAULT_POLICY)) |
46 | "Could load plugin twice, that should not be allowed\n"); | 46 | { |
47 | } | 47 | fprintf (stderr, |
48 | "Could load plugin twice, that should not be allowed\n"); | ||
49 | } | ||
48 | arg = EXTRACTOR_plugin_remove (arg, "test"); | 50 | arg = EXTRACTOR_plugin_remove (arg, "test"); |
49 | if (NULL != arg) | 51 | if (NULL != arg) |
50 | { | 52 | { |
51 | fprintf (stderr, | 53 | fprintf (stderr, |
52 | "add-remove test failed!\n"); | 54 | "add-remove test failed!\n"); |
53 | return -1; | 55 | return -1; |
54 | } | 56 | } |
55 | return 0; | 57 | return 0; |
56 | } | 58 | } |
57 | 59 | ||
60 | |||
58 | /* end of test_plugin_loading.c */ | 61 | /* end of test_plugin_loading.c */ |
diff --git a/src/main/test_trivial.c b/src/main/test_trivial.c index fac9a91..b0860b4 100644 --- a/src/main/test_trivial.c +++ b/src/main/test_trivial.c | |||
@@ -30,34 +30,36 @@ static int | |||
30 | testLoadPlugins (enum EXTRACTOR_Options policy) | 30 | testLoadPlugins (enum EXTRACTOR_Options policy) |
31 | { | 31 | { |
32 | struct EXTRACTOR_PluginList *pl; | 32 | struct EXTRACTOR_PluginList *pl; |
33 | 33 | ||
34 | if (NULL == (pl = EXTRACTOR_plugin_add_defaults (policy))) | 34 | if (NULL == (pl = EXTRACTOR_plugin_add_defaults (policy))) |
35 | { | 35 | { |
36 | fprintf (stderr, | 36 | fprintf (stderr, |
37 | "Failed to load default plugins!\n"); | 37 | "Failed to load default plugins!\n"); |
38 | return 1; | 38 | return 1; |
39 | } | 39 | } |
40 | EXTRACTOR_plugin_remove_all (pl); | 40 | EXTRACTOR_plugin_remove_all (pl); |
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | |||
44 | int | 45 | int |
45 | main (int argc, char *argv[]) | 46 | main (int argc, char *argv[]) |
46 | { | 47 | { |
47 | int ret = 0; | 48 | int ret = 0; |
48 | 49 | ||
49 | 50 | ||
50 | /* change environment to find 'extractor_test' plugin which is | 51 | /* change environment to find 'extractor_test' plugin which is |
51 | not installed but should be in the current directory (or .libs) | 52 | not installed but should be in the current directory (or .libs) |
52 | on 'make check' */ | 53 | on 'make check' */ |
53 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) | 54 | if (0 != putenv ("LIBEXTRACTOR_PREFIX=." PATH_SEPARATOR_STR ".libs/")) |
54 | fprintf (stderr, | 55 | fprintf (stderr, |
55 | "Failed to update my environment, plugin loading may fail: %s\n", | 56 | "Failed to update my environment, plugin loading may fail: %s\n", |
56 | strerror (errno)); | 57 | strerror (errno)); |
57 | ret += testLoadPlugins (EXTRACTOR_OPTION_DEFAULT_POLICY); | 58 | ret += testLoadPlugins (EXTRACTOR_OPTION_DEFAULT_POLICY); |
58 | ret += testLoadPlugins (EXTRACTOR_OPTION_DEFAULT_POLICY); | 59 | ret += testLoadPlugins (EXTRACTOR_OPTION_DEFAULT_POLICY); |
59 | ret += testLoadPlugins (EXTRACTOR_OPTION_DEFAULT_POLICY); | 60 | ret += testLoadPlugins (EXTRACTOR_OPTION_DEFAULT_POLICY); |
60 | return ret; | 61 | return ret; |
61 | } | 62 | } |
62 | 63 | ||
64 | |||
63 | /* end of test_trivial.c */ | 65 | /* end of test_trivial.c */ |