xref: /plan9/sys/src/cmd/aux/antiword/wordmac.c (revision 25b329d522281a8cdd35da0dcc08c3fc621059a9)
1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier  * wordmac.c
3*25b329d5SDavid du Colombier  * Copyright (C) 2002-2004 A.J. van Os; Released under GNU GPL
4f5736e95SDavid du Colombier  *
5f5736e95SDavid du Colombier  * Description:
6f5736e95SDavid du Colombier  * Deal with the MAC internals of a MS Word file
7f5736e95SDavid du Colombier  */
8f5736e95SDavid du Colombier 
9f5736e95SDavid du Colombier #include "antiword.h"
10f5736e95SDavid du Colombier 
11f5736e95SDavid du Colombier 
12f5736e95SDavid du Colombier /*
13f5736e95SDavid du Colombier  * bGetDocumentText - make a list of the text blocks of a Word document
14f5736e95SDavid du Colombier  *
15f5736e95SDavid du Colombier  * Return TRUE when succesful, otherwise FALSE
16f5736e95SDavid du Colombier  */
17f5736e95SDavid du Colombier static BOOL
bGetDocumentText(FILE * pFile,const UCHAR * aucHeader)18f5736e95SDavid du Colombier bGetDocumentText(FILE *pFile, const UCHAR *aucHeader)
19f5736e95SDavid du Colombier {
20f5736e95SDavid du Colombier 	text_block_type	tTextBlock;
21f5736e95SDavid du Colombier 	ULONG	ulBeginOfText, ulEndOfText;
22f5736e95SDavid du Colombier 	ULONG	ulTextLen;
23*25b329d5SDavid du Colombier 	UCHAR	ucDocStatus;
24*25b329d5SDavid du Colombier 	BOOL    bFastSaved;
25f5736e95SDavid du Colombier 
26f5736e95SDavid du Colombier 	fail(pFile == NULL);
27f5736e95SDavid du Colombier 	fail(aucHeader == NULL);
28f5736e95SDavid du Colombier 
29f5736e95SDavid du Colombier 	DBG_MSG("bGetDocumentText");
30f5736e95SDavid du Colombier 
31*25b329d5SDavid du Colombier 	NO_DBG_PRINT_BLOCK(aucHeader, 0x20);
32*25b329d5SDavid du Colombier 
33*25b329d5SDavid du Colombier 	/* Get the status flags from the header */
34*25b329d5SDavid du Colombier 	ucDocStatus = ucGetByte(0x0a, aucHeader);
35*25b329d5SDavid du Colombier 	DBG_HEX(ucDocStatus);
36*25b329d5SDavid du Colombier 	bFastSaved = (ucDocStatus & BIT(5)) != 0;
37*25b329d5SDavid du Colombier 	DBG_MSG_C(bFastSaved, "This document is Fast Saved");
38*25b329d5SDavid du Colombier 	if (bFastSaved) {
39*25b329d5SDavid du Colombier 		werr(0, "MacWord: fast saved documents are not supported yet");
40*25b329d5SDavid du Colombier 		return FALSE;
41*25b329d5SDavid du Colombier 	}
42*25b329d5SDavid du Colombier 
43f5736e95SDavid du Colombier 	/* Get length information */
44f5736e95SDavid du Colombier 	ulBeginOfText = ulGetLongBE(0x14, aucHeader);
45f5736e95SDavid du Colombier 	DBG_HEX(ulBeginOfText);
46f5736e95SDavid du Colombier 	ulEndOfText = ulGetLongBE(0x18, aucHeader);
47f5736e95SDavid du Colombier 	DBG_HEX(ulEndOfText);
48f5736e95SDavid du Colombier 	ulTextLen = ulEndOfText - ulBeginOfText;
49f5736e95SDavid du Colombier 	DBG_DEC(ulTextLen);
50f5736e95SDavid du Colombier 	tTextBlock.ulFileOffset = ulBeginOfText;
51f5736e95SDavid du Colombier 	tTextBlock.ulCharPos = ulBeginOfText;
52f5736e95SDavid du Colombier 	tTextBlock.ulLength = ulTextLen;
53f5736e95SDavid du Colombier 	tTextBlock.bUsesUnicode = FALSE;
54f5736e95SDavid du Colombier 	tTextBlock.usPropMod = IGNORE_PROPMOD;
55f5736e95SDavid du Colombier 	if (!bAdd2TextBlockList(&tTextBlock)) {
56f5736e95SDavid du Colombier 		DBG_HEX(tTextBlock.ulFileOffset);
57f5736e95SDavid du Colombier 		DBG_HEX(tTextBlock.ulCharPos);
58f5736e95SDavid du Colombier 		DBG_DEC(tTextBlock.ulLength);
59f5736e95SDavid du Colombier 		DBG_DEC(tTextBlock.bUsesUnicode);
60f5736e95SDavid du Colombier 		DBG_DEC(tTextBlock.usPropMod);
61f5736e95SDavid du Colombier 		return FALSE;
62f5736e95SDavid du Colombier 	}
63f5736e95SDavid du Colombier 	return TRUE;
64f5736e95SDavid du Colombier } /* end of bGetDocumentText */
65f5736e95SDavid du Colombier 
66f5736e95SDavid du Colombier /*
67f5736e95SDavid du Colombier  * iInitDocumentMAC - initialize an MAC document
68f5736e95SDavid du Colombier  *
69f5736e95SDavid du Colombier  * Returns the version of Word that made the document or -1
70f5736e95SDavid du Colombier  */
71f5736e95SDavid du Colombier int
iInitDocumentMAC(FILE * pFile,long lFilesize)72f5736e95SDavid du Colombier iInitDocumentMAC(FILE *pFile, long lFilesize)
73f5736e95SDavid du Colombier {
74f5736e95SDavid du Colombier 	int	iWordVersion;
75f5736e95SDavid du Colombier 	BOOL	bSuccess;
76f5736e95SDavid du Colombier 	USHORT	usIdent;
77f5736e95SDavid du Colombier 	UCHAR	aucHeader[256];
78f5736e95SDavid du Colombier 
79f5736e95SDavid du Colombier 	fail(pFile == NULL);
80f5736e95SDavid du Colombier 
81f5736e95SDavid du Colombier 	if (lFilesize < 256) {
82f5736e95SDavid du Colombier 		return -1;
83f5736e95SDavid du Colombier 	}
84f5736e95SDavid du Colombier 
85f5736e95SDavid du Colombier 	/* Read the headerblock */
86f5736e95SDavid du Colombier 	if (!bReadBytes(aucHeader, 256, 0x00, pFile)) {
87f5736e95SDavid du Colombier 		return -1;
88f5736e95SDavid du Colombier 	}
89f5736e95SDavid du Colombier 	/* Get the "magic number" from the header */
90f5736e95SDavid du Colombier 	usIdent = usGetWord(0x00, aucHeader);
91f5736e95SDavid du Colombier 	DBG_HEX(usIdent);
92f5736e95SDavid du Colombier 	fail(usIdent != 0x37fe);	/* MacWord 4 and 5 */
93f5736e95SDavid du Colombier 	iWordVersion = iGetVersionNumber(aucHeader);
94f5736e95SDavid du Colombier 	if (iWordVersion != 4 && iWordVersion != 5) {
95f5736e95SDavid du Colombier 		werr(0, "This file is not from ''Mac Word 4 or 5'.");
96f5736e95SDavid du Colombier 		return -1;
97f5736e95SDavid du Colombier 	}
98f5736e95SDavid du Colombier 	bSuccess = bGetDocumentText(pFile, aucHeader);
99f5736e95SDavid du Colombier 	if (bSuccess) {
100*25b329d5SDavid du Colombier 		vGetPropertyInfo(pFile, NULL,
101f5736e95SDavid du Colombier 				NULL, 0, NULL, 0,
102f5736e95SDavid du Colombier 				aucHeader, iWordVersion);
103*25b329d5SDavid du Colombier 		vSetDefaultTabWidth(pFile, NULL,
104f5736e95SDavid du Colombier 				NULL, 0, NULL, 0,
105f5736e95SDavid du Colombier 				aucHeader, iWordVersion);
106f5736e95SDavid du Colombier 	}
107f5736e95SDavid du Colombier 	return bSuccess ? iWordVersion : -1;
108f5736e95SDavid du Colombier } /* end of iInitDocumentMAC */
109