diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /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-x | sys/src/cmd/aux/antiword/finddata.c | 154 |
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 */ |