securityos/scripts/fs2json.js

114 lines
2.8 KiB
JavaScript

const { mkdir, readdir, readlink, stat, writeFile } = require("fs");
const { basename, dirname, join, resolve: resolvePath } = require("path");
const VERSION = 4;
const IDX_NAME = 0;
const IDX_SIZE = 1;
const IDX_MTIME = 2;
const IDX_TARGET = 3;
const args = process.argv.slice(2);
const argPath = resolvePath(args[args.length - 1]);
const excludedPaths = [];
let outputPath = "";
args.forEach((arg, index) => {
if (arg === "--exclude") excludedPaths.push(args[index + 1]);
if (arg === "--out") outputPath = resolvePath(args[index + 1]);
});
const fs2json = (dir) => {
let totalSize = 0;
const makeNode = (st, name) => {
const obj = [];
obj[IDX_NAME] = name;
obj[IDX_SIZE] = st.size;
obj[IDX_MTIME] = Number(st.mtime);
totalSize += st.size;
return obj;
};
const walk = (walkDir) => {
return new Promise((resolve, reject) => {
const result = [];
readdir(walkDir, (dirError, files) => {
if (dirError) {
reject(dirError);
return;
}
const includedFiles = files.filter(
(file) => !excludedPaths.includes(file)
);
const recur = () => {
const file = includedFiles.shift();
if (file) {
const fullPath = join(walkDir, file);
stat(fullPath, (statError, fileStat) => {
if (statError) {
reject(statError);
return;
}
const name = basename(fullPath);
const node = makeNode(fileStat, name);
if (fileStat.isSymbolicLink()) {
readlink(fullPath, (linkError, path) => {
if (!linkError) {
node[IDX_TARGET] = path;
result.push(node);
recur();
}
});
} else if (fileStat.isDirectory()) {
walk(fullPath).then((rest) => {
node[IDX_TARGET] = rest;
result.push(node);
recur();
});
} else {
result.push(node);
recur();
}
});
} else {
resolve(result);
}
};
recur();
});
});
};
console.info("Creating file tree ...");
return walk(dir).then((data) => {
console.info("Creating json ...");
mkdir(dirname(outputPath), { recursive: true }, () =>
writeFile(
outputPath,
JSON.stringify({
fsroot: data,
size: totalSize,
version: VERSION,
}),
() => process.exit()
)
);
});
};
fs2json(resolvePath(argPath));