#include <u.h>
#include <libc.h>
#include <bio.h>
/* automatically generated; do not edit. */
typedef struct Fibhdr Fibhdr;
struct Fibhdr {
ushort wIdent;
ushort nFib;
ushort nProduct;
ushort lid;
short pnNext;
uchar fDot;
uchar fGlsy;
uchar fComplex;
uchar fHasPic;
uchar cQuickSaves;
uchar fEncrypted;
uchar fWhichTblStm;
uchar fReadOnlyRecommended;
uchar fWriteReservation;
uchar fExtChar;
uchar fLoadOverride;
uchar fFarEast;
uchar fCrypto;
ushort nFibBack;
ulong lKey;
uchar envr;
uchar fMac;
uchar fEmptySpecial;
uchar fLoadOverridePage;
uchar fFutureSavedUndo;
uchar fWord97Saved;
ushort chs;
ushort chsTables;
long fcMin;
long fcMac;
ushort csw;
};
enum { bcFibhdr = 0x22 };
/* automatically generated; do not edit. */
void
readFibhdr(Fibhdr *s, uchar *v, int nv)
{
if(nv < bcFibhdr) sysfatal("not enough data for Fibhdr");
s->wIdent = v[0x0] | (v[0x0+1] << 8);
s->nFib = v[0x2] | (v[0x2+1] << 8);
s->nProduct = v[0x4] | (v[0x4+1] << 8);
s->lid = v[0x6] | (v[0x6+1] << 8);
s->pnNext = v[0x8] | (v[0x8+1] << 8);
s->fDot = ((v[0xA]) & 0x1) >> 0;
s->fGlsy = ((v[0xA]) & 0x2) >> 1;
s->fComplex = ((v[0xA]) & 0x4) >> 2;
s->fHasPic = ((v[0xA]) & 0x8) >> 3;
s->cQuickSaves = ((v[0xA]) & 0x240) >> 4;
s->fEncrypted = ((v[0xB]) & 0x1) >> 0;
s->fWhichTblStm = ((v[0xB]) & 0x2) >> 1;
s->fReadOnlyRecommended = ((v[0xB]) & 0x4) >> 2;
s->fWriteReservation = ((v[0xB]) & 0x8) >> 3;
s->fExtChar = ((v[0xB]) & 0x16) >> 4;
s->fLoadOverride = ((v[0xB]) & 0x32) >> 5;
s->fFarEast = ((v[0xB]) & 0x64) >> 6;
s->fCrypto = ((v[0xB]) & 0x128) >> 7;
s->nFibBack = v[0xC] | (v[0xC+1] << 8);
s->lKey = v[0xE] | (v[0xE+1] << 8)| (v[0xE+2] << 16) | (v[0xE+3] << 24);
s->envr = v[0x12];
s->fMac = ((v[0x13]) & 0x1) >> 0;
s->fEmptySpecial = ((v[0x13]) & 0x2) >> 1;
s->fLoadOverridePage = ((v[0x13]) & 0x4) >> 2;
s->fFutureSavedUndo = ((v[0x13]) & 0x8) >> 3;
s->fWord97Saved = ((v[0x13]) & 0x16) >> 4;
s->chs = v[0x14] | (v[0x14+1] << 8);
s->chsTables = v[0x16] | (v[0x16+1] << 8);
s->fcMin = v[0x18] | (v[0x18+1] << 8)| (v[0x18+2] << 16) | (v[0x18+3] << 24);
s->fcMac = v[0x1C] | (v[0x1C+1] << 8)| (v[0x1C+2] << 16) | (v[0x1C+3] << 24);
s->csw = v[0x20] | (v[0x20+1] << 8);
}
void
usage(void)
{
fprint(2, "usage: mswordstrings /mnt/doc/WordDocument\n");
exits("usage");
}
void
main(int argc, char **argv)
{
Biobuf *b;
Biobuf bout;
uchar buf[512];
Fibhdr f;
int i, c, n;
ARGBEGIN{
default:
usage();
}ARGEND
if(argc != 1)
usage();
Binit(&bout, 1, OWRITE);
b = Bopen(argv[0], OREAD);
if(b == nil) {
fprint(2, "couldn't open file: %r\n");
exits("word");
}
n = Bread(b, buf, sizeof buf);
if(n < sizeof buf) {
fprint(2, "short read: %r\n");
exits("read");
}
readFibhdr(&f, buf, sizeof buf);
// printFibhdr(&f);
Bseek(b, f.fcMin, 0);
n = f.fcMac - f.fcMin;
for(i=0; i<n; i++) {
c = Bgetc(b);
if(c < 0)
break;
switch(c) {
default:
Bputc(&bout, c);
break;
case '\\': Bprint(&bout, "\\"); break; /* field escape */
case 7: Bprint(&bout, "\n"); break; /* cell, row mark */
case 9: Bprint(&bout, "\t"); break; /* tab */
case 11: Bprint(&bout, "\n"); break; /* hard line break */
case 12: Bprint(&bout, "\n\n\n\n"); break; /* page break */
case 13: Bprint(&bout, "\n\n"); break; /* paragraph end */
case 14: break; /* column break */
case 19: Bprint(&bout, "<"); break; /* field begin */
case 20: Bprint(&bout, ":"); break; /* field sep */
case 21: Bprint(&bout, ">"); break; /* field end */
case 30: Bprint(&bout, "-"); break; /* non-breaking hyphen */
case 31: break; /* non-required hyphen */
/* case 45: Bprint(&bout, "-"); break; /* breaking hyphen */
case 160: Bprint(&bout, " "); break; /* non-breaking space */
/*
* these are only supposed to get used when special is set, but we
* never see these ascii values otherwise anyway.
*/
/*
* Empirically, some documents have sections of text where
* every character is followed by a zero byte. Some have sections
* of text where there are no zero bytes. Still others have both
* types and alternate between them. Until we parse which
* characters are ``special'', page numbers lose out.
*/
case 0: /* Bprint(&bout, "<pageno>"); */ break;
case 1: Bprint(&bout, "<picture>"); break;
case 2: Bprint(&bout, "<footnote>"); break;
case 3: Bprint(&bout, "<footnote sep>"); break;
case 4: Bprint(&bout, "<footnote cont>"); break;
case 5: Bprint(&bout, "<animation>"); break;
case 6: Bprint(&bout, "<lineno>"); break;
/* case 7: Bprint(&bout, "<hand picture>"); break; */
case 8: Bprint(&bout, "<drawn object>"); break;
case 10: Bprint(&bout, "<abbrev date>"); break;
/* case 11: Bprint(&bout, "<hh:mm:ss>"); break; */
/* case 12: Bprint(&bout, "<section no>"); break; */
/* case 14: Bprint(&bout, "<Thu>"); break; */
case 15: Bprint(&bout, "<Thursday>"); break;
case 16: Bprint(&bout, "<day of month>"); break;
case 22: Bprint(&bout, "<hour>"); break;
case 23: Bprint(&bout, "<hour hh>"); break;
case 24: Bprint(&bout, "<minute>"); break;
case 25: Bprint(&bout, "<minute mm>"); break;
case 26: Bprint(&bout, "<seconds>"); break;
case 27: Bprint(&bout, "<AM/PM>"); break;
case 28: Bprint(&bout, "<hh:mm:ss>"); break;
case 29: Bprint(&bout, "<date>"); break;
/* printable ascii begins hereish */
/*
case 30: Bprint(&bout, "<mm/dd/yy>"); break;
case 33: Bprint(&bout, "<mm>"); break;
case 34: Bprint(&bout, "<yyyy>"); break;
case 35: Bprint(&bout, "<yy>"); break;
case 36: Bprint(&bout, "<Feb>"); break;
case 37: Bprint(&bout, "<February>"); break;
case 38: Bprint(&bout, "<hh:mm>"); break;
case 39: Bprint(&bout, "<long date>"); break;
case 41: break; */
}
}
Bprint(&bout, "\n");
}
|