448 lines
15 KiB
JavaScript
448 lines
15 KiB
JavaScript
/**
|
||
* kit cli 注册和调用执行
|
||
*/
|
||
require("./init")
|
||
const { CliCmdParser } = require("../../argv")
|
||
const parser = new CliCmdParser("kit V" + $version + " build " + $build);
|
||
const net = require("./net")
|
||
const shell = require("./shell")
|
||
const {sm4en3, sm4de3} = require("./crypto");
|
||
const convutil = require("./util/convutil")
|
||
const path = require("path");
|
||
const fs = require("fs");
|
||
const {sm3} = require("sm-crypto");
|
||
const zlib = require("zlib");
|
||
const mem = require("./mem")
|
||
const { getAllDeviceInfo } = require("./platform")
|
||
const kitcommand = require("./kitcommand")
|
||
kitcommand.init()
|
||
kitcommand.regTo( parser )
|
||
|
||
const registry = require("./registry")
|
||
registry.init()
|
||
registry.regTo( parser )
|
||
|
||
|
||
// parser.addCmdLine("man", "打开在线帮助;", async function (){
|
||
// const uConfig = await $context.get("uConfig")
|
||
// shell.execSync("start " + uConfig.get("man"))
|
||
// });
|
||
// parser.addCmdLine("manu", "人工维护配置;", function (){
|
||
// shell.execSync("start " + $sConfig.getUserConfigPath())
|
||
// });
|
||
//
|
||
// parser.addCmdLine("run [--file] [func]", "运行项目脚本;", function (cli) {
|
||
// $logger.info( "kit 当前执行目录 " + process.cwd());
|
||
// const fs = require("fs");
|
||
//
|
||
// let step = cli.getParamValue("func");
|
||
// if ( ! step ) {
|
||
// step = "main"
|
||
// }
|
||
//
|
||
// let file = cli.getParamValue("file");
|
||
// if ( ! file ) {
|
||
// file = "kit"
|
||
// }
|
||
//
|
||
// const stat = fs.existsSync(`./${file}.js`)
|
||
// if ( ! stat ) {
|
||
// if ( ! cli.getParamValue("file") ) {
|
||
// fs.writeFileSync("./kit.js",
|
||
// `
|
||
// async function main(){
|
||
// console.log("hello kit!")
|
||
// }
|
||
// `);
|
||
// } else {
|
||
// $logger.info( `文件 ${file} 不存在` );
|
||
// return
|
||
// }
|
||
// }
|
||
//
|
||
//
|
||
// const projectScript = fs.readFileSync("./kit.js", "utf-8");
|
||
// const vm = require('node:vm');
|
||
// const script = new vm.Script(projectScript + ";" + step + "()");
|
||
// const context = {
|
||
// animal: 'cat',
|
||
// count: 2,
|
||
// $logger,
|
||
// shell
|
||
// };
|
||
//
|
||
// script.runInNewContext(context, {
|
||
// timeout : 10 * 60 * 1000,
|
||
// breakOnSigint : true,
|
||
// });
|
||
// $logger.info( "暂未实现" );
|
||
// });
|
||
//
|
||
// parser.addCmdLine("config <key> [value]", "查询/设置配置;", async function (cli){
|
||
// let key = cli.getParamValue("key");
|
||
// let value = cli.getParamValue("value");
|
||
// const uConfig = await $context.get("uConfig")
|
||
// if (null != key && null == value) {
|
||
// let v = uConfig.get(key);
|
||
// $logger.info("{} : {}", key, v);
|
||
// } else if (null != key && null != value) {
|
||
// uConfig.set(key, value);
|
||
// $logger.info("set {} : {}", key, value);
|
||
// } else {
|
||
// $logger.error("参数异常");
|
||
// }
|
||
// });
|
||
//
|
||
// parser.addCmdLine("remote-check", "验证远程仓库;", async function (){
|
||
// let remote = await $context.get("remote")
|
||
// if (! ( await remote.check()) ) {
|
||
// $logger.error("远程仓库不可用")
|
||
// return
|
||
// } else {
|
||
// $logger.info("远程仓库可用")
|
||
// }
|
||
// });
|
||
//
|
||
// parser.addCmdLine("publish", "发布到远程仓库;", async function (){
|
||
// let remote = await $context.get("remote")
|
||
// if (! ( await remote.check()) ) {
|
||
// $logger.error("远程仓库不可用")
|
||
// return
|
||
// } else {
|
||
// $logger.info("远程仓库可用")
|
||
// }
|
||
// remote.publish()
|
||
// });
|
||
// parser.addCmdLine("install [module]", "安装/更新模块;", async function (cli){
|
||
// let remote = await $context.get("remote")
|
||
// if (! ( await remote.check()) ) {
|
||
// $logger.error("远程仓库不可用")
|
||
// return
|
||
// } else {
|
||
// $logger.info("远程仓库可用")
|
||
// }
|
||
// remote.install(cli.getParamValue("module"))
|
||
// });
|
||
|
||
|
||
parser.addCmdLine("platform [-json]", "平台信息", function (cli) {
|
||
|
||
|
||
// 调用主函数并打印结果
|
||
getAllDeviceInfo().then(info => {
|
||
console.log('Device Information:');
|
||
let table = []
|
||
for ( let k in info.os ){
|
||
table.push({ '项' : 'OS ' + k, '值' : info.os[k]})
|
||
}
|
||
for ( let k in info.cpu ){
|
||
table.push({ '项' : 'CPU ' + k, '值' : info.cpu[k]})
|
||
}
|
||
for ( let k in info.memory ){
|
||
if ( k.endsWith("Size") ) {
|
||
continue;
|
||
}
|
||
table.push({ '项' : 'Mem ' + k, '值' : info.memory[k]})
|
||
}
|
||
|
||
if( cli.hasFlag("json") ) {
|
||
console.log( JSON.stringify(info, null, 4));
|
||
} else {
|
||
console.table(table);
|
||
const disks = info.disk;
|
||
|
||
const diskTable = []
|
||
disks.forEach(disk => {
|
||
diskTable.push({
|
||
'盘符' : disk.mount
|
||
,'总空间' : `${(disk.size / 1024 / 1024 / 1024).toFixed(2)} GB`
|
||
,'已用空间' : `${(disk.used / 1024 / 1024 / 1024).toFixed(2)} GB`
|
||
,'可用空间' : `${(disk.available / 1024 / 1024 / 1024).toFixed(2)} GB`
|
||
,'使用率' : `${disk.use}%`
|
||
})
|
||
});
|
||
console.table(diskTable);
|
||
}
|
||
}).catch(error => {
|
||
console.error('Error getting device information:', error);
|
||
});
|
||
});
|
||
|
||
|
||
|
||
parser.addCmdLine("freem [level]", "释放内存", function (cli) {
|
||
let level = cli.getParamValue("level")
|
||
mem.free( level )
|
||
});
|
||
|
||
|
||
parser.addCmdLine("dockersh <container> [--file]", "反向获取 docker 容器启动脚本", function (cli) {
|
||
let container = cli.getParamValue("container")
|
||
let file = cli.getParamValue("file")
|
||
import("./docker/index.js").then(psl => psl.main(container, file))
|
||
});
|
||
|
||
|
||
parser.addCmdLine("killport <port>", "释放端口", function (cli) {
|
||
let port = cli.getParamValue("port")
|
||
net.killport( parseInt(port, 10) );
|
||
});
|
||
|
||
|
||
parser.addCmdLine("getport [--port]", "获取一个可用端口;或查询指定端口状态;", async function (cli) {
|
||
const getPort = await import('get-port').then(psl => psl.default);
|
||
let port = cli.getParamValue("port")
|
||
if( ! port ) {
|
||
let ret = await getPort()
|
||
$logger.info(`端口 ${ret} 未被使用`)
|
||
} else {
|
||
await net.getport( port )
|
||
|
||
}
|
||
});
|
||
|
||
parser.addCmdLine("checkip", "获取自己的公网 ip;", async function (cli) {
|
||
let ret = await net.checkip()
|
||
if( "ok" === ret.ret ) {
|
||
$logger.info( "ip : " + ret.data.ip )
|
||
$logger.info( "location : " + ret.data.location.join(" ") )
|
||
} else {
|
||
$logger.error("获取失败")
|
||
}
|
||
});
|
||
|
||
parser.addCmdLine("scan <ip-and-mask> [ports]", "扫描局域网;", async function (cli) {
|
||
let ipAndMask = cli.getParamValue("ip-and-mask")
|
||
let ports = cli.getParamValue("ports")
|
||
let ret = await net.scan(ipAndMask, ports)
|
||
$logger.info( JSON.stringify(ret, null, 4) )
|
||
});
|
||
|
||
|
||
parser.addCmdLine("telnet [--timeout] <ip-port> [port]", "验证远程 TCP 端口是否可用;", async function (cli) {
|
||
let ip = cli.getParamValue("ip-port")
|
||
let port = 80;
|
||
|
||
// 允许冒号形式指定端口
|
||
const re = /^(?<ip>.*):(?<port>[0-9]+)$/
|
||
const match = ip.match( re );
|
||
if ( match ) {
|
||
ip = match.groups.ip;
|
||
port = match.groups.port;
|
||
} else {
|
||
// 如果指定了 port 参数,那么使用 port 参数
|
||
let dport = cli.getParamValue("port")
|
||
if ( dport ) {
|
||
port = dport;
|
||
}
|
||
}
|
||
|
||
// 支持不填写 ip,默认访问本地
|
||
if( "" === ip.trim() ) {
|
||
ip = "127.0.0.1";
|
||
}
|
||
|
||
try {
|
||
await net.telnet(port, ip, cli.getParamValue("timeout"))
|
||
$logger.info("连接成功")
|
||
process.exit(0)
|
||
}catch (e) {
|
||
$logger.error( e )
|
||
process.exit(-1)
|
||
}
|
||
|
||
});
|
||
|
||
parser.addCmdLine("checklist <checkListFile>", "生成/验证文件 hash", async function (cli) {
|
||
let checkListFile = cli.getParamValue("checkListFile")
|
||
if ( !fs.existsSync( checkListFile ) ) {
|
||
$logger.error(`file ${checkListFile} 不存在`)
|
||
process.exit(-2)
|
||
}
|
||
const sm3 = require('sm-crypto').sm3
|
||
const list = fs.readFileSync(checkListFile, "UTF-8")
|
||
const files = list.split('\n').filter(line => line.trim() !== '');
|
||
for ( let file of files ) {
|
||
const infos = file.split(/\s+/)
|
||
const info = {}
|
||
if ( infos.length > 2 ) {
|
||
info.file = infos[0]
|
||
info.hash = infos[1]
|
||
info.alg = infos[2]
|
||
} else {
|
||
info.file = infos[0]
|
||
info.hash = infos[1]
|
||
info.alg = "md5"
|
||
}
|
||
if ( "sm3" === info.alg ) {
|
||
if ( !fs.existsSync( info.file ) ) {
|
||
$logger.error(`file ${info.file} 不存在`)
|
||
process.exit(-2)
|
||
}
|
||
|
||
const data = fs.readFileSync(info.file);
|
||
const arrayBuffer = Buffer.from(data);
|
||
const uint8Array = new Uint8Array(arrayBuffer);
|
||
let hashData = sm3( uint8Array ) // 杂凑
|
||
if ( hashData === info.hash ) {
|
||
$logger.info(`file ${file} 验证通过`)
|
||
} else {
|
||
$logger.error(`file ${file} 验证不通过`)
|
||
process.exit(-400)
|
||
}
|
||
|
||
} else {
|
||
$logger.error(`不支持 file ${file} `)
|
||
process.exit(-2)
|
||
}
|
||
}
|
||
|
||
$logger.info(`${checkListFile} 中的文件全部验证通过`)
|
||
|
||
})
|
||
|
||
parser.addCmdLine("sm3 [--file] [--text] [--hash]", "生成/验证 SM3 值;", async function (cli) {
|
||
let filePath = cli.getParamValue("file")
|
||
let text = cli.getParamValue("text")
|
||
if( !filePath && !text ) {
|
||
$logger.error(`file 和 text 入参不能同时有`)
|
||
process.exit(-1)
|
||
}
|
||
const sm3 = require('sm-crypto').sm3
|
||
if ( text ) {
|
||
let hashData = sm3( text ) // 杂凑
|
||
$logger.info( hashData )
|
||
}
|
||
if ( filePath ) {
|
||
if ( !fs.existsSync( filePath ) ) {
|
||
$logger.error(`file ${filePath} 不存在`)
|
||
process.exit(-2)
|
||
}
|
||
const data = fs.readFileSync(filePath);
|
||
const arrayBuffer = Buffer.from(data);
|
||
const uint8Array = new Uint8Array(arrayBuffer);
|
||
let hashData = sm3( uint8Array ) // 杂凑
|
||
$logger.info( hashData )
|
||
}
|
||
});
|
||
|
||
parser.addCmdLine("sm4en3 <key> <data>", "sm4 加密,密钥通过 sm3 制备;", function (cli) {
|
||
const {sm4en3} = require("./crypto");
|
||
let key = cli.getParamValue("key")
|
||
let data = cli.getParamValue("data")
|
||
let out = sm4en3( key, data )
|
||
$logger.info( out );
|
||
});
|
||
|
||
parser.addCmdLine("sm4de3 <key> <data>", "sm4 解密,密钥通过 sm3 制备;", function (cli) {
|
||
const {sm4de3} = require("./crypto");
|
||
let key = cli.getParamValue("key")
|
||
let data = cli.getParamValue("data")
|
||
let out = sm4de3( key, data )
|
||
$logger.info( out );
|
||
});
|
||
|
||
|
||
parser.addCmdLine("pkcs7verify <sign> <data>", "验证 pkCS7 签名;", function (cli) {
|
||
const {verifyPKCS7} = require("./crypto");
|
||
let sign = cli.getParamValue("sign")
|
||
let data = cli.getParamValue("data")
|
||
let out = verifyPKCS7( sign, data )
|
||
if ( out ) {
|
||
$logger.info("验证通过")
|
||
} else {
|
||
$logger.error("验证不通过")
|
||
}
|
||
});
|
||
|
||
parser.addCmdLine("pkcs7info <sign>", "从 pkCS7 签名中提取信息(证书、公钥、签名);", function (cli) {
|
||
const {getInfoFromPKCS7} = require("./crypto");
|
||
let sign = cli.getParamValue("sign")
|
||
let out = getInfoFromPKCS7( sign )
|
||
$logger.info(' cert:');
|
||
$logger.info(' subject:', result.cert?.subjectDN);
|
||
$logger.info(' issuer:', result.cert?.issuerDN);
|
||
$logger.info(' serialNumber:', result.cert?.serialNumber);
|
||
$logger.info(' notBefore:', result.cert?.notBefore);
|
||
$logger.info(' notAfter:', result.cert?.notAfter);
|
||
$logger.info(' pem:');
|
||
$logger.info(result.cert?.pem);
|
||
$logger.info(' publicKey:');
|
||
$logger.info(result.publicKey);
|
||
$logger.info(' publicKey (hex):');
|
||
$logger.info(result.publicKeyHex);
|
||
$logger.info(' signature (hex):');
|
||
$logger.info(result.signatureHex);
|
||
});
|
||
|
||
// parser.addCmdLine("base64 <-en/-de> <data>", "base64 编解码", function (cli) {
|
||
parser.addCmdLine("base64 [-en] [-de] [-hex] <data>", "base64 编解码;", function (cli) {
|
||
let data = cli.getParamValue("data")
|
||
if ( cli.hasFlag("de") ) {
|
||
if ( cli.hasFlag("hex") ) {
|
||
$logger.info( "执行 base64 decode to hex: " );
|
||
$logger.info( convutil.base64ToHex( data ) );
|
||
} else {
|
||
$logger.info( "执行 base64 decode to string: " );
|
||
$logger.info( convutil.base64ToString( data ) );
|
||
}
|
||
} else {
|
||
if ( cli.hasFlag("hex") ) {
|
||
$logger.info( "执行 hex encode to base64: " );
|
||
$logger.info( convutil.hexToBase64( data ) );
|
||
} else {
|
||
$logger.info( "执行 string encode to base64: " );
|
||
$logger.info( convutil.stringToBase64( data ) );
|
||
}
|
||
}
|
||
});
|
||
|
||
|
||
parser.addCmdLine("touch [-d] <file_name>", "文件时间修改为当前时间;", function (cli) {
|
||
const fs = require('fs');
|
||
const path = cli.getParamValue("file_name")
|
||
// 获取当前日期时间
|
||
const now = new Date();
|
||
// 修改文件的访问时间和修改时间为当前时间
|
||
fs.utimes(path, now, now, (err) => {
|
||
if (err) {
|
||
$logger.error('修改文件时间出错:', err);
|
||
} else {
|
||
$logger.info('文件时间修改成功');
|
||
}
|
||
});
|
||
});
|
||
|
||
parser.addCmdLine("replace [-d] <file_name> <re1> <re2>", "文件内容正则替换;", function (cli) {
|
||
$logger.info( "暂未实现" );
|
||
});
|
||
|
||
parser.addCmdLine("crlf [-d] [-r] [--path] [--filter-name] [--filter-path] <crlf:{CRLF,CR,LF,\\r\\n,\\r,\\n}>", "回车一致化", function (cli) {
|
||
$logger.info( "暂未实现" );
|
||
});
|
||
|
||
parser.addCmdLine("tcpc [-d] [-x] [--host] [--ip] [--port] [--headlen] [--timeout] [--filepath]", "tcp 报文发收", function (cli) {
|
||
$logger.info( "暂未实现" );
|
||
});
|
||
|
||
async function main(){
|
||
|
||
try {
|
||
let cmd = parser.parse(process.argv.slice(2))
|
||
if ( ! cmd ) {
|
||
console.log( parser.help() )
|
||
} else {
|
||
$logger.info(`执行命令 ${cmd.cmdline.cmd}`)
|
||
if ( cmd.canEval() ){
|
||
await cmd.eval()
|
||
} else {
|
||
console.log( parser.help() )
|
||
}
|
||
}
|
||
} catch ( e ) {
|
||
console.error( e )
|
||
}
|
||
}
|
||
|
||
main()
|