« index
Coverage for /Users/kris/q-io/fs-root.js : 87%
91 lines |
80 run |
11 missing |
0 partial |
21 blocks |
10 blocks run |
11 blocks missing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | var Q = require("q"); var BOOT = require("./fs-boot"); var COMMON = require("./fs-common"); module.exports = RootFs; function RootFs(outer, root) { var inner = Object.create(BOOT); function attenuate(path) { // the machinations of projecting a path inside a // subroot var actual; // if it's absolute, we want the path relative to // the root of the inner file system if (outer.isAbsolute(path)) { actual = outer.relativeFromDirectory(outer.ROOT, path); } else { actual = path; } // we join the path onto the root of the inner file // system so that parent references from the root // return to the root, emulating standard unix // behavior actual = outer.join(outer.ROOT, actual); // then we reconstruct the path relative to the // inner root actual = outer.relativeFromDirectory(outer.ROOT, actual); // and rejoin it on the outer root actual = outer.join(root, actual); // and find the corresponding real path actual = outer.canonical(actual); return Q.when(actual, function (actual) { // and verify that the outer canonical path is // actually inside the inner canonical path, to // prevent break-outs if (outer.contains(root, actual)) { return { "inner": outer.join(outer.ROOT, outer.relativeFromDirectory(root, actual)), "outer": actual }; } else { return Q.reject("Can't find: " + JSON.stringify(path)); } }); } function workingDirectory() { return outer.ROOT; } COMMON.update(inner, workingDirectory); inner.list = function (path) { return Q.when(attenuate(path), function (path) { return outer.list(path.outer); }).then(null, function (reason) { return Q.reject("Can't list " + JSON.stringify(path)); }); }; inner.open = function (path, flags, charset) { return Q.when(attenuate(path), function (path) { return outer.open(path.outer, flags, charset); }).then(null, function (reason) { return Q.reject("Can't open " + JSON.stringify(path)); }); }; inner.stat = function (path) { return Q.when(attenuate(path), function (path) { return outer.stat(path.outer); }).then(null, function (reason) { return Q.reject("Can't stat " + JSON.stringify(path)); }); }; inner.canonical = function (path) { return Q.when(attenuate(path), function (path) { return path.inner; }).then(null, function (reason) { return Q.reject("Can't find canonical of " + JSON.stringify(path)); }); }; return Q.when(outer.canonical(root), function (_root) { root = _root; return inner; }); } |