2023-02-04 23:11:02 +00:00
|
|
|
import { MessageWriter } from "./messagewriter.js";
|
|
|
|
import { MessageReader } from "./messagereader.js";
|
|
|
|
import { ERRNO } from "./errno.js";
|
|
|
|
import { AccessMode } from "./accessmode.js";
|
2023-02-05 10:37:19 +00:00
|
|
|
import { OpenFlags } from "./openflags.js";
|
2023-02-04 23:11:02 +00:00
|
|
|
import { BaseFileSystem } from "./basefilesystem.js";
|
|
|
|
|
|
|
|
|
|
|
|
const Mode = {
|
|
|
|
REG : 0o100000,
|
|
|
|
DIR : 0o040000,
|
|
|
|
CHR : 0o020000,
|
|
|
|
BLK : 0o060000,
|
|
|
|
FIFO : 0o010000,
|
|
|
|
LNK : 0o120000,
|
|
|
|
SOCK : 0o140000
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function fs_access(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const mode = reader.read_u8();
|
2023-02-05 10:37:19 +00:00
|
|
|
const result = filesystem.access(path, mode);
|
2023-02-04 23:11:02 +00:00
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_getattr(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const result = filesystem.getattr(path);
|
|
|
|
if (typeof(result) !== "number") {
|
|
|
|
writer.write_i32(0);
|
|
|
|
writer.write_u64(result.ino | 0);
|
|
|
|
writer.write_u64(result.nlink | 0);
|
|
|
|
writer.write_u32(result.mode | 0);
|
|
|
|
writer.write_i32(result.uid | 0);
|
|
|
|
writer.write_i32(result.gid | 0);
|
|
|
|
writer.write_u64(result.dev | 0);
|
|
|
|
writer.write_u64(result.size | 0);
|
|
|
|
writer.write_u64(result.blocks | 0);
|
|
|
|
writer.write_time(result.atime | 0);
|
|
|
|
writer.write_time(result.mtime | 0);
|
|
|
|
writer.write_time(result.ctime | 0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_readlink(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const result = filesystem.readlink(path);
|
|
|
|
if (typeof(result) != "number") {
|
|
|
|
writer.write_i32(0);
|
|
|
|
writer.write_str(result);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_symlink(reader, writer, filesystem) {
|
|
|
|
const target = reader.read_str();
|
|
|
|
const linkpath = reader.read_str();
|
|
|
|
const result = filesystem.symlink(target, linkpath);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function fs_link(reader, writer, filesystem) {
|
|
|
|
const oldpath = reader.read_str();
|
|
|
|
const newpath = reader.read_str();
|
|
|
|
const result = filesystem.link(oldpath, newpath);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_rename(reader, writer, filesystem) {
|
|
|
|
const oldpath = reader.read_str();
|
|
|
|
const newpath = reader.read_str();
|
|
|
|
const flags = reader.read_u8();
|
|
|
|
const result = filesystem.rename(oldpath, newpath, flags);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_chmod(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const mode = reader.read_u32();
|
|
|
|
const result = filesystem.chmod(path, mode);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_chown(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const uid = reader.read_u32();
|
|
|
|
const gid = reader.read_u32();
|
|
|
|
const result = filesystem.chown(path, uid, gid);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_truncate(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const size = reader.read_u64();
|
|
|
|
const fd = reader.read_u64();
|
|
|
|
const result = filesystem.truncate(path, size, fd);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_fsync(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const isDataSync = reader.read_bool();
|
|
|
|
const fd = reader.read_fd();
|
|
|
|
const result = filesystem.fsync(path, isDataSync, fd);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_open(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const flags = reader.read_u32();
|
|
|
|
const [result, fd] = filesystem.open(path, flags);
|
|
|
|
writer.write_i32(result);
|
|
|
|
writer.write_u64(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_mknod(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const mode = reader.read_u32();
|
|
|
|
const rdev = reader.read_u64();
|
|
|
|
const result = filesystem.mknod(path, mode, rdev);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_create(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const mode = reader.read_u32();
|
|
|
|
const [result, fd] = filesystem.create(path, mode);
|
|
|
|
writer.write_i32(result);
|
|
|
|
writer.write_u64(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_release(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const fd = reader.read_u64();
|
|
|
|
const result = filesystem.release(path, fd);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_unlink(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const result = filesystem.unlink(path);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_read(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const size = reader.read_u32();
|
|
|
|
const offset = reader.read_u64();
|
|
|
|
const fd = reader.read_u64();
|
|
|
|
const result = filesystem.read(path, size, offset, fd);
|
|
|
|
if (typeof(result) != "number") {
|
2023-02-05 10:37:19 +00:00
|
|
|
writer.write_i32(result.length);
|
2023-02-04 23:11:02 +00:00
|
|
|
writer.write_bytes(result);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_write(reader, wriuter, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const data = reader.read_bytes();
|
|
|
|
const offset = reader.read_u64();
|
|
|
|
const fd = reader.read_u64();
|
|
|
|
const result = filesystem.write(path, data, offset, fd);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_mkdir(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str()
|
|
|
|
const mode = reader.read_u32();
|
|
|
|
const result = filesystem.mkdir(path, mode);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_readdir(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const result = filesystem.readdir(path);
|
|
|
|
if (typeof(result) != "number") {
|
|
|
|
writer.write_i32(0);
|
|
|
|
writer.write_strings(result);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_rmdir(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const result = filesystem.rmdir(path);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_statfs(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const result = filesystem.statfs(path);
|
|
|
|
if (typeof(result) != "number") {
|
|
|
|
writer.write_i32t(0)
|
|
|
|
writer.write_u64(result.bsize | 0);
|
|
|
|
writer.write_u64(result.frsize | 0);
|
|
|
|
writer.write_u64(result.blocks | 0);
|
|
|
|
writer.write_u64(result.bfree | 0);
|
|
|
|
writer.write_u64(result.bavail | 0);
|
|
|
|
writer.write_u64(result.files | 0);
|
|
|
|
writer.write_u64(result.ffree | 0);
|
|
|
|
writer.write_u64(result.namemax | 0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_utimens(reader, writer, filesystem) {
|
|
|
|
const path = reader.read_str();
|
|
|
|
const atime = reader.read_time();
|
|
|
|
const mtime = reader.read_time();
|
|
|
|
const result = filesystem.utimens(path, atime, mtime);
|
|
|
|
writer.write_i32(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fs_getcreds(reader, writer, filesystem) {
|
|
|
|
const credentials = filesystem.getcreds();
|
|
|
|
writer.write_str(credentials);
|
|
|
|
}
|
|
|
|
|
|
|
|
const commands = new Map([
|
|
|
|
[0x01, fs_access],
|
|
|
|
[0x02, fs_getattr],
|
|
|
|
[0x03, fs_readlink],
|
|
|
|
[0x04, fs_symlink],
|
|
|
|
[0x05, fs_link],
|
|
|
|
[0x06, fs_rename],
|
|
|
|
[0x07, fs_chmod],
|
|
|
|
[0x08, fs_chown],
|
|
|
|
[0x09, fs_truncate],
|
|
|
|
[0x0a, fs_fsync],
|
|
|
|
[0x0b, fs_open],
|
|
|
|
[0x0c, fs_mknod],
|
|
|
|
[0x0d, fs_create],
|
|
|
|
[0x0e, fs_release],
|
|
|
|
[0x0f, fs_unlink],
|
|
|
|
[0x10, fs_read],
|
|
|
|
[0x11, fs_write],
|
|
|
|
[0x12, fs_mkdir],
|
|
|
|
[0x13, fs_readdir],
|
|
|
|
[0x14, fs_rmdir],
|
|
|
|
[0x15, fs_statfs],
|
|
|
|
[0x16, fs_utimens],
|
|
|
|
[0x17, fs_getcreds]
|
|
|
|
]);
|
|
|
|
|
|
|
|
class Webfuse {
|
|
|
|
|
|
|
|
constructor(url, filesystem) {
|
|
|
|
this.ws = new WebSocket(url, ["webfuse2"]);
|
|
|
|
this.ws.binaryType = 'arraybuffer';
|
2023-02-05 10:37:19 +00:00
|
|
|
this.ws.addEventListener('open', (event) => this.on_connected(event));
|
2023-02-04 23:11:02 +00:00
|
|
|
this.ws.addEventListener('close', (event) => this.on_closed(event));
|
|
|
|
this.ws.addEventListener('error', (event) => this.on_error(event));
|
|
|
|
this.ws.addEventListener('message', (event) => this.on_message(event));
|
|
|
|
|
|
|
|
this.filesystem = filesystem;
|
|
|
|
}
|
|
|
|
|
|
|
|
close() {
|
|
|
|
this.ws.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
on_message(event) {
|
|
|
|
const reader = new MessageReader(event.data);
|
|
|
|
const message_id = reader.read_u32();
|
|
|
|
const message_type = reader.read_u8();
|
|
|
|
|
|
|
|
const writer = new MessageWriter(message_id, 0x80 + message_type);
|
|
|
|
if (commands.has(message_type)) {
|
|
|
|
const command = commands.get(message_type);
|
|
|
|
command(reader, writer, this.filesystem);
|
|
|
|
}
|
|
|
|
else {
|
2023-02-05 10:37:19 +00:00
|
|
|
console.warn(`unknow message type: ${message_type}`);
|
2023-02-04 23:11:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this.ws.send(writer.get_data());
|
|
|
|
}
|
|
|
|
|
2023-02-05 10:37:19 +00:00
|
|
|
on_connected(event) {
|
|
|
|
this.filesystem.connectionstatechanged("connected");
|
|
|
|
}
|
|
|
|
|
2023-02-04 23:11:02 +00:00
|
|
|
on_error(event) {
|
2023-02-05 10:37:19 +00:00
|
|
|
console.info("connection error");
|
2023-02-04 23:11:02 +00:00
|
|
|
this.ws.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
on_closed(event) {
|
2023-02-05 10:37:19 +00:00
|
|
|
this.filesystem.connectionstatechanged("closed");
|
2023-02-04 23:11:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-02-05 10:37:19 +00:00
|
|
|
export { Webfuse, BaseFileSystem, ERRNO, Mode, AccessMode, OpenFlags }
|