386 lines
12 KiB
JavaScript
386 lines
12 KiB
JavaScript
/**
|
||
* kit cli 注册和调用执行
|
||
*/
|
||
require("./init")
|
||
const { CliCmdParser } = require("../../argv")
|
||
const parser = new CliCmdParser("kit V" + $version);
|
||
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 )
|
||
|
||
|
||
// 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", "平台信息", function (cli) {
|
||
// 调用主函数并打印结果
|
||
getAllDeviceInfo().then(info => {
|
||
console.log('Device Information:');
|
||
var 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]})
|
||
}
|
||
for ( let k in info.disk ){
|
||
if ( k.endsWith("Size") ) {
|
||
continue;
|
||
}
|
||
table.push({ '项' : 'Disk' + k, '值' : info.disk[k]})
|
||
}
|
||
|
||
console.table(table);
|
||
console.log( JSON.stringify(info, null, 4));
|
||
}).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("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(" ") )
|
||
$logger.info("\n" + ret.data.ip)
|
||
} else {
|
||
$logger.error("获取失败")
|
||
}
|
||
});
|
||
|
||
|
||
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("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()
|