diff options
Diffstat (limited to 'src/main/extractor.c')
-rw-r--r-- | src/main/extractor.c | 361 |
1 files changed, 268 insertions, 93 deletions
diff --git a/src/main/extractor.c b/src/main/extractor.c index b29676b..09d402b 100644 --- a/src/main/extractor.c +++ b/src/main/extractor.c | |||
@@ -630,6 +630,7 @@ EXTRACTOR_plugin_add_defaults(enum EXTRACTOR_Options flags) | |||
630 | */ | 630 | */ |
631 | static void * | 631 | static void * |
632 | get_symbol_with_prefix(void *lib_handle, | 632 | get_symbol_with_prefix(void *lib_handle, |
633 | const char *template, | ||
633 | const char *prefix, | 634 | const char *prefix, |
634 | const char **options) | 635 | const char **options) |
635 | { | 636 | { |
@@ -649,9 +650,9 @@ get_symbol_with_prefix(void *lib_handle, | |||
649 | dot = strstr (sym, "."); | 650 | dot = strstr (sym, "."); |
650 | if (dot != NULL) | 651 | if (dot != NULL) |
651 | *dot = '\0'; | 652 | *dot = '\0'; |
652 | name = malloc(strlen(sym) + 32); | 653 | name = malloc(strlen(sym) + strlen(template) + 1); |
653 | sprintf(name, | 654 | sprintf(name, |
654 | "_EXTRACTOR_%s_extract", | 655 | template, |
655 | sym); | 656 | sym); |
656 | /* try without '_' first */ | 657 | /* try without '_' first */ |
657 | symbol = lt_dlsym(lib_handle, name + 1); | 658 | symbol = lt_dlsym(lib_handle, name + 1); |
@@ -678,7 +679,8 @@ get_symbol_with_prefix(void *lib_handle, | |||
678 | #endif | 679 | #endif |
679 | } | 680 | } |
680 | 681 | ||
681 | if (symbol != NULL) | 682 | if ( (symbol != NULL) && |
683 | (NULL != options) ) | ||
682 | { | 684 | { |
683 | /* get special options */ | 685 | /* get special options */ |
684 | sprintf(name, | 686 | sprintf(name, |
@@ -741,6 +743,7 @@ plugin_load (struct EXTRACTOR_PluginList *plugin) | |||
741 | return -1; | 743 | return -1; |
742 | } | 744 | } |
743 | plugin->extractMethod = get_symbol_with_prefix (plugin->libraryHandle, | 745 | plugin->extractMethod = get_symbol_with_prefix (plugin->libraryHandle, |
746 | "_EXTRACTOR_%s_extract", | ||
744 | plugin->libname, | 747 | plugin->libname, |
745 | &plugin->specials); | 748 | &plugin->specials); |
746 | if (plugin->extractMethod == NULL) | 749 | if (plugin->extractMethod == NULL) |
@@ -1094,10 +1097,9 @@ transmit_reply (void *cls, | |||
1094 | 1097 | ||
1095 | 1098 | ||
1096 | /** | 1099 | /** |
1097 | * 'main' function of the child process. | 1100 | * 'main' function of the child process. Reads shm-filenames from |
1098 | * Reads shm-filenames from 'in' (line-by-line) and | 1101 | * 'in' (line-by-line) and writes meta data blocks to 'out'. The meta |
1099 | * writes meta data blocks to 'out'. The meta data | 1102 | * data stream is terminated by an empty entry. |
1100 | * stream is terminated by an empty entry. | ||
1101 | * | 1103 | * |
1102 | * @param plugin extractor plugin to use | 1104 | * @param plugin extractor plugin to use |
1103 | * @param in stream to read from | 1105 | * @param in stream to read from |
@@ -1108,12 +1110,15 @@ process_requests (struct EXTRACTOR_PluginList *plugin, | |||
1108 | int in, | 1110 | int in, |
1109 | int out) | 1111 | int out) |
1110 | { | 1112 | { |
1111 | char fn[256]; | 1113 | char hfn[256]; |
1114 | char tfn[256]; | ||
1115 | char *fn; | ||
1112 | FILE *fin; | 1116 | FILE *fin; |
1113 | void *ptr; | 1117 | void *ptr; |
1114 | int shmid; | 1118 | int shmid; |
1115 | struct IpcHeader hdr; | 1119 | struct IpcHeader hdr; |
1116 | size_t size; | 1120 | size_t size; |
1121 | int want_tail; | ||
1117 | #ifdef WINDOWS | 1122 | #ifdef WINDOWS |
1118 | HANDLE map; | 1123 | HANDLE map; |
1119 | #endif | 1124 | #endif |
@@ -1129,6 +1134,13 @@ process_requests (struct EXTRACTOR_PluginList *plugin, | |||
1129 | #endif | 1134 | #endif |
1130 | return; | 1135 | return; |
1131 | } | 1136 | } |
1137 | want_tail = 0; | ||
1138 | if ( (plugin->specials != NULL) && | ||
1139 | (NULL != strstr (plugin->specials, | ||
1140 | "want-tail")) ) | ||
1141 | { | ||
1142 | want_tail = 1; | ||
1143 | } | ||
1132 | if ( (plugin->specials != NULL) && | 1144 | if ( (plugin->specials != NULL) && |
1133 | (NULL != strstr (plugin->specials, | 1145 | (NULL != strstr (plugin->specials, |
1134 | "close-stderr")) ) | 1146 | "close-stderr")) ) |
@@ -1144,12 +1156,27 @@ process_requests (struct EXTRACTOR_PluginList *plugin, | |||
1144 | 1156 | ||
1145 | memset (&hdr, 0, sizeof (hdr)); | 1157 | memset (&hdr, 0, sizeof (hdr)); |
1146 | fin = fdopen (in, "r"); | 1158 | fin = fdopen (in, "r"); |
1147 | while (NULL != fgets (fn, sizeof(fn), fin)) | 1159 | while (NULL != fgets (hfn, sizeof(hfn), fin)) |
1148 | { | 1160 | { |
1149 | if (strlen (fn) == 0) | 1161 | if (strlen (hfn) <= 1) |
1150 | break; | 1162 | break; |
1151 | ptr = NULL; | 1163 | ptr = NULL; |
1152 | fn[strlen(fn)-1] = '\0'; /* kill newline */ | 1164 | hfn[strlen(hfn)-1] = '\0'; /* kill newline */ |
1165 | if (NULL == fgets (tfn, sizeof(tfn), fin)) | ||
1166 | break; | ||
1167 | if ('!' != tfn[0]) | ||
1168 | break; | ||
1169 | tfn[strlen(tfn)-1] = '\0'; /* kill newline */ | ||
1170 | if ( (want_tail) && | ||
1171 | (strlen (tfn) > 1) ) | ||
1172 | { | ||
1173 | fn = &tfn[1]; | ||
1174 | } | ||
1175 | else | ||
1176 | { | ||
1177 | fn = hfn; | ||
1178 | } | ||
1179 | |||
1153 | #ifndef WINDOWS | 1180 | #ifndef WINDOWS |
1154 | if ( (-1 != (shmid = shm_open (fn, O_RDONLY, 0))) && | 1181 | if ( (-1 != (shmid = shm_open (fn, O_RDONLY, 0))) && |
1155 | (((off_t)-1) != (size = lseek (shmid, 0, SEEK_END))) && | 1182 | (((off_t)-1) != (size = lseek (shmid, 0, SEEK_END))) && |
@@ -1161,12 +1188,13 @@ process_requests (struct EXTRACTOR_PluginList *plugin, | |||
1161 | if (ptr != NULL) | 1188 | if (ptr != NULL) |
1162 | #endif | 1189 | #endif |
1163 | { | 1190 | { |
1164 | if (0 != plugin->extractMethod (ptr, | 1191 | if ( (plugin->extractMethod != NULL) && |
1165 | size, | 1192 | (0 != plugin->extractMethod (ptr, |
1166 | &transmit_reply, | 1193 | size, |
1167 | &out, | 1194 | &transmit_reply, |
1168 | plugin->plugin_options)) | 1195 | &out, |
1169 | break; | 1196 | plugin->plugin_options)) ) |
1197 | break; | ||
1170 | if (0 != write_all (out, &hdr, sizeof(hdr))) | 1198 | if (0 != write_all (out, &hdr, sizeof(hdr))) |
1171 | break; | 1199 | break; |
1172 | } | 1200 | } |
@@ -1195,8 +1223,10 @@ process_requests (struct EXTRACTOR_PluginList *plugin, | |||
1195 | close (out); | 1223 | close (out); |
1196 | } | 1224 | } |
1197 | 1225 | ||
1226 | |||
1198 | #ifdef WINDOWS | 1227 | #ifdef WINDOWS |
1199 | static void write_plugin_data (HANDLE h, const struct EXTRACTOR_PluginList *plugin) | 1228 | static void |
1229 | write_plugin_data (HANDLE h, const struct EXTRACTOR_PluginList *plugin) | ||
1200 | { | 1230 | { |
1201 | size_t i; | 1231 | size_t i; |
1202 | DWORD len; | 1232 | DWORD len; |
@@ -1217,7 +1247,9 @@ static void write_plugin_data (HANDLE h, const struct EXTRACTOR_PluginList *plug | |||
1217 | WriteFile (h, plugin->plugin_options, i, &len, NULL); | 1247 | WriteFile (h, plugin->plugin_options, i, &len, NULL); |
1218 | } | 1248 | } |
1219 | 1249 | ||
1220 | static struct EXTRACTOR_PluginList *read_plugin_data (FILE *f) | 1250 | |
1251 | static struct EXTRACTOR_PluginList * | ||
1252 | read_plugin_data (FILE *f) | ||
1221 | { | 1253 | { |
1222 | struct EXTRACTOR_PluginList *ret; | 1254 | struct EXTRACTOR_PluginList *ret; |
1223 | size_t i; | 1255 | size_t i; |
@@ -1239,7 +1271,9 @@ static struct EXTRACTOR_PluginList *read_plugin_data (FILE *f) | |||
1239 | return ret; | 1271 | return ret; |
1240 | } | 1272 | } |
1241 | 1273 | ||
1242 | void CALLBACK RundllEntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) | 1274 | |
1275 | void CALLBACK | ||
1276 | RundllEntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) | ||
1243 | { | 1277 | { |
1244 | int in, out; | 1278 | int in, out; |
1245 | 1279 | ||
@@ -1253,6 +1287,7 @@ void CALLBACK RundllEntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, in | |||
1253 | } | 1287 | } |
1254 | #endif | 1288 | #endif |
1255 | 1289 | ||
1290 | |||
1256 | /** | 1291 | /** |
1257 | * Start the process for the given plugin. | 1292 | * Start the process for the given plugin. |
1258 | */ | 1293 | */ |
@@ -1331,6 +1366,7 @@ start_process (struct EXTRACTOR_PluginList *plugin) | |||
1331 | * | 1366 | * |
1332 | * @param plugin which plugin to call | 1367 | * @param plugin which plugin to call |
1333 | * @param shmfn file name of the shared memory segment | 1368 | * @param shmfn file name of the shared memory segment |
1369 | * @param tshmfn file name of the shared memory segment for the end of the data | ||
1334 | * @param proc function to call on the meta data | 1370 | * @param proc function to call on the meta data |
1335 | * @param proc_cls cls for proc | 1371 | * @param proc_cls cls for proc |
1336 | * @return 0 if proc did not return non-zero | 1372 | * @return 0 if proc did not return non-zero |
@@ -1338,6 +1374,7 @@ start_process (struct EXTRACTOR_PluginList *plugin) | |||
1338 | static int | 1374 | static int |
1339 | extract_oop (struct EXTRACTOR_PluginList *plugin, | 1375 | extract_oop (struct EXTRACTOR_PluginList *plugin, |
1340 | const char *shmfn, | 1376 | const char *shmfn, |
1377 | const char *tshmfn, | ||
1341 | EXTRACTOR_MetaDataProcessor proc, | 1378 | EXTRACTOR_MetaDataProcessor proc, |
1342 | void *proc_cls) | 1379 | void *proc_cls) |
1343 | { | 1380 | { |
@@ -1347,7 +1384,19 @@ extract_oop (struct EXTRACTOR_PluginList *plugin, | |||
1347 | 1384 | ||
1348 | if (plugin->cpid == -1) | 1385 | if (plugin->cpid == -1) |
1349 | return 0; | 1386 | return 0; |
1350 | if (0 >= fprintf (plugin->cpipe_in, "%s\n", shmfn)) | 1387 | if (0 >= fprintf (plugin->cpipe_in, |
1388 | "%s\n", | ||
1389 | shmfn)) | ||
1390 | { | ||
1391 | stop_process (plugin); | ||
1392 | plugin->cpid = -1; | ||
1393 | if (plugin->flags != EXTRACTOR_OPTION_DEFAULT_POLICY) | ||
1394 | plugin->flags = EXTRACTOR_OPTION_DISABLED; | ||
1395 | return 0; | ||
1396 | } | ||
1397 | if (0 >= fprintf (plugin->cpipe_in, | ||
1398 | "!%s\n", | ||
1399 | (tshmfn != NULL) ? tshmfn : "")) | ||
1351 | { | 1400 | { |
1352 | stop_process (plugin); | 1401 | stop_process (plugin); |
1353 | plugin->cpid = -1; | 1402 | plugin->cpid = -1; |
@@ -1420,33 +1469,108 @@ extract_oop (struct EXTRACTOR_PluginList *plugin, | |||
1420 | 1469 | ||
1421 | 1470 | ||
1422 | /** | 1471 | /** |
1423 | * Extract keywords from a file using the given set of plugins. | 1472 | * Setup a shared memory segment. |
1473 | * | ||
1474 | * @param ptr set to the location of the shm segment | ||
1475 | * @param shmid where to store the shm ID | ||
1476 | * @param fn name of the shared segment | ||
1477 | * @param fn_size size available in fn | ||
1478 | * @param size number of bytes to allocated for the segment | ||
1479 | * @return 0 on success | ||
1480 | */ | ||
1481 | static int | ||
1482 | make_shm (int is_tail, | ||
1483 | void **ptr, | ||
1484 | #ifndef WINDOWS | ||
1485 | int *shmid, | ||
1486 | #else | ||
1487 | HANDLE *mappedFile, | ||
1488 | HANDLE *map, | ||
1489 | #endif | ||
1490 | char *fn, | ||
1491 | size_t fn_size, | ||
1492 | size_t size) | ||
1493 | { | ||
1494 | snprintf (fn, | ||
1495 | fn_size, | ||
1496 | #ifdef WINDOWS | ||
1497 | "%TEMP%\\" | ||
1498 | #else | ||
1499 | "/" | ||
1500 | #endif | ||
1501 | "libextractor-%sshm-%u-%u", | ||
1502 | (is_tail) ? "t" : "", | ||
1503 | getpid(), | ||
1504 | (unsigned int) RANDOM()); | ||
1505 | #ifndef WINDOWS | ||
1506 | *shmid = shm_open (fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); | ||
1507 | *ptr = NULL; | ||
1508 | if (-1 == (*shmid)) | ||
1509 | return 1; | ||
1510 | if ( (0 != ftruncate (*shmid, size)) || | ||
1511 | (NULL == (*ptr = mmap (NULL, size, PROT_WRITE, MAP_SHARED, *shmid, 0))) || | ||
1512 | (*ptr == (void*) -1) ) | ||
1513 | { | ||
1514 | close (*shmid); | ||
1515 | *shmid = -1; | ||
1516 | return 1; | ||
1517 | } | ||
1518 | return 0; | ||
1519 | #else | ||
1520 | *mappedFile = CreateFile (fn, | ||
1521 | GENERIC_READ | GENERIC_WRITE, | ||
1522 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, | ||
1523 | FILE_FLAG_DELETE_ON_CLOSE, NULL); | ||
1524 | *map = CreateFileMapping (*mappedFile, NULL, PAGE_READWRITE, 1, 0, NULL); | ||
1525 | ptr = MapViewOfFile (*map, FILE_MAP_READ, 0, 0, 0); | ||
1526 | if (ptr == NULL) | ||
1527 | { | ||
1528 | CloseHandle (*map); | ||
1529 | CloseHandle (*mappedFile); | ||
1530 | return 1; | ||
1531 | } | ||
1532 | #endif | ||
1533 | return 0; | ||
1534 | } | ||
1535 | |||
1536 | |||
1537 | /** | ||
1538 | * Extract keywords using the given set of plugins. | ||
1424 | * | 1539 | * |
1425 | * @param plugins the list of plugins to use | 1540 | * @param plugins the list of plugins to use |
1426 | * @param filename the name of the file, can be NULL | ||
1427 | * @param data data to process, never NULL | 1541 | * @param data data to process, never NULL |
1428 | * @param size number of bytes in data, ignored if data is NULL | 1542 | * @param size number of bytes in data, ignored if data is NULL |
1543 | * @param tdata end of file data, or NULL | ||
1544 | * @param tsize number of bytes in tdata | ||
1429 | * @param proc function to call for each meta data item found | 1545 | * @param proc function to call for each meta data item found |
1430 | * @param proc_cls cls argument to proc | 1546 | * @param proc_cls cls argument to proc |
1431 | */ | 1547 | */ |
1432 | static void | 1548 | static void |
1433 | extract (struct EXTRACTOR_PluginList *plugins, | 1549 | extract (struct EXTRACTOR_PluginList *plugins, |
1434 | const char * filename, | ||
1435 | const char * data, | 1550 | const char * data, |
1436 | size_t size, | 1551 | size_t size, |
1552 | const char * tdata, | ||
1553 | size_t tsize, | ||
1437 | EXTRACTOR_MetaDataProcessor proc, | 1554 | EXTRACTOR_MetaDataProcessor proc, |
1438 | void *proc_cls) | 1555 | void *proc_cls) |
1439 | { | 1556 | { |
1440 | struct EXTRACTOR_PluginList *ppos; | 1557 | struct EXTRACTOR_PluginList *ppos; |
1441 | #ifndef WINDOWS | ||
1442 | int shmid; | ||
1443 | #else | ||
1444 | HANDLE map, mappedFile; | ||
1445 | #endif | ||
1446 | enum EXTRACTOR_Options flags; | 1558 | enum EXTRACTOR_Options flags; |
1447 | void *ptr; | 1559 | void *ptr; |
1560 | void *tptr; | ||
1448 | char fn[255]; | 1561 | char fn[255]; |
1562 | char tfn[255]; | ||
1449 | int want_shm; | 1563 | int want_shm; |
1564 | int want_tail; | ||
1565 | #ifndef WINDOWS | ||
1566 | int shmid; | ||
1567 | int tshmid; | ||
1568 | #else | ||
1569 | HANDLE map; | ||
1570 | HANDLE mappedFile; | ||
1571 | HANDLE tmap; | ||
1572 | HANDLE tmappedFile; | ||
1573 | #endif | ||
1450 | 1574 | ||
1451 | want_shm = 0; | 1575 | want_shm = 0; |
1452 | ppos = plugins; | 1576 | ppos = plugins; |
@@ -1472,100 +1596,106 @@ extract (struct EXTRACTOR_PluginList *plugins, | |||
1472 | } | 1596 | } |
1473 | ppos = ppos->next; | 1597 | ppos = ppos->next; |
1474 | } | 1598 | } |
1599 | ptr = NULL; | ||
1600 | tptr = NULL; | ||
1475 | if (want_shm) | 1601 | if (want_shm) |
1476 | { | 1602 | { |
1477 | snprintf (fn, | 1603 | if (size > MAX_READ) |
1478 | sizeof(fn), | 1604 | size = MAX_READ; |
1479 | #ifdef WINDOWS | 1605 | if (0 == make_shm (0, |
1480 | "%TEMP%\\" | 1606 | &ptr, |
1607 | #ifndef WINDOWS | ||
1608 | &shmid, | ||
1481 | #else | 1609 | #else |
1482 | "/" | 1610 | &mappedFile, |
1611 | &map, | ||
1483 | #endif | 1612 | #endif |
1484 | "libextractor-shm-%u-%u", | 1613 | fn, sizeof(fn), size)) |
1485 | getpid(), | ||
1486 | (unsigned int) RANDOM()); | ||
1487 | #ifndef WINDOWS | ||
1488 | shmid = shm_open (fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); | ||
1489 | ptr = NULL; | ||
1490 | if (shmid != -1) | ||
1491 | { | 1614 | { |
1492 | if ( (0 != ftruncate (shmid, size)) || | 1615 | memcpy (ptr, data, size); |
1493 | (NULL == (ptr = mmap (NULL, size, PROT_WRITE, MAP_SHARED, shmid, 0))) || | 1616 | if ( (tdata != NULL) && |
1494 | (ptr == (void*) -1) ) | 1617 | (0 == make_shm (1, |
1618 | &tptr, | ||
1619 | #ifndef WINDOWS | ||
1620 | &tshmid, | ||
1621 | #else | ||
1622 | &tmappedFile, | ||
1623 | &tmap, | ||
1624 | #endif | ||
1625 | tfn, sizeof(tfn), tsize)) ) | ||
1495 | { | 1626 | { |
1496 | close (shmid); | 1627 | memcpy (tptr, tdata, tsize); |
1497 | shmid = -1; | ||
1498 | } | 1628 | } |
1499 | else | 1629 | else |
1500 | { | 1630 | { |
1501 | memcpy (ptr, data, size); | 1631 | tptr = NULL; |
1502 | } | 1632 | } |
1503 | } | 1633 | } |
1504 | #else | ||
1505 | mappedFile = CreateFile (fn, GENERIC_READ | GENERIC_WRITE, | ||
1506 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, | ||
1507 | FILE_FLAG_DELETE_ON_CLOSE, NULL); | ||
1508 | map = CreateFileMapping (mappedFile, NULL, PAGE_READWRITE, 1, 0, NULL); | ||
1509 | ptr = MapViewOfFile (map, FILE_MAP_READ, 0, 0, 0); | ||
1510 | if (ptr == NULL) | ||
1511 | { | ||
1512 | CloseHandle (map); | ||
1513 | CloseHandle (mappedFile); | ||
1514 | map = NULL; | ||
1515 | } | ||
1516 | else | 1634 | else |
1517 | memcpy (ptr, data, size); | 1635 | { |
1518 | #endif | 1636 | want_shm = 0; |
1637 | } | ||
1519 | } | 1638 | } |
1520 | else | ||
1521 | #ifndef WINDOWS | ||
1522 | shmid = -1; | ||
1523 | if (want_shm && (shmid == -1)) | ||
1524 | _exit(1); | ||
1525 | #else | ||
1526 | map = NULL; | ||
1527 | if (want_shm && map == NULL) | ||
1528 | _exit(1); | ||
1529 | #endif | ||
1530 | ppos = plugins; | 1639 | ppos = plugins; |
1531 | while (NULL != ppos) | 1640 | while (NULL != ppos) |
1532 | { | 1641 | { |
1533 | flags = ppos->flags; | 1642 | flags = ppos->flags; |
1534 | #ifndef WINDOWS | 1643 | if (! want_shm) |
1535 | if (shmid == -1) | ||
1536 | #else | ||
1537 | if (map == NULL) | ||
1538 | #endif | ||
1539 | flags = EXTRACTOR_OPTION_IN_PROCESS; | 1644 | flags = EXTRACTOR_OPTION_IN_PROCESS; |
1540 | switch (flags) | 1645 | switch (flags) |
1541 | { | 1646 | { |
1542 | case EXTRACTOR_OPTION_DEFAULT_POLICY: | 1647 | case EXTRACTOR_OPTION_DEFAULT_POLICY: |
1543 | if (0 != extract_oop (ppos, fn, proc, proc_cls)) | 1648 | if (0 != extract_oop (ppos, fn, |
1649 | (tptr != NULL) ? tfn : NULL, | ||
1650 | proc, proc_cls)) | ||
1544 | return; | 1651 | return; |
1545 | if (ppos->cpid == -1) | 1652 | if (ppos->cpid == -1) |
1546 | { | 1653 | { |
1547 | start_process (ppos); | 1654 | start_process (ppos); |
1548 | if (0 != extract_oop (ppos, fn, proc, proc_cls)) | 1655 | if (0 != extract_oop (ppos, fn, |
1656 | (tptr != NULL) ? tfn : NULL, | ||
1657 | proc, proc_cls)) | ||
1549 | return; | 1658 | return; |
1550 | } | 1659 | } |
1551 | break; | 1660 | break; |
1552 | case EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART: | 1661 | case EXTRACTOR_OPTION_OUT_OF_PROCESS_NO_RESTART: |
1553 | if (0 != extract_oop (ppos, fn, proc, proc_cls)) | 1662 | if (0 != extract_oop (ppos, fn, |
1663 | (tptr != NULL) ? tfn : NULL, | ||
1664 | proc, proc_cls)) | ||
1554 | return; | 1665 | return; |
1555 | break; | 1666 | break; |
1556 | case EXTRACTOR_OPTION_IN_PROCESS: | 1667 | case EXTRACTOR_OPTION_IN_PROCESS: |
1557 | if (NULL == ppos->extractMethod) | 1668 | want_tail = ( (ppos->specials != NULL) && |
1669 | (NULL != strstr (ppos->specials, | ||
1670 | "want-tail"))); | ||
1671 | if (NULL == ppos->extractMethod) | ||
1558 | plugin_load (ppos); | 1672 | plugin_load (ppos); |
1559 | if ( ( (ppos->specials == NULL) || | 1673 | if ( ( (ppos->specials == NULL) || |
1560 | (NULL == strstr (ppos->specials, | 1674 | (NULL == strstr (ppos->specials, |
1561 | "oop-only")) ) && | 1675 | "oop-only")) ) ) |
1562 | (NULL != ppos->extractMethod) && | 1676 | { |
1563 | (0 != ppos->extractMethod (data, | 1677 | if (want_tail) |
1564 | size, | 1678 | { |
1565 | proc, | 1679 | if ( (NULL != ppos->extractMethod) && |
1566 | proc_cls, | 1680 | (tdata != NULL) && |
1567 | ppos->plugin_options)) ) | 1681 | (0 != ppos->extractMethod (tdata, |
1568 | return; | 1682 | tsize, |
1683 | proc, | ||
1684 | proc_cls, | ||
1685 | ppos->plugin_options)) ) | ||
1686 | return; | ||
1687 | } | ||
1688 | else | ||
1689 | { | ||
1690 | if ( (NULL != ppos->extractMethod) && | ||
1691 | (0 != ppos->extractMethod (data, | ||
1692 | size, | ||
1693 | proc, | ||
1694 | proc_cls, | ||
1695 | ppos->plugin_options)) ) | ||
1696 | return; | ||
1697 | } | ||
1698 | } | ||
1569 | break; | 1699 | break; |
1570 | case EXTRACTOR_OPTION_DISABLED: | 1700 | case EXTRACTOR_OPTION_DISABLED: |
1571 | break; | 1701 | break; |
@@ -1580,10 +1710,21 @@ extract (struct EXTRACTOR_PluginList *plugins, | |||
1580 | if (shmid != -1) | 1710 | if (shmid != -1) |
1581 | close (shmid); | 1711 | close (shmid); |
1582 | shm_unlink (fn); | 1712 | shm_unlink (fn); |
1713 | if (NULL != tptr) | ||
1714 | munmap (tptr, tsize); | ||
1715 | if (tshmid != -1) | ||
1716 | close (tshmid); | ||
1717 | shm_unlink (tfn); | ||
1583 | #else | 1718 | #else |
1584 | UnmapViewOfFile (ptr); | 1719 | UnmapViewOfFile (ptr); |
1585 | CloseHandle (map); | 1720 | CloseHandle (map); |
1586 | CloseHandle (mappedFile); | 1721 | CloseHandle (mappedFile); |
1722 | if (tptr != NULL) | ||
1723 | { | ||
1724 | UnmapViewOfFile (tptr); | ||
1725 | CloseHandle (tmap); | ||
1726 | CloseHandle (tmappedFile); | ||
1727 | } | ||
1587 | #endif | 1728 | #endif |
1588 | } | 1729 | } |
1589 | } | 1730 | } |
@@ -1595,17 +1736,19 @@ extract (struct EXTRACTOR_PluginList *plugins, | |||
1595 | * contents if they were not compressed). | 1736 | * contents if they were not compressed). |
1596 | * | 1737 | * |
1597 | * @param plugins the list of plugins to use | 1738 | * @param plugins the list of plugins to use |
1598 | * @param filename the name of the file, can be NULL | ||
1599 | * @param data data to process, never NULL | 1739 | * @param data data to process, never NULL |
1600 | * @param size number of bytes in data, ignored if data is NULL | 1740 | * @param size number of bytes in data |
1741 | * @param tdata end of file data, or NULL | ||
1742 | * @param tsize number of bytes in tdata | ||
1601 | * @param proc function to call for each meta data item found | 1743 | * @param proc function to call for each meta data item found |
1602 | * @param proc_cls cls argument to proc | 1744 | * @param proc_cls cls argument to proc |
1603 | */ | 1745 | */ |
1604 | static void | 1746 | static void |
1605 | decompress_and_extract (struct EXTRACTOR_PluginList *plugins, | 1747 | decompress_and_extract (struct EXTRACTOR_PluginList *plugins, |
1606 | const char * filename, | ||
1607 | const unsigned char * data, | 1748 | const unsigned char * data, |
1608 | size_t size, | 1749 | size_t size, |
1750 | const char * tdata, | ||
1751 | size_t tsize, | ||
1609 | EXTRACTOR_MetaDataProcessor proc, | 1752 | EXTRACTOR_MetaDataProcessor proc, |
1610 | void *proc_cls) { | 1753 | void *proc_cls) { |
1611 | unsigned char * buf; | 1754 | unsigned char * buf; |
@@ -1838,9 +1981,10 @@ decompress_and_extract (struct EXTRACTOR_PluginList *plugins, | |||
1838 | size = dsize; | 1981 | size = dsize; |
1839 | } | 1982 | } |
1840 | extract (plugins, | 1983 | extract (plugins, |
1841 | filename, | ||
1842 | (const char*) data, | 1984 | (const char*) data, |
1843 | size, | 1985 | size, |
1986 | tdata, | ||
1987 | tsize, | ||
1844 | proc, | 1988 | proc, |
1845 | proc_cls); | 1989 | proc_cls); |
1846 | if (buf != NULL) | 1990 | if (buf != NULL) |
@@ -1908,9 +2052,13 @@ EXTRACTOR_extract (struct EXTRACTOR_PluginList *plugins, | |||
1908 | { | 2052 | { |
1909 | int fd; | 2053 | int fd; |
1910 | void * buffer; | 2054 | void * buffer; |
2055 | void * tbuffer; | ||
1911 | struct stat fstatbuf; | 2056 | struct stat fstatbuf; |
1912 | size_t fsize; | 2057 | size_t fsize; |
2058 | size_t tsize; | ||
1913 | int eno; | 2059 | int eno; |
2060 | off_t offset; | ||
2061 | long pg; | ||
1914 | 2062 | ||
1915 | fd = -1; | 2063 | fd = -1; |
1916 | buffer = NULL; | 2064 | buffer = NULL; |
@@ -1941,14 +2089,41 @@ EXTRACTOR_extract (struct EXTRACTOR_PluginList *plugins, | |||
1941 | if ( (buffer == NULL) && | 2089 | if ( (buffer == NULL) && |
1942 | (data == NULL) ) | 2090 | (data == NULL) ) |
1943 | return; | 2091 | return; |
2092 | /* for footer extraction */ | ||
2093 | tsize = 0; | ||
2094 | tbuffer = NULL; | ||
2095 | if ( (data == NULL) && | ||
2096 | (fstatbuf.st_size > fsize) && | ||
2097 | (fstatbuf.st_size > MAX_READ) ) | ||
2098 | { | ||
2099 | pg = sysconf (_SC_PAGE_SIZE); | ||
2100 | if ( (pg > 0) && | ||
2101 | (pg < MAX_READ) ) | ||
2102 | { | ||
2103 | offset = (1 + (fstatbuf.st_size - MAX_READ) / pg) * pg; | ||
2104 | if (offset < fstatbuf.st_size) | ||
2105 | { | ||
2106 | tsize = fstatbuf.st_size - offset; | ||
2107 | tbuffer = MMAP (NULL, tsize, PROT_READ, MAP_PRIVATE, fd, offset); | ||
2108 | if ( (tbuffer == NULL) || (tbuffer == (void *) -1) ) | ||
2109 | { | ||
2110 | tsize = 0; | ||
2111 | tbuffer = NULL; | ||
2112 | } | ||
2113 | } | ||
2114 | } | ||
2115 | } | ||
1944 | decompress_and_extract (plugins, | 2116 | decompress_and_extract (plugins, |
1945 | filename, | ||
1946 | buffer != NULL ? buffer : data, | 2117 | buffer != NULL ? buffer : data, |
1947 | buffer != NULL ? fsize : size, | 2118 | buffer != NULL ? fsize : size, |
2119 | tbuffer, | ||
2120 | tsize, | ||
1948 | proc, | 2121 | proc, |
1949 | proc_cls); | 2122 | proc_cls); |
1950 | if (buffer != NULL) | 2123 | if (buffer != NULL) |
1951 | MUNMAP (buffer, fsize); | 2124 | MUNMAP (buffer, fsize); |
2125 | if (tbuffer != NULL) | ||
2126 | MUNMAP (tbuffer, tsize); | ||
1952 | if (-1 != fd) | 2127 | if (-1 != fd) |
1953 | close(fd); | 2128 | close(fd); |
1954 | } | 2129 | } |