summaryrefslogtreecommitdiff
path: root/sys/src/cmd/aux/antiword/finddata.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/aux/antiword/finddata.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/aux/antiword/finddata.c')
-rwxr-xr-xsys/src/cmd/aux/antiword/finddata.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/antiword/finddata.c b/sys/src/cmd/aux/antiword/finddata.c
new file mode 100755
index 000000000..441030c5a
--- /dev/null
+++ b/sys/src/cmd/aux/antiword/finddata.c
@@ -0,0 +1,154 @@
+/*
+ * finddata.c
+ * Copyright (C) 2000-2002 A.J. van Os; Released under GPL
+ *
+ * Description:
+ * Find the blocks that contain the data of MS Word files
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "antiword.h"
+
+
+/*
+ * bAddDataBlocks - Add the blocks to the data block list
+ *
+ * Returns TRUE when successful, otherwise FALSE
+ */
+BOOL
+bAddDataBlocks(ULONG ulDataPosFirst, ULONG ulTotalLength,
+ ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen)
+{
+ data_block_type tDataBlock;
+ ULONG ulDataPos, ulOffset, ulIndex;
+ long lToGo;
+ BOOL bSuccess;
+
+ fail(ulTotalLength > (ULONG)LONG_MAX);
+ fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
+ fail(aulBBD == NULL);
+
+ NO_DBG_HEX(ulDataPosFirst);
+ NO_DBG_DEC(ulTotalLength);
+
+ lToGo = (long)ulTotalLength;
+
+ ulDataPos = ulDataPosFirst;
+ ulOffset = ulDataPosFirst;
+ for (ulIndex = ulStartBlock;
+ ulIndex != END_OF_CHAIN && lToGo > 0;
+ ulIndex = aulBBD[ulIndex]) {
+ if (ulIndex == UNUSED_BLOCK || ulIndex >= (ULONG)tBBDLen) {
+ DBG_DEC(ulIndex);
+ DBG_DEC(tBBDLen);
+ return FALSE;
+ }
+ if (ulOffset >= BIG_BLOCK_SIZE) {
+ ulOffset -= BIG_BLOCK_SIZE;
+ continue;
+ }
+ tDataBlock.ulFileOffset =
+ (ulIndex + 1) * BIG_BLOCK_SIZE + ulOffset;
+ tDataBlock.ulDataPos = ulDataPos;
+ tDataBlock.ulLength = min(BIG_BLOCK_SIZE - ulOffset,
+ (ULONG)lToGo);
+ fail(tDataBlock.ulLength > BIG_BLOCK_SIZE);
+ ulOffset = 0;
+ if (!bAdd2DataBlockList(&tDataBlock)) {
+ DBG_HEX(tDataBlock.ulFileOffset);
+ DBG_HEX(tDataBlock.ulDataPos);
+ DBG_DEC(tDataBlock.ulLength);
+ return FALSE;
+ }
+ ulDataPos += tDataBlock.ulLength;
+ lToGo -= (long)tDataBlock.ulLength;
+ }
+ bSuccess = lToGo == 0 ||
+ (ulTotalLength == (ULONG)LONG_MAX && ulIndex == END_OF_CHAIN);
+ DBG_DEC_C(!bSuccess, lToGo);
+ DBG_DEC_C(!bSuccess, ulTotalLength);
+ DBG_DEC_C(!bSuccess, ulIndex);
+ return bSuccess;
+} /* end of bAddDataBlocks */
+
+/*
+ * bGet6DocumentData - make a list of the data blocks of Word 6/7 files
+ *
+ * Code for "fast saved" files.
+ *
+ * Returns TRUE when successful, otherwise FALSE
+ */
+BOOL
+bGet6DocumentData(FILE *pFile, ULONG ulStartBlock,
+ const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
+{
+ UCHAR *aucBuffer;
+ ULONG ulBeginTextInfo, ulOffset, ulTotLength;
+ size_t tTextInfoLen;
+ int iIndex, iOff, iType, iLen, iPieces;
+
+ DBG_MSG("bGet6DocumentData");
+
+ fail(pFile == NULL);
+ fail(aulBBD == NULL);
+ fail(aucHeader == NULL);
+
+ ulBeginTextInfo = ulGetLong(0x160, aucHeader);
+ DBG_HEX(ulBeginTextInfo);
+ tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader);
+ DBG_DEC(tTextInfoLen);
+
+ aucBuffer = xmalloc(tTextInfoLen);
+ if (!bReadBuffer(pFile, ulStartBlock,
+ aulBBD, tBBDLen, BIG_BLOCK_SIZE,
+ aucBuffer, ulBeginTextInfo, tTextInfoLen)) {
+ aucBuffer = xfree(aucBuffer);
+ return FALSE;
+ }
+ NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen);
+
+ iOff = 0;
+ while (iOff < (int)tTextInfoLen) {
+ iType = (int)ucGetByte(iOff, aucBuffer);
+ iOff++;
+ if (iType == 0) {
+ iOff++;
+ continue;
+ }
+ iLen = (int)usGetWord(iOff, aucBuffer);
+ iOff += 2;
+ if (iType == 1) {
+ iOff += iLen;
+ continue;
+ }
+ if (iType != 2) {
+ werr(0, "Unknown type of 'fastsaved' format");
+ aucBuffer = xfree(aucBuffer);
+ return FALSE;
+ }
+ /* Type 2 */
+ NO_DBG_DEC(iLen);
+ iOff += 2;
+ iPieces = (iLen - 4) / 12;
+ DBG_DEC(iPieces);
+ for (iIndex = 0; iIndex < iPieces; iIndex++) {
+ ulOffset = ulGetLong(
+ iOff + (iPieces + 1) * 4 + iIndex * 8 + 2,
+ aucBuffer);
+ ulTotLength = ulGetLong(iOff + (iIndex + 1) * 4,
+ aucBuffer) -
+ ulGetLong(iOff + iIndex * 4,
+ aucBuffer);
+ if (!bAddDataBlocks(ulOffset, ulTotLength,
+ ulStartBlock,
+ aulBBD, tBBDLen)) {
+ aucBuffer = xfree(aucBuffer);
+ return FALSE;
+ }
+ }
+ break;
+ }
+ aucBuffer = xfree(aucBuffer);
+ return TRUE;
+} /* end of bGet6DocumentData */