vfs: Add filo like vfs layer
Signed-off-by: Thomas Heijligen <src@posteo.de>
diff --git a/src/main.c b/src/main.c
index d1939ee..ee3095c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3,18 +3,7 @@
#include <getopt.h>
#include "blockdev.h"
-
-struct fsys_entry {
- char *name;
- int (*mount_func) (void);
- int (*read_func) (char *buf, int len); // read from open file
- int (*dir_func) (char *dirname); // open file
- int (*close_func) (void);
-} fsys_table[] = {
- { "dummy", NULL, NULL, NULL, NULL},
-};
-
-static const size_t fsys_table_length = sizeof(fsys_table) / sizeof(struct fsys_entry);
+#include "vfs.h"
struct program_options {
char *devname;
diff --git a/src/vfs.c b/src/vfs.c
new file mode 100644
index 0000000..f73edb2
--- /dev/null
+++ b/src/vfs.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "vfs.h"
+#include "blockdev.h"
+
+struct fsys_entry {
+ char *name;
+ int (*mount_func) (void);
+ int (*read_func) (char *buf, int len);
+ int (*dir_func) (char *dirname);
+ int (*close_func) (void);
+} static const fsys_table[] = {
+ { "dummy", NULL, NULL, NULL, NULL },
+};
+
+static const size_t fsys_table_length = sizeof(fsys_table) / sizeof(fsys_table[0]);
+
+const struct fsys_entry *fsys = NULL;
+int filemax;
+int filepos;
+
+int mount_fs(char *fs_name)
+{
+ for (size_t i = 0; i < fsys_table_length; i++) {
+ if ((!fs_name || !strcmp(fsys_table[i].name, fs_name)) && fsys_table[i].mount_func()) {
+ fsys = &fsys_table[i];
+ return 1;
+ }
+ }
+
+ if (fs_name)
+ fprintf(stderr, "mount_fs: Faild to mount filesystem: %s.\n", fs_name);
+ else
+ fprintf(stderr, "mount_fs: No matching filesystem found.\n");
+ return 0;
+}
+
+
+
+
+int file_open(const char *filename)
+{
+ if (filename && filename[0] != '/') {
+ fprintf(stderr, "file_open: filename musst start with '/',"
+ "no support for device identifier");
+ return 0;
+ }
+
+ if (!fsys) {
+ fprintf(stderr, "file_open: no open filesystem.\n");
+ return 0;
+ }
+ char *path = strdup(filename);
+ if (!fsys->dir_func(path)) {
+ fprintf(stderr, "file_open: file not found '%s'.\n", filename);
+ return 0;
+ }
+ filepos = 0;
+ return 1;
+}
+
+int file_read(void *buf, unsigned long len)
+{
+ if (filepos < 0 || filepos > filemax)
+ filepos = filemax;
+
+ if (len < 0 || len > filemax - filepos)
+ len = filemax - filepos;
+ return fsys->read_func(buf, len);
+}
+
+unsigned long file_seek(unsigned long offset)
+{
+ if (offset <= filemax)
+ filepos = offset;
+ else
+ filepos = filemax;
+ return filepos;
+}
+
+unsigned long file_size(void)
+{
+ return filemax;
+}
+
+void file_close(void)
+{
+ // In contrast to filo the device is not closed here
+ // devclose();
+}
+
diff --git a/src/vfs.h b/src/vfs.h
new file mode 100644
index 0000000..865b73b
--- /dev/null
+++ b/src/vfs.h
@@ -0,0 +1,31 @@
+#ifndef VFS_H
+#define VFS_H
+
+/** mount_fs
+ * @param fs_name Name of filesystem or NULL for auto selection
+ * @return 1 on success, 0 on failure
+ */
+int mount_fs(char *fs_name);
+
+/** file_open
+ * @param filename
+ * @return 1 on success, 0 on failure
+ */
+int file_open(const char *filename);
+
+/** file_read
+ * @param buf
+ * @param len Size of buffer / bytes to read
+ * @return Number of bytes read
+ */
+int file_read(void *buf, unsigned long len);
+
+unsigned long file_seek(unsigned long offset);
+/**file_size
+ * @return Filesize in bytes
+ */
+unsigned long file_size(void);
+
+void file_close(void);
+
+#endif /* VFS_H */