/*
* prop0.c
* Copyright (C) 2002-2004 A.J. van Os; Released under GNU GPL
*
* Description:
* Read the property information from a Word for DOS file
*/
/*
* tConvertDosDate - convert DOS date format
*
* returns Unix time_t or -1
*/
static time_t
tConvertDosDate(const char *szDosDate)
{
struct tm tTime;
const char *pcTmp;
time_t tResult;
memset(&tTime, 0, sizeof(tTime));
pcTmp = szDosDate;
/* Get the month */
if (!isdigit(*pcTmp)) {
return (time_t)-1;
}
tTime.tm_mon = (int)(*pcTmp - '0');
pcTmp++;
if (isdigit(*pcTmp)) {
tTime.tm_mon *= 10;
tTime.tm_mon += (int)(*pcTmp - '0');
pcTmp++;
}
/* Get the first separater */
if (isalnum(*pcTmp)) {
return (time_t)-1;
}
pcTmp++;
/* Get the day */
if (!isdigit(*pcTmp)) {
return (time_t)-1;
}
tTime.tm_mday = (int)(*pcTmp - '0');
pcTmp++;
if (isdigit(*pcTmp)) {
tTime.tm_mday *= 10;
tTime.tm_mday += (int)(*pcTmp - '0');
pcTmp++;
}
/* Get the second separater */
if (isalnum(*pcTmp)) {
return (time_t)-1;
}
pcTmp++;
/* Get the year */
if (!isdigit(*pcTmp)) {
return (time_t)-1;
}
tTime.tm_year = (int)(*pcTmp - '0');
pcTmp++;
if (isdigit(*pcTmp)) {
tTime.tm_year *= 10;
tTime.tm_year += (int)(*pcTmp - '0');
pcTmp++;
}
/* Check the values */
if (tTime.tm_mon == 0 || tTime.tm_mday == 0 || tTime.tm_mday > 31) {
return (time_t)-1;
}
/* Correct the values */
tTime.tm_mon--; /* From 01-12 to 00-11 */
if (tTime.tm_year < 80) {
tTime.tm_year += 100; /* 00 means 2000 is 100 */
}
tTime.tm_isdst = -1;
tResult = mktime(&tTime);
NO_DBG_MSG(ctime(&tResult));
return tResult;
} /* end of tConvertDosDate */
/*
* Build the lists with Document Property Information for Word for DOS files
*/
void
vGet0DopInfo(FILE *pFile, const UCHAR *aucHeader)
{
document_block_type tDocument;
UCHAR *aucBuffer;
ULONG ulBeginSumdInfo, ulBeginNextBlock;
size_t tLen;
USHORT usOffset;
if (ulBeginSumdInfo < ulBeginNextBlock && ulBeginNextBlock != 0) {
/* There is a summary information block */
tLen = (size_t)(ulBeginNextBlock - ulBeginSumdInfo);
aucBuffer = xmalloc(tLen);
/* Read the summary information block */
if (bReadBytes(aucBuffer, tLen, ulBeginSumdInfo, pFile)) {
usOffset = usGetWord(12, aucBuffer);
if (aucBuffer[usOffset] != 0) {
NO_DBG_STRN(aucBuffer + usOffset, 8);
tDocument.tRevisedDate =
tConvertDosDate((char *)aucBuffer + usOffset);
}
usOffset = usGetWord(14, aucBuffer);
if (aucBuffer[usOffset] != 0) {
NO_DBG_STRN(aucBuffer + usOffset, 8);
tDocument.tCreateDate =
tConvertDosDate((char *)aucBuffer + usOffset);
}
}
aucBuffer = xfree(aucBuffer);
}
vCreateDocumentInfoList(&tDocument);
} /* end of vGet0DopInfo */
/*
* Fill the section information block with information
* from a Word for DOS file.
*/
static void
vGet0SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
section_block_type *pSection)
{
USHORT usCcol;
UCHAR ucTmp;
/*
* Build the lists with Section Property Information for Word for DOS files
*/
void
vGet0SepInfo(FILE *pFile, const UCHAR *aucHeader)
{
section_block_type tSection;
UCHAR *aucBuffer;
ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo;
ULONG ulCharPos, ulSectPage, ulBeginNextBlock;
size_t tSectInfoLen, tIndex, tSections, tBytes;
UCHAR aucTmp[2], aucFpage[35];
fail(pFile == NULL || aucHeader == NULL);
ulBeginOfText = 128;
NO_DBG_HEX(ulBeginOfText);
ulBeginSectInfo = 128 * (ULONG)usGetWord(0x18, aucHeader);
DBG_HEX(ulBeginSectInfo);
ulBeginNextBlock = 128 * (ULONG)usGetWord(0x1a, aucHeader);
DBG_HEX(ulBeginNextBlock);
if (ulBeginSectInfo == ulBeginNextBlock) {
/* There is no section information block */
return;
}
/* Get the the number of sections */
if (!bReadBytes(aucTmp, 2, ulBeginSectInfo, pFile)) {
return;
}
tSections = (size_t)usGetWord(0, aucTmp);
NO_DBG_DEC(tSections);
/* Read the Section Properties */
for (tIndex = 0; tIndex < tSections; tIndex++) {
ulTextOffset = ulGetLong(10 * tIndex, aucBuffer);
NO_DBG_HEX(ulTextOffset);
ulCharPos = ulBeginOfText + ulTextOffset;
NO_DBG_HEX(ulTextOffset);
ulSectPage = ulGetLong(10 * tIndex + 6, aucBuffer);
NO_DBG_HEX(ulSectPage);
if (ulSectPage == FC_INVALID || /* Must use defaults */
ulSectPage < 128 || /* Should not happen */
ulSectPage >= ulBeginSectInfo) { /* Should not happen */
DBG_HEX_C(ulSectPage != FC_INVALID, ulSectPage);
vDefault2SectionInfoList(ulCharPos);
continue;
}
/* Get the number of bytes to read */
if (!bReadBytes(aucTmp, 1, ulSectPage, pFile)) {
continue;
}
tBytes = 1 + (size_t)ucGetByte(0, aucTmp);
NO_DBG_DEC(tBytes);
if (tBytes > sizeof(aucFpage)) {
DBG_DEC(tBytes);
tBytes = sizeof(aucFpage);
}
/* Read the bytes */
if (!bReadBytes(aucFpage, tBytes, ulSectPage, pFile)) {
continue;
}
NO_DBG_PRINT_BLOCK(aucFpage, tBytes);
/* Process the bytes */
vGetDefaultSection(&tSection);
vGet0SectionInfo(aucFpage + 1, tBytes - 1, &tSection);
vAdd2SectionInfoList(&tSection, ulCharPos);
}
/* Clean up before you leave */
aucBuffer = xfree(aucBuffer);
} /* end of vGet0SepInfo */
/*
* Fill the style information block with information
* from a Word for DOS file.
*/
static void
vGet0StyleInfo(int iFodo, const UCHAR *aucGrpprl, style_block_type *pStyle)
{
int iBytes;
UCHAR ucTmp;
/*
* Build the lists with Paragraph Information for Word for DOS files
*/
void
vGet0PapInfo(FILE *pFile, const UCHAR *aucHeader)
{
style_block_type tStyle;
ULONG ulBeginParfInfo, ulCharPos, ulCharPosNext;
int iIndex, iRun, iFodo;
UCHAR aucFpage[128];
/*
* Fill the font information block with information
* from a Word for DOS file.
*/
static void
vGet0FontInfo(int iFodo, const UCHAR *aucGrpprl, font_block_type *pFont)
{
int iBytes;
UCHAR ucTmp;
/*
* Build the lists with Character Information for Word for DOS files
*/
void
vGet0ChrInfo(FILE *pFile, const UCHAR *aucHeader)
{
font_block_type tFont;
ULONG ulBeginCharInfo, ulCharPos, ulCharPosNext;
int iIndex, iRun, iFodo;
UCHAR aucFpage[128];