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:
M | odrawfs.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;