Add unlink support. Make by-title/ writable. Add . and .. entries.

Still haven't added the unlink handler to by-title/, though.
This commit is contained in:
Omar Rizwan 2020-12-13 22:02:29 -08:00
parent cabc3fe03f
commit 9feca9b0b9
3 changed files with 31 additions and 9 deletions

View file

@ -54,12 +54,16 @@ $ echo remove | tee -a mnt/tabs/by-title/*Stack_Overflow*/control
$ cat mnt/tabs/by-id/*/text > text.txt $ cat mnt/tabs/by-id/*/text > text.txt
``` ```
### TODO: Manage tabs in Emacs dired
I do this
## Setup ## Setup
**disclaimer**: security, functionality. In some sense, the whole **disclaimer**: security, functionality. In some sense, the whole
point of this extension is to create a gigantic new surface area of point of this extension is to create a gigantic new surface area of
communication between stuff inside your browser and the rest of your communication between stuff inside your browser and the rest of your
computer. computer. permissions
First, install the browser extension. First, install the browser extension.

View file

@ -156,7 +156,7 @@ const defineFile = (getData, setData) => ({
router["/tabs/by-id"] = { router["/tabs/by-id"] = {
async readdir() { async readdir() {
const tabs = await browser.tabs.query({}); 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?) // (should these have .txt extensions?)
@ -169,7 +169,7 @@ router["/tabs/by-id"] = {
// TODO: mem (?) // TODO: mem (?)
// TODO: cpu (?) // TODO: cpu (?)
// screenshot.png (TODO: when unfocused?) // screenshot.png (FIXME: how to keep from blocking when unfocused?)
// TODO: archive.mhtml ? // TODO: archive.mhtml ?
// TODO: printed.pdf // TODO: printed.pdf
// control // control
@ -203,7 +203,7 @@ router["/tabs/by-id/*/resources"] = {
const tabId = parseInt(pathComponent(path, -2)); const tabId = parseInt(pathComponent(path, -2));
await TabManager.debugTab(tabId); await TabManager.enableDomainForTab(tabId, "Page"); await TabManager.debugTab(tabId); await TabManager.enableDomainForTab(tabId, "Page");
const {frameTree} = await sendDebuggerCommand(tabId, "Page.getResourceTree", {}); 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 => { router["/tabs/by-id/*/resources/*"] = defineFile(async path => {
@ -232,7 +232,7 @@ router["/tabs/by-id/*/scripts"] = {
}, },
async readdir({path}) { async readdir({path}) {
const tabId = parseInt(pathComponent(path, -2)); 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 => { router["/tabs/by-id/*/scripts/*"] = defineFile(async path => {
@ -265,9 +265,16 @@ router["/tabs/by-id/*/control"] = {
}; };
router["/tabs/by-title"] = { router["/tabs/by-title"] = {
getattr() {
return {
st_mode: unix.S_IFDIR | 0777,
st_nlink: 3,
st_size: 0,
};
},
async readdir() { async readdir() {
const tabs = await browser.tabs.query({}); 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/*"] = { router["/tabs/by-title/*"] = {
@ -304,7 +311,7 @@ for (let key in router) {
(k.match(/\//g) || []).length === (k.match(/\//g) || []).length ===
(path.match(/\//g) || []).length + 1) (path.match(/\//g) || []).length + 1)
.map(k => k.substr((path === '/' ? 0 : path.length) + 1).split('/')[0]); .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 }; } }; router[path] = { readdir() { return { entries: children }; } };
} }
@ -342,7 +349,7 @@ for (let key in router) {
} else if (router[key].readlink) { } else if (router[key].readlink) {
router[key] = { router[key] = {
async getattr({path}) { async getattr({path}) {
const st_size = (await this.readlink({path})).length + 1; const st_size = (await this.readlink({path})).buf.length + 1;
return { return {
st_mode: unix.S_IFLNK | 0444, st_mode: unix.S_IFLNK | 0444,
st_nlink: 1, st_nlink: 1,

View file

@ -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 = { static struct fuse_operations tabfs_filesystem_operations = {
.getattr = tabfs_getattr, /* To provide size, permissions, etc. */ .getattr = tabfs_getattr, /* To provide size, permissions, etc. */
.readlink = tabfs_readlink, .readlink = tabfs_readlink,
.open = tabfs_open, /* To enforce read-only access. */ .open = tabfs_open, /* To enforce read-only access. */
.read = tabfs_read, /* To provide file content. */ .read = tabfs_read, /* To provide file content. */
.write = tabfs_write, .write = tabfs_write,
@ -235,7 +244,9 @@ static struct fuse_operations tabfs_filesystem_operations = {
.opendir = tabfs_opendir, .opendir = tabfs_opendir,
.readdir = tabfs_readdir, /* To provide directory listing. */ .readdir = tabfs_readdir, /* To provide directory listing. */
.releasedir = tabfs_releasedir .releasedir = tabfs_releasedir,
.unlink = tabfs_unlink
}; };
int main(int argc, char **argv) { int main(int argc, char **argv) {