123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- #!/usr/bin/env node
- /* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
- /* eslint-env node */
- /* vim: set ts=2 ft=javascript: */
- var n = "cfb";
- var X = require('../');
- var fs = require('fs');
- var program = require('commander');
- var PRINTJ = require("printj");
- var sprintf = PRINTJ.sprintf;
- program
- .version(X.version)
- .usage('[options] <file> [subfiles...]')
- .option('-l, --list-files', 'list files')
- .option('-r, --repair', 'attempt to repair and garbage-collect archive')
- .option('-c, --create', 'create file')
- .option('-a, --append', 'add files to CFB (overwrite existing data)')
- .option('-d, --delete', 'delete files from CFB')
- .option('-O, --to-stdout', 'extract raw contents to stdout')
- .option('-z, --dump', 'dump internal representation but do not extract')
- .option('-q, --quiet', 'process but do not report')
- .option('--dev', 'development mode')
- .option('--read', 'read but do not print out contents');
- program.parse(process.argv);
- var exit = process.exit;
- var die = function(errno/*:number*/, msg/*:string*/) { console.error(n + ": " + msg); exit(errno); };
- var logit = function(cmd/*:string*/, f/*:string*/) { console.error(sprintf("%-6s %s", cmd, f)); };
- if(program.args.length === 0) die(1, "must specify a filename");
- if(program.create) {
- logit("create", program.args[0]);
- var newcfb = X.utils.cfb_new();
- X.writeFile(newcfb, program.args[0]);
- }
- if(!fs.existsSync(program.args[0])) die(1, "must specify a filename");
- var opts = ({type:'file'}/*:any*/);
- if(program.dev) opts.WTF = true;
- var cfb = X.read(program.args[0], opts);
- if(program.quiet) exit(0);
- if(program.dump) {
- console.log("Full Paths:");
- console.log(cfb.FullPaths.map(function(x/*:string*/) { return " " + x; }).join("\n"));
- console.log("File Index:");
- console.log(cfb.FileIndex);
- exit(0);
- }
- if(program.repair) { X.writeFile(cfb, program.args[0]); exit(0); }
- function fix_string(x/*:string*/)/*:string*/ { return x.replace(/[\u0000-\u001f]/g, function($$) { return sprintf("\\u%04X", $$.charCodeAt(0)); }); }
- var format_date = function(date/*:Date*/)/*:string*/ {
- return sprintf("%02u-%02u-%02u %02u:%02u", date.getUTCMonth()+1, date.getUTCDate(), date.getUTCFullYear()%100, date.getUTCHours(), date.getUTCMinutes());
- };
- if(program.listFiles) {
- var basetime = new Date(1980,0,1);
- var cnt = 0, rootsize = 0, filesize = 0;
- console.log(" Length Date Time Name");
- console.log(" -------- ---- ---- ----");
- cfb.FileIndex.forEach(function(file/*:CFBEntry*/, i/*:number*/) {
- switch(file.type) {
- case 5:
- basetime = file.ct || file.mt || basetime;
- rootsize = file.size;
- break;
- case 2:
- console.log(sprintf("%9lu %s %s", file.size, format_date(basetime), fix_string(cfb.FullPaths[i])));
- filesize += file.size;
- ++cnt;
- }
- });
- console.log(" -------- -------");
- console.log(sprintf("%9lu %lu file%s", rootsize || filesize, cnt, (cnt !== 1 ? "s" : "")));
- exit(0);
- }
- function mkdirp(path/*:string*/) { path.split("/").reduce(function(acc/*:string*/, p/*:string*/) {
- acc += p + "/";
- if(!fs.existsSync(acc)) { logit("mkdir", acc); fs.mkdirSync(acc); }
- return acc;
- }, ""); }
- function write(path/*:string*/, data/*:CFBEntry*/) {
- logit("write", fix_string(path));
- fs.writeFileSync(path, /*::new Buffer((*/data.content/*:: :any))*/ || new Buffer(0));
- }
- if(program.create || program.append) {
- program.args.slice(1).forEach(function(x/*:string*/) {
- logit("append", x);
- X.utils.cfb_add(cfb, "/" + x, fs.readFileSync(x));
- });
- X.writeFile(cfb, program.args[0]);
- exit(0);
- }
- if(program.delete) {
- program.args.slice(1).forEach(function(x/*:string*/) {
- logit("delete", x);
- X.utils.cfb_del(cfb, "/" + x);
- });
- X.writeFile(cfb, program.args[0]);
- exit(0);
- }
- if(program.args.length > 1) {
- program.args.slice(1).forEach(function(x/*:string*/) {
- var data/*:?CFBEntry*/ = X.find(cfb, x.replace(/\\u000\d/g,"!"));
- if(!data) { console.error(x + ": file not found"); return; }
- if(data.type !== 2) { console.error(x + ": not a file"); return; }
- var idx = cfb.FileIndex.indexOf(data), path = cfb.FullPaths[idx];
- if(program.toStdout) return process.stdout.write(/*::new Buffer((*/data.content/*:: :any))*/);
- mkdirp(path.slice(0, path.lastIndexOf("/")));
- write(path, data);
- });
- exit(0);
- }
- if(program.toStdout) exit(0);
- for(var i=0; i!==cfb.FullPaths.length; ++i) {
- if(!cfb.FileIndex[i].name) continue;
- if(cfb.FullPaths[i].slice(-1) === "/") mkdirp(cfb.FullPaths[i]);
- else write(cfb.FullPaths[i], cfb.FileIndex[i]);
- }
|