aboutsummaryrefslogtreecommitdiff
path: root/src/main/extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/extractor.c')
-rw-r--r--src/main/extractor.c361
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 */
631static void * 631static void *
632get_symbol_with_prefix(void *lib_handle, 632get_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
1199static void write_plugin_data (HANDLE h, const struct EXTRACTOR_PluginList *plugin) 1228static void
1229write_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
1220static struct EXTRACTOR_PluginList *read_plugin_data (FILE *f) 1250
1251static struct EXTRACTOR_PluginList *
1252read_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
1242void CALLBACK RundllEntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) 1274
1275void CALLBACK
1276RundllEntryPoint(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)
1338static int 1374static int
1339extract_oop (struct EXTRACTOR_PluginList *plugin, 1375extract_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 */
1481static int
1482make_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 */
1432static void 1548static void
1433extract (struct EXTRACTOR_PluginList *plugins, 1549extract (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 */
1604static void 1746static void
1605decompress_and_extract (struct EXTRACTOR_PluginList *plugins, 1747decompress_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}