From 9feca9b0b90a107ece6be1b4d197e08020a40690 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Sun, 13 Dec 2020 22:02:29 -0800 Subject: Add unlink support. Make by-title/ writable. Add . and .. entries. Still haven't added the unlink handler to by-title/, though. --- README.md | 6 +++++- extension/background.js | 21 ++++++++++++++------- fs/tabfs.c | 13 ++++++++++++- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0fd6c42..fc13381 100644 --- a/README.md +++ b/README.md @@ -54,12 +54,16 @@ $ echo remove | tee -a mnt/tabs/by-title/*Stack_Overflow*/control $ cat mnt/tabs/by-id/*/text > text.txt ``` +### TODO: Manage tabs in Emacs dired + +I do this + ## Setup **disclaimer**: security, functionality. In some sense, the whole point of this extension is to create a gigantic new surface area of communication between stuff inside your browser and the rest of your -computer. +computer. permissions First, install the browser extension. diff --git a/extension/background.js b/extension/background.js index 964e210..a233f27 100644 --- a/extension/background.js +++ b/extension/background.js @@ -156,7 +156,7 @@ const defineFile = (getData, setData) => ({ router["/tabs/by-id"] = { async readdir() { const tabs = await browser.tabs.query({}); - return { entries: tabs.map(tab => String(tab.id)) }; + return { entries: [".", "..", ...tabs.map(tab => String(tab.id))] }; } }; // (should these have .txt extensions?) @@ -169,7 +169,7 @@ router["/tabs/by-id"] = { // TODO: mem (?) // TODO: cpu (?) -// screenshot.png (TODO: when unfocused?) +// screenshot.png (FIXME: how to keep from blocking when unfocused?) // TODO: archive.mhtml ? // TODO: printed.pdf // control @@ -203,7 +203,7 @@ router["/tabs/by-id/*/resources"] = { const tabId = parseInt(pathComponent(path, -2)); await TabManager.debugTab(tabId); await TabManager.enableDomainForTab(tabId, "Page"); const {frameTree} = await sendDebuggerCommand(tabId, "Page.getResourceTree", {}); - return { entries: frameTree.resources.map(r => sanitize(String(r.url).slice(0, 200))) }; + return { entries: [".", "..", ...frameTree.resources.map(r => sanitize(String(r.url).slice(0, 200)))] }; } }; router["/tabs/by-id/*/resources/*"] = defineFile(async path => { @@ -232,7 +232,7 @@ router["/tabs/by-id/*/scripts"] = { }, async readdir({path}) { const tabId = parseInt(pathComponent(path, -2)); - return { entries: BrowserState.scriptsForTab[tabId].map(params => sanitize(params.url).slice(0, 200) + "_" + params.scriptId) }; + return { entries: [".", "..", ...BrowserState.scriptsForTab[tabId].map(params => sanitize(params.url).slice(0, 200) + "_" + params.scriptId)] }; } }; router["/tabs/by-id/*/scripts/*"] = defineFile(async path => { @@ -265,9 +265,16 @@ router["/tabs/by-id/*/control"] = { }; router["/tabs/by-title"] = { + getattr() { + return { + st_mode: unix.S_IFDIR | 0777, + st_nlink: 3, + st_size: 0, + }; + }, async readdir() { const tabs = await browser.tabs.query({}); - return { entries: tabs.map(tab => sanitize(String(tab.title).slice(0, 200)) + "_" + String(tab.id)) }; + return { entries: [".", "..", ...tabs.map(tab => sanitize(String(tab.title).slice(0, 200)) + "_" + String(tab.id))] }; } }; router["/tabs/by-title/*"] = { @@ -304,7 +311,7 @@ for (let key in router) { (k.match(/\//g) || []).length === (path.match(/\//g) || []).length + 1) .map(k => k.substr((path === '/' ? 0 : path.length) + 1).split('/')[0]); - children = [...new Set(children)]; + children = [".", "..", ...new Set(children)]; router[path] = { readdir() { return { entries: children }; } }; } @@ -342,7 +349,7 @@ for (let key in router) { } else if (router[key].readlink) { router[key] = { async getattr({path}) { - const st_size = (await this.readlink({path})).length + 1; + const st_size = (await this.readlink({path})).buf.length + 1; return { st_mode: unix.S_IFLNK | 0444, st_nlink: 1, diff --git a/fs/tabfs.c b/fs/tabfs.c index 13cd7ee..803d6c2 100644 --- a/fs/tabfs.c +++ b/fs/tabfs.c @@ -225,9 +225,18 @@ tabfs_releasedir(const char *path, struct fuse_file_info *fi) { /* }); */ } +static int tabfs_unlink(const char *path) { + send_request("{op: %Q, path: %Q}", "unlink", path); + + receive_response("{}", NULL); + + return 0; +} + static struct fuse_operations tabfs_filesystem_operations = { .getattr = tabfs_getattr, /* To provide size, permissions, etc. */ .readlink = tabfs_readlink, + .open = tabfs_open, /* To enforce read-only access. */ .read = tabfs_read, /* To provide file content. */ .write = tabfs_write, @@ -235,7 +244,9 @@ static struct fuse_operations tabfs_filesystem_operations = { .opendir = tabfs_opendir, .readdir = tabfs_readdir, /* To provide directory listing. */ - .releasedir = tabfs_releasedir + .releasedir = tabfs_releasedir, + + .unlink = tabfs_unlink }; int main(int argc, char **argv) { -- cgit v1.2.3