script_fileList.js (4670B)
1 /* eslint-env mozilla/chrome-script */ 2 // eslint-disable-next-line mozilla/reject-importGlobalProperties 3 Cu.importGlobalProperties(["File"]); 4 function createProfDFile() { 5 return Services.dirsvc 6 .QueryInterface(Ci.nsIProperties) 7 .get("ProfD", Ci.nsIFile); 8 } 9 10 const { AppConstants } = ChromeUtils.importESModule( 11 "resource://gre/modules/AppConstants.sys.mjs" 12 ); 13 14 // Creates a parametric arity directory hierarchy as a function of depth. 15 // Each directory contains one leaf file, and subdirectories of depth [1, depth). 16 // e.g. for depth 3: 17 // 18 // subdir3 19 // - file.txt 20 // - subdir2 21 // - file.txt 22 // - subdir1 23 // - file.txt 24 // - subdir1 25 // - file.txt 26 // 27 // Returns the parent directory of the subtree. 28 function createTreeFile(depth, parent) { 29 if (!parent) { 30 parent = Services.dirsvc 31 .QueryInterface(Ci.nsIProperties) 32 .get("TmpD", Ci.nsIFile); 33 parent.append("dir-tree-test"); 34 parent.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o700); 35 } 36 37 var nextFile = parent.clone(); 38 if (depth == 0) { 39 nextFile.append("file.txt"); 40 nextFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600); 41 42 // It's not possible to create symlinks on windows by default or on our 43 // Android platforms, so we can't create the symlink file there. Our 44 // callers that care are aware of this and also check AppConstants. 45 if ( 46 AppConstants.platform !== "win" && 47 AppConstants.platform !== "android" 48 ) { 49 var linkFile = parent.clone(); 50 linkFile.append("symlink.txt"); 51 createSymLink(nextFile.path, linkFile.path); 52 } 53 } else { 54 nextFile.append("subdir" + depth); 55 nextFile.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o700); 56 // Decrement the maximal depth by one for each level of nesting. 57 for (var i = 0; i < depth; i++) { 58 createTreeFile(i, nextFile); 59 } 60 } 61 62 return parent; 63 } 64 65 function createRootFile() { 66 var testFile = createProfDFile(); 67 68 // Let's go back to the root of the FileSystem 69 while (true) { 70 var parent = testFile.parent; 71 if (!parent) { 72 break; 73 } 74 75 testFile = parent; 76 } 77 78 return testFile; 79 } 80 81 var process; 82 function createSymLink(target, linkName) { 83 if (!process) { 84 var ln = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); 85 ln.initWithPath("/bin/ln"); 86 87 process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); 88 process.init(ln); 89 } 90 91 const args = ["-s", target, linkName]; 92 process.run(true, args, args.length); 93 Assert.equal(process.exitValue, 0); 94 } 95 96 function createTestFile() { 97 var tmpFile = Services.dirsvc 98 .QueryInterface(Ci.nsIProperties) 99 .get("TmpD", Ci.nsIFile); 100 tmpFile.append("dir-test"); 101 tmpFile.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o700); 102 103 var file1 = tmpFile.clone(); 104 file1.append("foo.txt"); 105 file1.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600); 106 107 var dir = tmpFile.clone(); 108 dir.append("subdir"); 109 dir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o700); 110 111 var file2 = dir.clone(); 112 file2.append("bar.txt"); 113 file2.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600); 114 115 // It's not possible to create symlinks on windows by default or on our 116 // Android platforms, so we can't create the symlink file there. Our 117 // callers that care are aware of this and also check AppConstants. 118 if (AppConstants.platform !== "win" && AppConstants.platform !== "android") { 119 var linkFile = dir.clone(); 120 linkFile.append("symlink.txt"); 121 createSymLink(file1.path, linkFile.path); 122 } 123 124 return tmpFile; 125 } 126 127 addMessageListener("dir.open", function (e) { 128 var testFile; 129 130 switch (e.path) { 131 case "ProfD": 132 // Note that files in the profile directory are not guaranteed to persist- 133 // see bug 1284742. 134 testFile = createProfDFile(); 135 break; 136 137 case "root": 138 testFile = createRootFile(); 139 break; 140 141 case "test": 142 testFile = createTestFile(); 143 break; 144 145 case "tree": 146 testFile = createTreeFile(3); 147 break; 148 } 149 150 sendAsyncMessage("dir.opened", { 151 dir: testFile.path, 152 name: testFile.leafName, 153 }); 154 }); 155 156 addMessageListener("file.open", function () { 157 var testFile = Services.dirsvc 158 .QueryInterface(Ci.nsIProperties) 159 .get("ProfD", Ci.nsIFile); 160 testFile.append("prefs.js"); 161 162 File.createFromNsIFile(testFile).then(function (file) { 163 sendAsyncMessage("file.opened", { file }); 164 }); 165 }); 166 167 addMessageListener("symlink.open", function () { 168 let testDir = createTestFile(); 169 let testFile = testDir.clone(); 170 testFile.append("subdir"); 171 testFile.append("symlink.txt"); 172 173 File.createFromNsIFile(testFile).then(function (file) { 174 sendAsyncMessage("symlink.opened", { dir: testDir.path, file }); 175 }); 176 });