You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
falk-werner_webfuse-example/www/src/filesystem_provider.js

120 lines
3.1 KiB

/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */
import { BadState, FileMode, Provider } from "webfuse";
export class FileSystemProvider extends Provider {
constructor(root) {
super();
this.root = root;
this._inodes = { };
this._walk(this.root, (entry) => { this._inodes[entry.inode] = entry; });
}
_walk(node, callback) {
callback(node);
const entries = node.entries;
if (entries) {
for(let entry of Object.entries(entries)) {
this._walk(entry[1], callback);
}
}
}
async lookup(parent, name) {
const parentEntry = this._inodes[parent];
const entry = (parentEntry && parentEntry.entries && parentEntry.entries[name]) || null;
if (entry) {
return {
inode: entry.inode,
mode: entry.mode || parseInt("755", 8),
type: entry.type || "file",
size: entry.size || (entry.contents && entry.contents.length) || 0,
atime: entry.atime || 0,
mtime: entry.mtime || 0,
ctime: entry.ctime || 0
};
}
else {
throw new BadState(BadState.NO_ENTRY);
}
}
async getattr(inode) {
let entry = this._inodes[inode];
if (entry) {
return {
mode: entry.mode || parseInt("755", 8),
type: entry.type || "file",
size: entry.size || (entry.contents && entry.contents.length) || 0,
atime: entry.atime || 0,
mtime: entry.mtime || 0,
ctime: entry.ctime || 0
};
}
else {
throw new BadState(BadState.NO_ENTRY);
}
}
async readdir(inode) {
let entry = this._inodes[inode];
if ((entry) && ("dir" === entry.type)) {
let result = [
{name: ".", inode: entry.inode},
{name: "..", inode: entry.inode}
];
for(let subdir of Object.entries(entry.entries)) {
const name = subdir[0];
const inode = subdir[1].inode;
result.push({name, inode});
}
return result;
}
else {
throw new BadState(BadState.NO_ENTRY);
}
}
async open(inode, mode) {
let entry = this._inodes[inode];
if (entry.type === "file") {
if ((mode & FileMode.ACCESS_MODE) === FileMode.READONLY) {
return {handle: 1337};
}
else {
throw new BadState(BadState.NO_ACCESS);
}
}
else {
throw new BadState(BadState.NO_ENTRY);
}
}
close(_inode, _handle, _mode) {
// do nothing
return true;
}
async read(inode, handle, offset, length) {
let entry = this._inodes[inode];
if (entry.type === "file") {
const end = Math.min(offset + length, entry.contents.length);
const data = (offset < entry.contents.length) ? entry.contents.substring(offset, end) : "";
return data;
}
else {
throw new BadState(BadState.NO_ENTRY);
}
}
}