olefs

command line tools to extract data from OLE documents like doc, ppt, xls, msg
git clone https://logand.com/git/olefs.git/
Log | Files | Refs

commit 8a8666933e51d1a56b8facaffa1445ecc92f3045
parent 2db62904f67a89bdc07fca1182b8f0f90920f819
Author: Tomas Hlavaty <tom@logand.com>
Date:   Sun, 29 May 2011 16:30:10 +0200

odrawfs fuse read command implemented using peep_stream

Diffstat:
Modrawfs.c | 146+++++++++++++++++++++++++++++++++++--------------------------------------------
1 file changed, 65 insertions(+), 81 deletions(-)

diff --git a/odrawfs.c b/odrawfs.c @@ -1,38 +1,34 @@ +// ls -v1 /tmp/a4 | awk '{print "<p><img src=\"/tmp/a4/" $0 "\"><p>" $0}' >/tmp/index.html + // TODO proper little endian read_ #include <fuse.h> #include <stdlib.h> -#include <assert.h> #include <stdio.h> #include <string.h> #include <errno.h> -#include <fcntl.h> #include <unistd.h> typedef uint8_t byte; -//typedef uint16_t ushort; -//typedef uint16_t wchar; typedef uint32_t dword; -//typedef uint64_t filetime; -//typedef uint64_t ulonglong; #define PATH_MAX 1024 static char *filename; static char cwd[PATH_MAX]; // fuse changes cwd:-{ -struct record_stream { +struct peep_stream { FILE *wrap; off_t start; size_t size; off_t offset; }; -static int record_stream_eof(struct record_stream *s) { +static int peep_stream_eof(struct peep_stream *s) { return !(s->offset < s->size); } -static int record_stream_read(struct record_stream *s, void *buf, size_t size) { +static int peep_stream_read(struct peep_stream *s, void *buf, size_t size) { int left = s->size - s->offset; if(0 < left) { int n = left < size ? left : size; @@ -44,20 +40,14 @@ static int record_stream_read(struct record_stream *s, void *buf, size_t size) { return 0; } -static void record_stream_seek(struct record_stream *s, off_t offset) { - /* FILE *f = fopen("/tmp/log", "a"); */ - /* fprintf(f, "%ld %ld %ld %ld\n", s->start, s->size, s->offset, offset); */ - /* fclose(f); */ +static void peep_stream_seek(struct peep_stream *s, off_t offset) { s->offset = offset; - if(!record_stream_eof(s)) + if(!peep_stream_eof(s)) fseek(s->wrap, s->start + s->offset, SEEK_SET); } -static int read_guid(struct record_stream *s, byte guid[]) { - int n = record_stream_read(s, guid, 16); - if(0 < n) - assert(n == 16); - return n; +static size_t read_guid(FILE *s, byte guid[]) { + return fread(guid, 16, 1, s); } // MS-PPT PowerPoint (.ppt) Binary File Format @@ -69,7 +59,7 @@ struct RecordHeader { dword recLen; } __attribute__((__packed__)); -static int read_RecordHeader(FILE *stream, struct RecordHeader *x) { +static size_t read_RecordHeader(FILE *stream, struct RecordHeader *x) { return fread(x, sizeof(struct RecordHeader), 1, stream); } @@ -96,9 +86,9 @@ struct OfficeArtMetafileHeader { byte filter; //:always #xfe)) } __attribute__((__packed__)); -static int read_OfficeArtMetafileHeader(struct record_stream *s, +static size_t read_OfficeArtMetafileHeader(FILE *s, struct OfficeArtMetafileHeader *x) { - return record_stream_read(s, x, sizeof(struct OfficeArtMetafileHeader)); + return fread(x, sizeof(struct OfficeArtMetafileHeader), 1, s); } static const struct OfficeArtBlip_config { @@ -118,7 +108,7 @@ static const struct OfficeArtBlip_config { {0xF02A, {0x46A, 0x46B, 0x6E2, 0x6E3}, "jpeg", {0x46B, 0x6E3}, 0}, }; -static int member(ushort x, const ushort a[]) { // , size_t n +static int member(ushort x, const ushort a[]) { int i; for(i = 0; i < sizeof(a); i++) if(a[i] == x) @@ -126,45 +116,6 @@ static int member(ushort x, const ushort a[]) { // , size_t n return 0; } -// TODO content and meta stream, or composable head and tail stream! - -/* static void blip(int n, ushort recType, ushort recInstance, dword recLen) { */ -/* const struct OfficeArtBlip_config *config; */ -/* int i; */ -/* for(i = 0; i < sizeof(OfficeArtBlip_config); i++) { */ -/* config = &OfficeArtBlip_config[i]; */ -/* if(OfficeArtBlip_config[i].recType == recType) break; */ -/* } */ -/* assert(member(recInstance, config->recInstance)); */ -/* FILE *stream = fopen(filename, "r"); */ -/* struct record_stream s = {stream, recLen, 0}; */ -/* byte guid[16]; */ -/* read_guid(&s, guid); */ -/* if(member(recInstance, config->guid2)) */ -/* read_guid(&s, guid); */ -/* if(config->metafileHeader) { */ -/* struct OfficeArtMetafileHeader h; */ -/* read_OfficeArtMetafileHeader(&s, &h); */ -/* } */ -/* else { */ -/* byte b; */ -/* record_stream_read(&s, &b, 1); */ -/* } */ -/* char ofile[1024]; */ -/* //snprintf(ofile, 1024, "%s/%d.%s", dir, n, config->ext); */ -/* FILE *o = fopen(ofile, "w"); */ -/* assert(o); */ -/* while(!record_stream_eof(&s)) { */ -/* byte buf[1024]; */ -/* int n = record_stream_read(&s, buf, 1024); */ -/* if(n <= 0) break; */ -/* fwrite(buf, sizeof(char), n, o); */ -/* } */ -/* fclose(o); */ -/* fclose(stream); */ -/* //printf("<p><img src=\"%d.%s\">\n", n, config->ext); */ -/* } */ - struct header { struct RecordHeader h; int i; @@ -174,17 +125,19 @@ struct header { static struct header *headers; -static const char *header_ext(struct header *h) { - char *ext; +static const struct OfficeArtBlip_config *header_config(struct header *h) { int i; for(i = 0; i < sizeof(OfficeArtBlip_config); i++) { const struct OfficeArtBlip_config *c = &OfficeArtBlip_config[i]; - if(c->recType == h->h.recType) { - ext = c->ext; - break; - } + if(c->recType == h->h.recType) + return c; } - return ext; + return NULL; +} + +static const char *header_ext(struct header *h) { + const struct OfficeArtBlip_config *c = header_config(h); + return c ? c->ext : NULL; } static const char *header_path(struct header *h, char *buf, size_t len, int slash) { @@ -250,6 +203,41 @@ static int odrawfs_open(const char *path, struct fuse_file_info *fi) { return -EACCES; } +static size_t read_blib_header(FILE *s, struct header *h) { + size_t n = 0; + const struct OfficeArtBlip_config *c = header_config(h); + if(c) { + byte guid[16]; + n += read_guid(s, guid); + if(member(h->h.recInstance, c->guid2)) + n += read_guid(s, guid); + if(c->metafileHeader) { + struct OfficeArtMetafileHeader h2; + n += read_OfficeArtMetafileHeader(s, &h2); + } + else { + byte b; + n += fread(&b, 1, 1, s); + } + } + return n; +} + +static int read_blib(char *filename, struct header *h, + char *buf, size_t size, off_t offset) { + int n = -EACCES; + FILE *f = fopen(filename, "r"); + if(f) { + fseek(f, h->fpos, SEEK_SET); + size_t hlen = read_blib_header(f, h); // TODO expose header as txt file? + struct peep_stream s = {f, ftell(f), h->h.recLen - hlen, 0}; + peep_stream_seek(&s, offset); + n = peep_stream_read(&s, buf, size); + fclose(f); + } + return n; +} + static int odrawfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int n = -EACCES; @@ -262,16 +250,12 @@ static int odrawfs_read(const char *path, char *buf, size_t size, off_t offset, continue; if((fi->flags & 3) != O_RDONLY) break; - // TODO fix path if not absolute - //char path[PATH_MAX]; - //n = snprintf(path, PATH_MAX, "%s/%s", cwd, filename); - //n = snprintf(buf, PATH_MAX, "%s/%s", cwd, filename); - FILE *f = fopen(filename, "r"); - if(f) { - struct record_stream s = {f, h->fpos, h->h.recLen, 0}; - record_stream_seek(&s, offset); - n = record_stream_read(&s, buf, size); - fclose(f); + if('/' == filename[0]) + n = read_blib(filename, h, buf, size, offset); + else { + char x[PATH_MAX]; + snprintf(x, PATH_MAX, "%s/%s", cwd, filename); + n = read_blib(x, h, buf, size, offset); } break; } @@ -297,8 +281,8 @@ static struct header *read_headers(FILE *stream) { new->i = i; new->fpos = ftell(stream); new->next = NULL; - printf("%d 0x%x 0x%x 0x%x %u %lu\n", new->i, new->h.recVer, - new->h.recInstance, new->h.recType, new->h.recLen, new->fpos); + /* printf("%d 0x%x 0x%x 0x%x %u %lu\n", new->i, new->h.recVer, */ + /* new->h.recInstance, new->h.recType, new->h.recLen, new->fpos); */ fseek(stream, new->h.recLen, SEEK_CUR); if(head) { tail->next = new;