Compare commits

..

75 Commits

Author SHA1 Message Date
9ea0224fd4 feat: ssh.rs 2026-01-02 20:09:33 +08:00
daed8578e2 feat: update ssh.rs 2026-01-02 19:46:27 +08:00
0b602d3e16 feat: ssh.rs 2026-01-02 19:23:18 +08:00
1ccc16865d feat: ssh.rs 2026-01-02 19:13:20 +08:00
22fc4a36ae feat: add ssh.rs 2026-01-02 19:00:20 +08:00
caa1d83958 feat: update keyring.rs 2026-01-02 16:17:29 +08:00
0db169932b feat: update keyring.rs 2026-01-02 15:56:30 +08:00
382bd834f6 feat: update connect.rs 2025-10-21 13:32:22 +08:00
8b0b289eb9 feat: udpate keyring.rs 2025-10-20 00:09:39 +08:00
bee137c563 feat: udpate connect.rs 2025-10-19 23:03:20 +08:00
1b5db69a73 feat: update connect-rs, add keyring-rs 2025-10-19 15:26:12 +08:00
2ea46e6df2 feat: update osssendfile-rs 2025-10-15 19:38:49 +08:00
b0d9cbfb61 feat: update osssendfile 2025-10-13 23:33:56 +08:00
5d215d3ca3 feat: update connect-rs 2025-10-13 23:13:48 +08:00
c9928c65fe feat: add connect-rs 2025-10-13 22:58:53 +08:00
85e442f114 feat: update osssendfilers 2025-10-10 00:24:50 +08:00
f74931f8bd feat: update script-verify.rs 2025-09-09 23:11:08 +08:00
db816cc1e1 feat: update globa.hatter.ink 2025-06-21 10:35:45 +08:00
c04dde9dcf feat: updates 2025-06-20 22:07:16 +08:00
067f76b5ff feat: add file-forma.rs 2025-05-31 00:26:48 +08:00
1657f3a955 feat: update osssendfile-rs 2025-04-04 08:50:46 +08:00
09a6a65de6 feat: sign scripts 2025-01-23 23:50:39 +08:00
c2af7ec23b feat: script-sign-rs script-verify-rs 2025-01-23 00:25:34 +08:00
912332da97 feat: update script-sign-rs 2025-01-22 01:44:21 +08:00
0ed00c14e2 feat: add publish_date and update_time 2025-01-19 15:43:04 +08:00
968309fff5 feat:update xattr-rs 2025-01-18 14:41:50 +08:00
d20f13c06b feat: add script_sub_dir 2025-01-18 13:00:41 +08:00
b04013c325 feat: add back update-meta-v1.rs 2025-01-18 12:47:28 +08:00
8b6cedb20d feat: fix single script 404 2025-01-18 12:42:39 +08:00
6b5f301086 feat: script-meta-v2 2025-01-18 12:41:12 +08:00
709c4b1e72 feat: add xattr-rs 2025-01-18 11:23:57 +08:00
c1bc33ef2d feat: script-sign.rs now works 2025-01-05 21:54:26 +08:00
7ed829e794 feat: poc works 2025-01-05 18:57:21 +08:00
899d3fcdbe feat: poc works 2025-01-05 18:55:40 +08:00
cbcc25a49f feat: poc works 2025-01-05 18:49:34 +08:00
d26a138df6 feat: add script-sign-rs, not ready 2025-01-05 18:08:09 +08:00
35351b097f feat: support fmt 2024-12-29 23:02:28 +08:00
0fe7b843a2 feat: support fmt 2024-12-29 23:02:03 +08:00
795265ef97 feat: update makepassword-rs 2024-12-29 13:05:27 +08:00
6d11b30ec9 feat: update post-rs 2024-12-29 12:47:47 +08:00
4d3e0341ff feat: current-time.rs 2024-12-29 12:34:22 +08:00
a3707f6d97 feat: add current-time-rs 2024-12-29 00:16:59 +08:00
8eddfc02e7 feat: upate derparse.rs 2024-09-14 01:12:40 +08:00
b927b727ad feat: upate derparse.rs 2024-09-14 01:12:12 +08:00
ccca8e66bd feat: update osssendfile-rs 2024-08-31 20:46:10 +08:00
2de76ade32 feat: update osssendfile-rs, check sha256 2024-08-25 10:36:57 +08:00
b21964eb41 feat: update osssendfile-rs, check sha256 2024-08-25 10:32:19 +08:00
a1ff0294e1 feat: osssendfile-rs 2024-08-24 22:23:32 +08:00
160f34456c feat: osssendfile-rs 2024-08-24 22:22:29 +08:00
cda5e9197d feat: updates 2024-08-24 14:56:08 +08:00
bb5f88a775 feat: update osssendfile-rs 2024-08-24 01:26:23 +08:00
e2329d96a6 feat: update osssendfile-rs 2024-08-22 00:15:55 +08:00
f3275a5421 feat: add osssendfile-rs 2024-08-21 23:42:32 +08:00
589ffd47cc feat: add update meta rs, and script-meta.json 2024-08-17 22:22:38 +08:00
ff0699bdd1 feat: update derparse-rs denpendencies 2024-08-11 15:58:09 +08:00
039a195573 feat: update derparser-rs 2024-08-11 15:50:21 +08:00
43922cda4a feat: olt ask 2023-12-17 15:33:21 +08:00
5a27b18a92 feat: generate olt in 10 min 2023-12-17 15:24:25 +08:00
800100e5c2 feat: add derparse-rs 2023-11-26 00:05:20 +08:00
558c309c91 feat: add derparse-rs 2023-11-26 00:02:25 +08:00
8666bf8a51 feat: add rpm-read-rs 2023-06-22 21:31:02 +08:00
f845518b40 feat: add -R or --rm-enc-file 2023-06-22 21:28:18 +08:00
2bbc62e6ea feat: more content types 2023-03-05 22:55:49 +08:00
d874cbd0a4 feat: secfile 2023-03-05 18:00:57 +08:00
8dda36da48 chore: format 2023-03-05 17:44:24 +08:00
0179b22e17 feat: fix typo 2023-03-05 17:40:19 +08:00
52111db2f8 feat: opt file memory 2023-03-05 17:39:05 +08:00
ad398ba543 feat: add post-rs 2023-03-05 14:19:43 +08:00
7e250b54b1 feat: secfile content-type 2023-03-05 13:04:09 +08:00
b1e951847a feat: post.rs 2023-03-05 11:57:43 +08:00
b2d46bf5a2 feat: add post-rs 2023-03-05 00:39:13 +08:00
6dca80b8c5 feat: add rpm-read-rs 2023-02-26 14:35:21 +08:00
144667cb76 feat: add bit-address-rs 2023-02-24 23:12:53 +08:00
91130596cb feat: add makepassword-rs 2023-02-24 22:55:32 +08:00
00e6b55d34 feat: add makepassword-rs 2023-02-24 22:55:14 +08:00
61 changed files with 15586 additions and 4 deletions

218
bit-address-rs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,218 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bit-address-rs"
version = "0.1.0"
dependencies = [
"bs58",
"digest",
"hex",
"num_cpus",
"rand",
"ripemd",
"secp256k1",
"sha2",
]
[[package]]
name = "block-buffer"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
dependencies = [
"generic-array",
]
[[package]]
name = "bs58"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
[[package]]
name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cpufeatures"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "generic-array"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "num_cpus"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "ripemd"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f"
dependencies = [
"digest",
]
[[package]]
name = "secp256k1"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894"
dependencies = [
"rand",
"secp256k1-sys",
]
[[package]]
name = "secp256k1-sys"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "642a62736682fdd8c71da0eb273e453c8ac74e33b9fb310e22ba5b03ec7651ff"
dependencies = [
"cc",
]
[[package]]
name = "sha2"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "typenum"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"

16
bit-address-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,16 @@
[package]
name = "bit-address-rs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bs58 = "0.4.0"
digest = "0.10.6"
hex = "0.4.3"
num_cpus = "1.15.0"
rand = "0.8.5"
ripemd = "0.1.3"
secp256k1 = { version = "0.26.0", features = ["rand"] }
sha2 = "0.10.6"

120
bit-address-rs/src/main.rs Normal file
View File

@@ -0,0 +1,120 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! bs58 = "0.4.0"
//! digest = "0.10.6"
//! hex = "0.4.3"
//! num_cpus = "1.15.0"
//! rand = "0.8.5"
//! ripemd = "0.1.3"
//! secp256k1 = { version = "0.26.0", features = ["rand"] }
//! sha2 = "0.10.6"
//! ```
use std::{sync::{Arc, Mutex}, thread};
use digest::{Digest};
use rand::rngs::OsRng;
use ripemd::Ripemd160;
use secp256k1::{PublicKey, Secp256k1};
use sha2::Sha256;
fn main() {
let args = std::env::args();
if args.len() <= 1 {
println!("[ERROR] Need at least one argument, e.g. 1Hatter 1UTF8 ...");
return;
}
let continue_on_found = std::env::var("CONTINUE_ON_FOUND")
.map(|c| c.to_lowercase())
.map(|c| c == "1" || c == "true" || c == "yes" || c == "on")
.unwrap_or_else(|_| false);
let prefixes: Vec<String> = args.skip(1).collect();
println!("Prefixes: {:?}", prefixes);
if continue_on_found {
println!("CONTINUE_ON_FOUND is ON");
} else {
println!("CONTINUE_ON_FOUND is OFF");
}
let loop_count = std::env::var("LOOP_COUNT")
.map(|c| c.parse::<u64>())
.unwrap_or_else(|_| Ok(10_000_000_u64))
.unwrap_or_else(|_| 10_000_000_u64);
println!("LOOP_COUNT={}", loop_count);
let num_of_vcpus = num_cpus::get();
let num_of_phycpus = num_cpus::get_physical();
println!("You have {} vCPUs, from {} phyCPUs", num_of_vcpus, num_of_phycpus);
let concurrent_count = std::env::var("CONCURRENT_COUNT")
.map(|c| c.parse::<u64>())
.unwrap_or_else(|_| Ok(num_of_phycpus as u64))
.unwrap_or_else(|_| 1_u64);
println!("CONCURRENT_COUNT={}", concurrent_count);
let stop_flag = Arc::new(Mutex::new(false));
let mut handles = vec![];
for ind in 0..concurrent_count {
println!("- Running task {} of {}", ind, concurrent_count);
let the_stop_flag = Arc::clone(&stop_flag);
let prefixes = prefixes.clone();
let child = thread::spawn(move || {
run_one_task(prefixes, continue_on_found, loop_count, ind, the_stop_flag);
});
handles.push(child);
}
while let Some(h) = handles.pop() {
h.join().unwrap();
}
println!("Finished!");
}
fn run_one_task(prefixes: Vec<String>, continue_on_found: bool, loop_count: u64, ind: u64, the_stop_flag: Arc<Mutex<bool>>) {
let secp = Secp256k1::new();
let mut rng = OsRng::default();
for i in 0..loop_count {
let (secret_key, public_key) = secp.generate_keypair(&mut rng);
let s = make_btc_address(&public_key);
if i % 1_000 == 0 {
if *the_stop_flag.lock().unwrap() {
return;
}
if i > 0 && i % 100_000 == 0 {
println!("> {} - {}", ind, i);
}
}
if prefixes.iter().any(|p| s.starts_with(p)) {
println!(">> {}\n{}", s, secret_key.display_secret());
if !continue_on_found {
*the_stop_flag.lock().unwrap() = true;
break;
}
}
}
}
fn make_btc_address(public_key: &PublicKey) -> String {
let public_key_bytes = public_key.serialize_uncompressed().to_vec();
let riphemd160_sha256_pub_key = calc_ripemd160(&calc_sha256(&public_key_bytes));
let mut btc_addr = Vec::<u8>::with_capacity(25);
btc_addr.push(0x00 as u8);
btc_addr.extend_from_slice(&riphemd160_sha256_pub_key);
let checksum = &calc_sha256(&calc_sha256(&btc_addr))[0..4];
btc_addr.extend_from_slice(checksum);
bs58::encode(&btc_addr).into_string()
}
#[inline]
fn calc_sha256(i: &[u8]) -> Vec<u8> {
let mut hasher = Sha256::default();
hasher.update(i);
hasher.finalize().to_vec()
}
#[inline]
fn calc_ripemd160(i: &[u8]) -> Vec<u8> {
let mut hasher = Ripemd160::default();
hasher.update(i);
hasher.finalize().to_vec()
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234308+08:00.MEUCIDhS7bXajTBtRd/QYF7k
// m091OGpR1rKuyCyufWhnwzjkAiEAupUjM6p+vPEkHQi3Pzv4kw6Gz46HXQnOOAtMuQCDQcw=

View File

@@ -188,3 +188,5 @@ fn install_commit_msg(force: bool) {
success!("Install commit-msg to repo succeed!");
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234924+08:00.MEYCIQDqMMcZsH7TgXwccBBc
// Ix+3r9KFeClL6DSDmk46XcARbAIhAOaTP0bCeJh4oapeX8dI0aA2kScyckQ3jU1WQ8iq/75X

2039
connect-rs/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

13
connect-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "connect-rs"
version = "0.1.0"
edition = "2024"
[dependencies]
clap = { version = "4.5.48", features = ["derive"] }
keyring = { version = "3.6.3", features = ["apple-native"] }
reqwest = { version = "0.12.23", features = ["blocking"] }
rust_util = "0.6.50"
serde_json = "1.0.145"
rust-crypto-hatter-fork = "0.2"

289
connect-rs/src/main.rs Executable file
View File

@@ -0,0 +1,289 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! clap = { version = "4.5.48", features = ["derive"] }
//! keyring = { version = "3.6.3", features = ["apple-native"] }
//! reqwest = { version = "0.12.23", features = ["blocking"] }
//! rust_util = "0.6.50"
//! serde_json = "1.0.145"
//! rust-crypto-hatter-fork = "0.2"
//! ```
use clap::{Args, Parser, Subcommand};
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use keyring::Entry;
use rust_util::{
failure, iff, information, opt_result, simple_error, success, util_cmd, util_env, util_file,
XResult,
};
use serde_json::Value;
use std::fs;
use std::process::Command;
const PAC_FILE: &str = "__proxy__.pac";
const ENV_CONNECT_PAC_FILE_PATH: &str = "CONNECT_PAC_FILE_PATH";
const KEYRING_SERVICE: &str = "hatter.ink";
const KEYRING_USER: &str = "pac_auth_token";
const NET_WORK_SETUP: &str = "networksetup";
const WIFI: &str = "Wi-Fi";
#[derive(Debug, Parser)]
#[command(name = "connect-rs", bin_name = "connect.rs")]
#[command(about = "Connect to the world", long_about = None)]
struct ConnectArgs {
#[command(subcommand)]
command: Commands,
}
#[derive(Debug, Subcommand)]
enum Commands {
/// Connect
#[command(short_flag = 'c')]
Connect(CmdConnect),
/// Disconnect
#[command(short_flag = 'd')]
Disconnect,
/// Update
#[command(short_flag = 'u')]
Update,
/// Add domain
#[command(short_flag = 'a')]
AddDomain(CmdAddDomain),
}
#[derive(Debug, Args)]
pub struct CmdConnect {
/// Update
#[arg(long)]
pub update: bool,
}
#[derive(Debug, Args)]
pub struct CmdAddDomain {
/// Domains (split by ',')
#[arg(long, short = 'd')]
pub domains: String,
/// Not GFW
#[arg(long)]
pub not_gfw: bool,
/// Reconnect
#[arg(long, short = 'r')]
pub reconnect: bool,
}
fn main() {
let args = ConnectArgs::parse();
match args.command {
Commands::Connect(cmd) => {
if cmd.update {
update_pac_file_ignore_error();
}
turn_proxy_off();
run_command(
NET_WORK_SETUP,
&["-setautoproxyurl", WIFI, "http://localhost:8888/pac"],
"setautoproxyurl proxy",
);
}
Commands::Disconnect => {
turn_proxy_off();
}
Commands::Update => {
update_pac_file_ignore_error();
}
Commands::AddDomain(cmd) => match add_pac_digest(&cmd.domains, !cmd.not_gfw) {
Ok(_) => {
success!("Add domain successfully");
if cmd.reconnect {
turn_proxy_off();
turn_proxy_on();
}
}
Err(e) => failure!("Add domain failed: {}", e),
},
}
}
fn update_pac_file_ignore_error() {
match update_pac_file() {
Ok(_) => success!("Update proxy successfully"),
Err(error) => failure!("Update proxy failed: {}", error),
}
}
fn update_pac_file() -> XResult<()> {
let digest = get_pac_digest()?;
let pac_file_full_path = get_pac_file_full_path();
let pac_file_content = util_file::read_file_content(&pac_file_full_path)?;
let mut sha256 = Sha256::new();
sha256.input(pac_file_content.as_bytes());
let pac_file_digest = format!("sha256-{}", sha256.result_str());
if digest == pac_file_digest {
success!("Pac file digest matches.");
return Ok(());
}
information!(
"Pac file digest mismatch, \n - remote: {}, \n - local : {}",
digest,
pac_file_digest
);
let pac_content = get_pac_content()?;
opt_result!(
fs::write(&pac_file_full_path, pac_content),
"Write file {}, failed: {}",
&pac_file_full_path
);
success!("Pac file updated successfully.");
Ok(())
}
fn turn_proxy_on() {
run_command(
NET_WORK_SETUP,
&["-setautoproxyurl", WIFI, "http://localhost:8888/pac"],
"setautoproxyurl proxy",
);
}
fn turn_proxy_off() {
run_command(
NET_WORK_SETUP,
&["-setautoproxystate", WIFI, "off"],
"setautoproxystate off",
);
run_command(
NET_WORK_SETUP,
&["-setsocksfirewallproxystate", WIFI, "off"],
"setsocksfirewallproxystate off",
);
}
fn run_command(program: &str, args: &[&str], message: &str) {
let mut c2 = Command::new(program);
c2.args(args);
match util_cmd::run_command_and_wait(&mut c2) {
Ok(status) => {
if status.success() {
success!("{} success", message);
} else {
failure!("{} failed: {:?}", message, status.code());
}
}
Err(e) => {
failure!("{} failed: {}", message, e);
}
}
}
fn get_pac_content() -> XResult<String> {
let auth_token = get_pac_auth_token()?;
let url = format!(
"https://hatter.ink/pac/get_pac.action?__auth_token={}",
auth_token
);
let pac_content_response =
opt_result!(reqwest::blocking::get(&url), "Get pac content failed: {}");
if pac_content_response.status().as_u16() != 200 {
return simple_error!(
"Get pac content HTTP status error: {}",
pac_content_response.status().as_u16()
);
}
let pac_content_text = opt_result!(
pac_content_response.text(),
"Get pac digest response failed: {}"
);
Ok(pac_content_text)
}
fn get_pac_file_full_path() -> String {
let connect_pac_file_path = match util_env::env_var(ENV_CONNECT_PAC_FILE_PATH) {
Some(connect_pac_file_path) => connect_pac_file_path,
None => return PAC_FILE.to_string(),
};
util_file::join_path(&connect_pac_file_path, PAC_FILE)
}
fn get_pac_digest() -> XResult<String> {
let auth_token = get_pac_auth_token()?;
let url = format!(
"https://hatter.ink/pac/get_pac.action?digest=1&__auth_token={}",
auth_token
);
let pac_digest_response =
opt_result!(reqwest::blocking::get(&url), "Get pac digest failed: {}");
if pac_digest_response.status().as_u16() != 200 {
return simple_error!(
"Get pac digest HTTP status error: {}",
pac_digest_response.status().as_u16()
);
}
let pac_digest_text = opt_result!(
pac_digest_response.text(),
"Get pac digest response failed: {}"
);
let pac_digest_value: Value = opt_result!(
serde_json::from_str(&pac_digest_text),
"Parse pac digest failed: {}"
);
if let Some(data) = pac_digest_value.get("data") {
if let Some(digest) = data.get("digest") {
match digest {
Value::String(digest) => Ok(digest.to_string()),
_ => simple_error!("Cannot get pac digest data.digest not string"),
}
} else {
simple_error!("Cannot get pac digest data.digest")
}
} else {
simple_error!("Cannot get pac digest data")
}
}
fn add_pac_digest(domains: &str, gfw: bool) -> XResult<()> {
let auth_token = get_pac_auth_token()?;
let url = format!(
"https://hatter.ink/pac/add_pac_domain.json?digest=1&__auth_token={}&type={}&domains={}",
auth_token,
iff!(gfw, "gfw", "no_gfw"),
domains
);
let pac_digest_response =
opt_result!(reqwest::blocking::get(&url), "Add domain to pac failed: {}");
if pac_digest_response.status().as_u16() != 200 {
return simple_error!(
"Get pac digest HTTP status error: {}",
pac_digest_response.status().as_u16()
);
}
Ok(())
}
fn get_pac_auth_token() -> XResult<String> {
let entry = opt_result!(
Entry::new(KEYRING_SERVICE, KEYRING_USER),
"New entry failed: {}"
);
Ok(opt_result!(
entry.get_password(),
"get password from keyring failed: {}"
))
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20251021T133159+08:00.MEQCIFEij7e8qbFLQ2oD7+uw
// mvdUy6nMUPIb/cxG6UDKm2ccAiBHgFSSqZ9DXdwPnn/yZH6vJVyqvricLpTuRApNT9g+yA==

445
current-time-rs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,445 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "cc"
version = "1.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets",
]
[[package]]
name = "clap"
version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "current-time-rs"
version = "0.1.0"
dependencies = [
"clap",
"simpledateformat",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "iana-time-zone"
version = "0.1.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "js-sys"
version = "0.3.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "proc-macro2"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "simpledateformat"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d99ace355f41f2391428701c164540ab9b0b644c0aa935f3eefe773dc0072a3e"
dependencies = [
"chrono",
"quick-error",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ae51629bf965c5c098cc9e87908a3df5301051a9e087d6f9bef5c9771ed126"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "wasm-bindgen"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

View File

@@ -0,0 +1,8 @@
[package]
name = "current-time-rs"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = { version = "4.5.23", features = ["derive"] }
simpledateformat = "0.1.4"

112
current-time-rs/src/main.rs Executable file
View File

@@ -0,0 +1,112 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! clap = { version = "4.5.23", features = ["derive"] }
//! simpledateformat = "0.1.4"
//! ```
use clap::Parser;
use std::ops::Add;
use std::process::exit;
use std::time::{Duration, SystemTime};
/// Current time
#[derive(Parser, Debug)]
#[command(version, about, long_about = None, bin_name = "current-time.rs")]
struct Args {
/// New line
#[arg(long)]
new_line: bool,
/// Add time (e.g. 1s (second), 1m (minute), 1h (hour), 1d (day), 1M (month), 1y (year) )
#[arg(short, long)]
add_time: Option<String>,
/// Output format (e.g. millis (default), s|secs)
#[arg(short, long)]
output_format: Option<String>,
/// Local time format
#[arg(long)]
local_time_format: Option<String>,
/// UTF time format
#[arg(long)]
utc_time_format: Option<String>,
}
fn main() {
let args = Args::parse();
let current_time_millis = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis();
let add_time_millis = parse_add_time(&args.add_time);
let final_time_millis = current_time_millis as i128 + add_time_millis;
let output_format = args.output_format.map(|f| f.to_lowercase());
let final_time = match output_format.as_deref() {
Some("s") | Some("secs") | Some("second") | Some("seconds") => final_time_millis / 1000,
_ => final_time_millis,
};
let mut print_time = format!("{}", final_time);
let final_system_time =
SystemTime::UNIX_EPOCH.add(Duration::from_millis(final_time_millis as u64));
if let Some(local_time_format) = &args.local_time_format {
print_time = match simpledateformat::fmt(local_time_format) {
Ok(fmt) => fmt.format_local(final_system_time),
Err(_) => {
eprintln!("Invalid local time format.");
exit(1);
}
};
} else if let Some(utc_time_format) = &args.utc_time_format {
print_time = match simpledateformat::fmt(utc_time_format) {
Ok(fmt) => fmt.format_local(final_system_time),
Err(_) => {
eprintln!("Invalid UTC time format.");
exit(1);
}
}
}
if args.new_line {
println!("{}", print_time);
} else {
print!("{}", print_time);
}
}
fn parse_add_time(add_time: &Option<String>) -> i128 {
let add_time = match add_time {
None => return 0,
Some(add_time) if add_time.len() < 2 => return 0,
Some(add_time) => add_time,
};
let add_time_chars = add_time.chars().collect::<Vec<_>>();
let add_time_number = add_time_chars[0..add_time_chars.len() - 1]
.iter()
.collect::<String>();
let last_char = add_time_chars[add_time_chars.len() - 1];
let number: i128 = match add_time_number.parse() {
Err(_e) => return 0,
Ok(number) => number,
};
let add_time_millis = match last_char {
's' => number * 1000,
'm' => number * 1000 * 60,
'h' => number * 1000 * 60 * 60,
'd' => number * 1000 * 60 * 60 * 20,
'M' => number * 1000 * 60 * 60 * 20 * 30,
'y' => number * 1000 * 60 * 60 * 20 * 365,
_ => return 0,
};
add_time_millis
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234910+08:00.MEUCIQD7FwdnfcUt7g6//wgu
// sPz5Vl/93dpOz4OCcxJiKsXAMwIgWI1+INKys7y5uvkENl7Bdj6z6r0zcaAwPht9mu+HWQk=

View File

@@ -15,7 +15,17 @@ use rust_util::{failure_and_exit, information, opt_result, success, warning, XRe
// see https://git.hatter.ink/hatter/crypto/src/branch/master/src/main/java/me/hatter/tools/crypto/stream/DecryptTool.java
fn main() -> XResult<()> {
let args: Vec<String> = std::env::args().skip(1).collect();
let mut rm_enc_file: bool = false;
let args: Vec<String> = std::env::args()
.skip(1)
.filter(|arg| {
if arg == "-R" || arg == "--rm-enc-file" {
rm_enc_file = true;
return false;
}
true
})
.collect();
if args.len() != 3 {
failure_and_exit!("crypt.rs <key-hex> <file-in> <file-out>");
}
@@ -70,9 +80,18 @@ fn main() -> XResult<()> {
opt_result!(fs::write(&file_out, decrypted), "Write file out: {}, failed: {}", file_out);
success!("Write file out succeed!");
if rm_enc_file {
information!("Remove file: {}", file_in);
if let Err(e) = fs::remove_file(file_in) {
warning!("Remove file: {} failed: {}", file_in, e);
}
}
Ok(())
}
fn is_file_exists(file: &str) -> bool {
fs::metadata(file).is_ok()
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234903+08:00.MEUCIH/RghKp5HfEexqUP2zj
// wO1erLygRPREcrq8iRUEbKqaAiEAuaFVR13QfTCcdpxG/nQMdF0WaU1hZ4/P5VpPKafL2QE=

263
derparse-rs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,263 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "asn1-rs"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0"
dependencies = [
"asn1-rs-derive",
"asn1-rs-impl",
"displaydoc",
"nom",
"num-traits",
"rusticata-macros",
"thiserror",
]
[[package]]
name = "asn1-rs-derive"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"synstructure",
]
[[package]]
name = "asn1-rs-impl"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "autocfg"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "der-parser"
version = "8.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e"
dependencies = [
"asn1-rs",
"displaydoc",
"nom",
"num-traits",
"rusticata-macros",
]
[[package]]
name = "derparse-rs"
version = "0.1.0"
dependencies = [
"base64 0.21.7",
"der-parser",
"hex",
"oid-registry",
"pem",
]
[[package]]
name = "displaydoc"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.73",
]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "oid-registry"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff"
dependencies = [
"asn1-rs",
]
[[package]]
name = "pem"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae"
dependencies = [
"base64 0.22.1",
"serde",
]
[[package]]
name = "proc-macro2"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rusticata-macros"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632"
dependencies = [
"nom",
]
[[package]]
name = "serde"
version = "1.0.206"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b3e4cd94123dd520a128bcd11e34d9e9e423e7e3e50425cb1b4b1e3549d0284"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.206"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fabfb6138d2383ea8208cf98ccf69cdfb1aff4088460681d84189aa259762f97"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.73",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "837a7e8026c6ce912ff01cefbe8cafc2f8010ac49682e2a3d9decc3bce1ecaaf"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "synstructure"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"unicode-xid",
]
[[package]]
name = "thiserror"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.73",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"

15
derparse-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,15 @@
[package]
name = "derparse-rs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
base64 = "0.21.5"
der-parser = "8.2.0"
hex = "0.4.3"
oid-registry = { version = "0.6.1", features = ["x962", "x509", "crypto", "pkcs1", "pkcs12", "pkcs7", "pkcs9", "kdf", "ms_spc", "nist_algs"] }
pem = "3.0.4"

224
derparse-rs/src/main.rs Executable file
View File

@@ -0,0 +1,224 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! base64 = "0.21.5"
//! der-parser = "8.2.0"
//! hex = "0.4.3"
//! oid-registry = { version = "0.6.1", features = ["x962", "x509", "crypto", "pkcs1", "pkcs12", "pkcs7", "pkcs9", "kdf", "ms_spc", "nist_algs"] }
//! pem = "3.0.4"
//! ```
use std::fs;
use std::str::FromStr;
use base64::Engine;
use der_parser::ber::{BerObject, BerObjectContent};
use der_parser::Oid;
use oid_registry::{OidEntry, OidRegistry};
use oid_registry::asn1_rs::oid;
use pem::Pem;
fn main() {
let args = std::env::args().skip(1).collect::<Vec<_>>();
if args.is_empty() {
println!("Require Args.");
return;
}
let arg1 = &args[0];
let content = try_load_and_parse(arg1);
let ber_obj = match der_parser::parse_ber(&content) {
Ok(ber_obj) => ber_obj.1,
Err(e) => panic!("Parse DER failed: {}", e),
};
let oid_reg = build_oid_register();
print(&oid_reg, 0, &ber_obj);
}
fn try_load_and_parse(arg1: &str) -> Vec<u8> {
match fs::read(arg1) {
Ok(file_content) => match String::from_utf8(file_content.clone()) {
Ok(file_content_string) => try_parse(&file_content_string),
Err(_) => file_content,
}
Err(_) => try_parse(arg1)
}
}
fn try_parse(arg1: &str) -> Vec<u8> {
if arg1.contains("-----") {
let pem = Pem::from_str(arg1).expect("Parse pem failed.");
return pem.contents().to_vec();
}
let arg1 = arg1.replace("\n", "").replace("\r", "");
if let Ok(h) = hex::decode(&arg1) {
return h;
}
if let Ok(h) = base64::engine::general_purpose::STANDARD.decode(&arg1) {
return h;
}
if let Ok(h) = base64::engine::general_purpose::STANDARD_NO_PAD.decode(&arg1) {
return h;
}
if let Ok(h) = base64::engine::general_purpose::URL_SAFE.decode(&arg1) {
return h;
}
if let Ok(h) = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(&arg1) {
return h;
}
if let Ok(content) = fs::read(&arg1) {
return content;
}
panic!("Parse arg failed: {}", arg1);
}
fn print(oid_reg: &OidRegistry, depth: usize, ber_obj: &BerObject) {
let prefix = " ".repeat(depth);
match &ber_obj.content {
BerObjectContent::EndOfContent => {
println!("{}END OF CONTENT", prefix);
}
BerObjectContent::Boolean(b) => {
println!("{}BOOLEAN: {}", prefix, b);
}
BerObjectContent::Integer(i) => {
println!("{}INTEGER: {}", prefix, hex::encode(i));
}
BerObjectContent::BitString(u, b) => {
if let Ok(ber_obj) = der_parser::parse_ber(&b.data) {
println!("{}BIT STRING[{}]", prefix, u);
print(&oid_reg, depth + 1, &ber_obj.1);
} else {
println!("{}BIT STRING[{}] - {}", prefix, u, hex::encode(b.data));
}
}
BerObjectContent::OctetString(s) => {
if let Ok(ber_obj) = der_parser::parse_ber(s) {
println!("{}OCTET STRING", prefix);
print(&oid_reg, depth + 1, &ber_obj.1);
} else {
println!("{}OCTET STRING: {}", prefix, hex::encode(s));
}
}
BerObjectContent::Null => {
println!("{}NULL", prefix);
}
BerObjectContent::Enum(e) => {
println!("{}ENUM: {}", prefix, e);
}
BerObjectContent::OID(oid) => {
println!("{}OID: {}{}", prefix, oid, format_oid(oid_reg, oid));
}
BerObjectContent::RelativeOID(oid) => {
println!("{}RELATIVE OID: {}{}", prefix, oid, format_oid(oid_reg, oid));
}
BerObjectContent::NumericString(s) => {
println!("{}NUMERIC STRING: {}", prefix, s);
}
BerObjectContent::VisibleString(s) => {
println!("{}VISIBLE STRING: {}", prefix, s);
}
BerObjectContent::PrintableString(s) => {
println!("{}PRINTABLE STRING: {}", prefix, s);
}
BerObjectContent::IA5String(s) => {
println!("{}IA5 STRING: {}", prefix, s);
}
BerObjectContent::UTF8String(s) => {
println!("{}UTF8 STRING: {}", prefix, s);
}
BerObjectContent::T61String(s) => {
println!("{}T61 STRING: {}", prefix, s);
}
BerObjectContent::VideotexString(s) => {
println!("{}VIDEOTEX STRING: {}", prefix, s);
}
BerObjectContent::BmpString(s) => {
println!("{}BMP STRING: {}", prefix, s);
}
BerObjectContent::UniversalString(s) => {
println!("{}UNIVERSAL STRING: {}", prefix, hex::encode(s));
}
BerObjectContent::GraphicString(s) => {
println!("{}GRAPHIC STRING: {}", prefix, s);
}
BerObjectContent::GeneralString(s) => {
println!("{}GENERAL STRING: {}", prefix, s);
}
BerObjectContent::ObjectDescriptor(d) => {
println!("{}OBJECT DESCRIPTOR: {}", prefix, d);
}
BerObjectContent::Sequence(ber_objects) => {
println!("{}SEQUENCE {{", prefix);
for b in ber_objects {
print(oid_reg, depth + 1, b);
}
println!("{}}}", prefix);
}
BerObjectContent::Set(ber_objects) => {
println!("{}SET {{", prefix);
for b in ber_objects {
print(oid_reg, depth + 1, b);
}
println!("{}}}", prefix);
}
BerObjectContent::UTCTime(t) => {
println!("{}UTC TIME: {}", prefix, t);
}
BerObjectContent::GeneralizedTime(t) => {
println!("{}GENERALIZED TIME: {}", prefix, t);
}
BerObjectContent::Optional(o) => {
println!("{}OPTIONAL {{", prefix);
match o {
None => { println!("{} NONE", prefix) }
Some(o) => {
print(oid_reg, depth + 1, o);
}
}
println!("{}}}", prefix);
}
BerObjectContent::Tagged(c, t, o) => {
println!("{}TAGGED class={} tag={} {{", prefix, c, t);
print(oid_reg, depth + 1, o);
println!("{}}}", prefix);
}
BerObjectContent::Unknown(u) => {
let tag = u.header.tag().0;
if let Ok(ber_obj) = der_parser::parse_ber(&u.data) {
println!("{}[{}]", prefix, tag);
print(&oid_reg, depth + 1, &ber_obj.1);
} else {
println!("{}[{}] {}", prefix, tag, hex::encode(&u.data));
}
}
}
}
fn format_oid(oid_reg: &OidRegistry, oid: &Oid) -> String {
match oid_reg.get(oid) {
None => "".to_string(),
Some(e) => format!(" // {} ({})", e.sn(), e.description())
}
}
fn build_oid_register() -> OidRegistry<'static> {
let mut oid_reg = OidRegistry::default()
.with_pkcs1()
.with_pkcs7()
.with_pkcs9()
.with_pkcs12()
.with_x509()
.with_x962()
.with_kdf()
.with_ms_spc()
.with_nist_algs();
// more OIDs, https://site.hatter.ink/asn1js/oids.js
oid_reg.insert(oid!(1.2.156.10197.1.301), OidEntry::new("sm2ECC", "China GM Standards Committee"));
oid_reg
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234846+08:00.MEQCIFHPcCDQxGpDLOiJakfD
// lZdGpGNG1/n6nc1qYfKv/pq8AiAi0M9NPn33bJx0Z/tEELWuRKzffKj+5qN855cdSPQIxA==

216
file-format-rs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,216 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "bitflags"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "file-format"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ff8badf6e72ff15e42c9ade15d01375837173b17d10c228ab41d821082619db"
[[package]]
name = "file-format-rs"
version = "0.1.0"
dependencies = [
"file-format",
"rust_util",
]
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "rust_util"
version = "0.6.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bca5d3493eb29d08dc76ee784a78723fe366fec5dfe67ab37da9d50fb868f7c"
dependencies = [
"lazy_static",
"libc",
"term",
"term_size",
]
[[package]]
name = "rustversion"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@@ -0,0 +1,8 @@
[package]
name = "file-format-rs"
version = "0.1.0"
edition = "2024"
[dependencies]
file-format = { version = "0.27.0", features = ["reader"] }
rust_util = "0.6.47"

38
file-format-rs/src/main.rs Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! file-format = { version = "0.27.0", features = ["reader"] }
//! rust_util = { version = "0.6" }
//! ```
use file_format::FileFormat;
use rust_util::{failure_and_exit, success, warning};
fn main() {
let filenames = std::env::args().skip(1).collect::<Vec<_>>();
if filenames.is_empty() {
failure_and_exit!("There are no filenames!")
}
for filename in &filenames {
let file_format = match FileFormat::from_file(filename) {
Ok(file_format) => file_format,
Err(e) => {
warning!("Read file: {}, failed: {}", filename, e);
continue;
}
};
success!("File: {}", filename);
println!("Name : {}", file_format.name());
if let Some(short_name) = file_format.short_name() {
println!("Short name : {}", short_name);
}
println!("Kind : {:?}", file_format.kind());
println!("Extension : {}", file_format.extension());
println!("Media type : {}", file_format.media_type());
}
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250531T002509+08:00.MEQCIGgJxc6Zw3eTviQTWg0Q
// fTekVUxKIE/Q6W18wlEGleeSAiBGBDCOQbwknbHIxQrb6qe+nfOydjB0ewy4T5fSQQBcBA==

View File

@@ -1,4 +1,18 @@
bit-address-rs
commit-msg-rs
connect-rs
current-time-rs
decrypt-rs
derparse-rs
file-format-rs
keyring-rs
makepassword-rs
myip-rs
osssendfile-rs
post-rs
rpm-read-rs
script-sign-rs
script-verify-rs
ssh-rs
sync-rs
xattr-rs

796
keyring-rs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,796 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anstream"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
dependencies = [
"windows-sys 0.60.2",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.60.2",
]
[[package]]
name = "bitflags"
version = "2.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "clap"
version = "4.5.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.60.2",
]
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "home"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "keyring"
version = "3.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eebcc3aff044e5944a8fbaf69eb277d11986064cba30c468730e8b9909fb551c"
dependencies = [
"log",
"security-framework 2.11.1",
"security-framework 3.5.1",
"zeroize",
]
[[package]]
name = "keyring-rs"
version = "0.1.0"
dependencies = [
"clap",
"keyring",
"pinentry-util",
"rust_util",
"serde",
"serde_json",
"zeroizing-alloc",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "libredox"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "log"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]]
name = "memchr"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "percent-encoding"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "pinentry"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1ecb857a7b11a03e8872c704d0a1ae1efc20533b3be98338008527a1928ffa6"
dependencies = [
"log",
"nom",
"percent-encoding",
"secrecy",
"which",
"zeroize",
]
[[package]]
name = "pinentry-util"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4273c4b215a6b01462534af2a3254dea0031bf95e3731a05d5f1d17287b3ebcd"
dependencies = [
"pinentry",
"rpassword",
"secrecy",
"zeroize",
]
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "rpassword"
version = "7.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66d4c8b64f049c6721ec8ccec37ddfc3d641c4a7fca57e8f2a89de509c73df39"
dependencies = [
"libc",
"rtoolbox",
"windows-sys 0.59.0",
]
[[package]]
name = "rtoolbox"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7cc970b249fbe527d6e02e0a227762c9108b2f49d81094fe357ffc6d14d7f6f"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "rust_util"
version = "0.6.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01736dfb1c97fec6b874d4939aac6db3b748c61cfd62183c7b80c4f1db003635"
dependencies = [
"lazy_static",
"libc",
"term",
"term_size",
]
[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "secrecy"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a"
dependencies = [
"zeroize",
]
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags",
"core-foundation 0.9.4",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework"
version = "3.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef"
dependencies = [
"bitflags",
"core-foundation 0.10.1",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.145"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
"serde_core",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets 0.53.5",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
dependencies = [
"windows-link",
"windows_aarch64_gnullvm 0.53.1",
"windows_aarch64_msvc 0.53.1",
"windows_i686_gnu 0.53.1",
"windows_i686_gnullvm 0.53.1",
"windows_i686_msvc 0.53.1",
"windows_x86_64_gnu 0.53.1",
"windows_x86_64_gnullvm 0.53.1",
"windows_x86_64_msvc 0.53.1",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "zeroize"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
[[package]]
name = "zeroizing-alloc"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebff5e6b81c1c7dca2d0bd333b2006da48cb37dbcae5a8da888f31fcb3c19934"

13
keyring-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "keyring-rs"
version = "0.1.0"
edition = "2024"
[dependencies]
clap = { version = "4.5.49", features = ["derive"] }
keyring = { version = "3.6.3", features = ["apple-native"] }
pinentry-util = "0.1.1"
rust_util = "0.6.50"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.145"
zeroizing-alloc = "0.1.0"

140
keyring-rs/src/main.rs Executable file
View File

@@ -0,0 +1,140 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! clap = { version = "4.5.48", features = ["derive"] }
//! keyring = { version = "3.6.3", features = ["apple-native"] }
//! rust_util = "0.6.50"
//! pinentry-util = "0.1.1"
//! serde = { version = "1.0.228", features = ["derive"] }
//! serde_json = "1.0.145"
//! zeroizing-alloc = "0.1.0"
//! ```
use clap::{Args, Parser, Subcommand};
use keyring::Entry;
use rust_util::{opt_result, success, XResult};
use std::collections::BTreeMap;
use zeroizing_alloc::ZeroAlloc;
#[global_allocator]
static ALLOC: ZeroAlloc<std::alloc::System> = ZeroAlloc(std::alloc::System);
#[derive(Debug, Parser)]
#[command(name = "keyring-rs", bin_name = "keyring.rs")]
#[command(about = "Keyring util", long_about = None)]
struct ConnectArgs {
#[command(subcommand)]
command: Commands,
}
#[derive(Debug, Subcommand)]
enum Commands {
/// Connect
#[command(short_flag = 's')]
Set(CmdSet),
/// Disconnect
#[command(short_flag = 'g')]
Get(CmdGet),
}
#[derive(Debug, Args)]
pub struct CmdSet {
/// Service (optional)
#[arg(long, short = 'S')]
pub service: Option<String>,
/// User service:user when service is optional
#[arg(long, short = 'U')]
pub user: String,
/// Password
#[arg(long, short = 'P')]
pub password: Option<String>,
}
#[derive(Debug, Args)]
pub struct CmdGet {
/// Service
#[arg(long, short = 'S')]
pub service: Option<String>,
/// User service:user when service is optional
#[arg(long, short = 'U')]
pub user: String,
// JSON output
#[arg(long)]
pub json: bool,
// Raw output
#[arg(long, short = 'R')]
pub raw: bool,
}
pub struct KeyringKey {
pub service: String,
pub user: String,
}
impl KeyringKey {
fn from(service: &str, user: &str) -> Self {
Self {
service: service.to_string(),
user: user.to_string(),
}
}
fn parse_key(service: &Option<String>, user: &str) -> KeyringKey {
match service {
Some(service) => KeyringKey::from(service, user),
None => {
let user_parts = user.split(":").collect::<Vec<_>>();
if user_parts.len() != 2 {
KeyringKey::from("keyring-service", user)
} else {
KeyringKey::from(user_parts[0], user_parts[1])
}
}
}
}
}
fn main() -> XResult<()> {
let args = ConnectArgs::parse();
match args.command {
Commands::Set(cmd_set) => {
let keyring_key = KeyringKey::parse_key(&cmd_set.service, &cmd_set.user);
let entry = Entry::new(&keyring_key.service, &keyring_key.user)?;
let password = match cmd_set.password {
Some(password) => password,
None => opt_result!(
pinentry_util::read_pin(Some(""), Some("")),
"Read password failed: {}"
)
.get_pin()
.to_string(),
};
entry.set_password(&password)?;
success!("Set password successfully");
}
Commands::Get(cmd_get) => {
let keyring_key = KeyringKey::parse_key(&cmd_get.service, &cmd_get.user);
let entry = Entry::new(&keyring_key.service, &keyring_key.user)?;
let password = entry.get_password()?;
if cmd_get.json {
let mut result = BTreeMap::new();
result.insert("service", keyring_key.service.to_string());
result.insert("user", keyring_key.user.to_string());
result.insert("password", password.to_string());
println!("{}", serde_json::to_string_pretty(&result)?);
} else if cmd_get.raw {
print!("{}", password);
} else {
success!("Got password: {}", password);
}
}
}
Ok(())
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260102T161635+08:00.MEUCIQD6zEitjMktgUQTzM9T
// 34zokou7pHGvhksmGrR41BS9VAIgD3HpLI01PfnN5nGoQi69yYmrILfdr82m4abfx8juzI4=

303
makepassword-rs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,303 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "makepassword-rs"
version = "0.1.0"
dependencies = [
"clap",
"rand",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

View File

@@ -0,0 +1,10 @@
[package]
name = "makepassword-rs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8.5"
clap = { version = "4.1.8", features = ["derive"] }

88
makepassword-rs/src/main.rs Executable file
View File

@@ -0,0 +1,88 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! rand = "0.8.5"
//! clap = { version = "4.1.8", features = ["derive"] }
//! ```
use clap::{arg, Parser};
use rand::RngCore;
use std::process::exit;
const ENGLISH_LOWER: &'static str = "abcdefghijklmnopqrstuvwxyz";
const ENGLISH_UPPER: &'static str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const NUMBER: &'static str = "0123456789";
const SPECIAL: &'static str = ".,/<>;:[]{}-=_+!@#$%^&*()~";
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None, bin_name = "makepassword.rs")]
struct Args {
/// Password length
#[arg(short, long)]
length: Option<u32>,
/// Chars (e.g. a - lower case alphabet, A - UPPER CASE ALPHABET, n|N|# - number, * - special)
#[arg(short, long)]
chars: Option<String>,
}
fn main() {
let args: Args = Args::parse();
let mut a = false;
let mut A = false;
let mut n = false;
let mut s = false;
match args.chars {
None => {
a = true;
A = true;
n = true;
}
Some(chars) => {
for c in chars.chars() {
match c {
'a' => a = true,
'A' => A = true,
'n' | 'N' | '#' => n = true,
'*' => s = true,
_ => {}
}
}
}
}
if !a && !A && !n && !s {
eprintln!("No chars selected.");
exit(1);
}
let mut str = "".to_string();
if a {
str += ENGLISH_LOWER;
}
if A {
str += ENGLISH_UPPER;
}
if n {
str += NUMBER;
}
if s {
str += SPECIAL;
}
let chars = str.chars().collect::<Vec<_>>();
let mut rng = rand::thread_rng();
let mut pass = String::new();
let len = args.length.unwrap_or(18);
for _ in 0..len {
pass.push(chars[rng.next_u32() as usize % chars.len()]);
}
println!("{}", pass);
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234836+08:00.MEYCIQDWrrmEPivS4NaZ+IVc
// zjbDY7Vo/hUSiJh4z+FfBZsL7gIhAIiwhEJ3fZ6kY5fEYE5W6b1f4wWeA3tMb6znH/bE9IjQ

View File

@@ -30,3 +30,6 @@ fn main() {
});
success!("Your IP address is: {}", ip_response.ip);
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234825+08:00.MEYCIQDu/n280mIfQ5cHOG2m
// CrX1sNCf+pKEtvk4fdlM9ZV7hQIhAI5V4wGI+KFd01b5gaMHpmlfa4wbOPMA34uPX1l2phze

2008
osssendfile-rs/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

19
osssendfile-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,19 @@
[package]
name = "osssendfile-rs"
version = "0.1.0"
edition = "2021"
[dependencies]
aes-gcm-stream = "0.2"
base64 = "0.22.1"
clap = { version = "4.5", features = ["derive"] }
hex = "0.4.3"
oss = "0.3.3"
rand = "0.8.5"
reqwest = { version = "0.12", default-features = false, features = ["stream", "native-tls-vendored"] }
rust_util = "0.6.47"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
sha2 = "0.10.8"
tokio = { version = "1.39", features = ["full"] }
tokio-util = "0.7.11"

6
osssendfile-rs/justfile Normal file
View File

@@ -0,0 +1,6 @@
_:
@just --list
build-linux-x64-musl:
cargo zigbuild --release --target x86_64-unknown-linux-musl

404
osssendfile-rs/src/main.rs Executable file
View File

@@ -0,0 +1,404 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! aes-gcm-stream = "0.2"
//! base64 = "0.22.1"
//! clap = { version = "4.5", features = ["derive"] }
//! hex = "0.4.3"
//! oss = "0.3.2"
//! rand = "0.8.5"
//! reqwest = { version = "0.12", features = ["stream"] }
//! rust_util = "0.6.47"
//! serde = { version = "1.0", features = ["derive"] }
//! serde_json = "1.0"
//! sha2 = "0.10.8"
//! tokio = { version = "1.39", features = ["full"] }
//! tokio-util = "0.7.11"
//! ```
use aes_gcm_stream::Aes128GcmStreamEncryptor;
use base64::engine::general_purpose::STANDARD;
use base64::Engine;
use clap::Parser;
use oss::OSSClient;
use reqwest::{Body, Client, Response};
use rust_util::util_io::DEFAULT_BUF_SIZE;
use rust_util::{failure, information, opt_result, opt_value_result, simple_error, success, util_file, util_msg, util_size, util_time, warning, XResult};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use sha2::Digest;
use sha2::Sha256;
use std::collections::HashMap;
use std::fs::File;
use std::io::{ErrorKind, Read, Write};
use std::path::PathBuf;
use std::{fs, io};
use tokio::fs::File as TokioFile;
use tokio_util::bytes::BytesMut;
use tokio_util::codec::{Decoder, FramedRead};
const OSS_SEND_FILE_CONFIG_FILE: &str = "~/.jssp/config/osssendfile.json";
const CREATE_STS_URL: &str = "https://global.hatter.ink/oidc/create_sts.json";
const ADD_DOC_URL: &str = "https://play.hatter.me/doc/addDoc.jsonp";
const ENV_OSS_SEND_FILE_CONFIG: &str = "OSS_SEND_FILE_CONFIG";
#[derive(Debug, Parser)]
#[command(name = "osssendfile-rs", bin_name = "osssendfile.rs")]
#[command(about = "OSS send file Rust edition", long_about = None)]
struct OssSendFileArgs {
/// Config file, default location: ~/.jssp/config/osssendfile.json
#[arg(long, short = 'c')]
config: Option<String>,
// /// Do not encrypt
// #[arg(long)]
// no_enc: bool,
// /// Do remove source file
#[arg(long)]
remove_source_file: bool,
// /// JWK
// #[arg(long, short = 'j')]
// jwk: Option<String>,
/// Upload file path
#[arg(long, short = 'f')]
file: PathBuf,
/// File name, default use local file name
#[arg(long, short = 'F')]
filename: Option<String>,
/// Keywords
#[arg(long, short = 'k')]
keywords: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct OssSendFileConfig {
endpoint: String,
bucket: String,
token: String,
oidc: OidcConfig,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct OidcConfig {
sub: String,
client_id: String,
client_secret: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Sts {
access_key_id: String,
access_key_secret: String,
expiration: String,
security_token: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct SendFileResponse {
status: i32,
id: i64,
length: i64,
etag: String,
sha256: String,
cdn_url: Option<String>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct CustomBytesCodec {
read_len: u64,
total_len: u64,
}
impl CustomBytesCodec {
pub fn new(total_len: u64) -> CustomBytesCodec {
CustomBytesCodec {
read_len: 0,
total_len,
}
}
}
impl Decoder for CustomBytesCodec {
type Item = BytesMut;
type Error = io::Error;
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<BytesMut>, io::Error> {
if !buf.is_empty() {
let len = buf.len();
self.read_len += len as u64;
util_msg::print_lastline(&format!(
"Copied {}, total: {}",
util_size::get_display_size(self.read_len as i64),
if self.total_len == 0 {
"-".to_string()
} else {
util_size::get_display_size(self.total_len as i64)
}
));
Ok(Some(buf.split_to(len)))
} else {
Ok(None)
}
}
}
#[tokio::main]
async fn main() -> XResult<()> {
let args = OssSendFileArgs::parse();
let client = Client::new();
let oss_send_file_config = load_config(&args.config)?;
information!("Get STS from hatter ink");
let sts = request_sts(&client, &oss_send_file_config).await?;
information!("Get STS success");
let source_file = args.file.clone();
let filename = source_file.file_name().unwrap().to_str().unwrap();
let filename_ext = get_filename_ext(filename);
let temp_file = match source_file.parent() {
None => PathBuf::from(format!("{}.tmp", filename)),
Some(parent_source_file) => {
parent_source_file.join(&format!("{}.tmp", filename))
}
};
if let Ok(metadata) = source_file.metadata() {
let file_len = metadata.len();
let file_len_display = util_size::get_display_size(file_len as i64);
if file_len < 1024 * 1024 {
information!("File length: {}", file_len_display);
} else if file_len < 10 * 1024 * 1024 {
warning!("File is large, length: {}", file_len_display);
} else {
failure!("File is very large, length: {}", file_len_display);
}
}
information!("Encrypt file {:?} -> {:?}", source_file, temp_file);
let temp_key = encrypt(&source_file, &temp_file)?;
information!("Encrypt file: {:?} success", &temp_file);
let oss_client = OSSClient::new_sts(&oss_send_file_config.endpoint,
&sts.access_key_id,
&sts.access_key_secret,
&sts.security_token);
let temp_oss_filename = format!("tempfiles/temp_transfer_{}.{}", util_time::get_current_millis(), filename_ext);
let temp_file_len = temp_file.metadata().map(|m| m.len()).unwrap_or(0);
information!("Put object {:?} -> {}", &temp_file, &temp_oss_filename);
// thanks: https://stackoverflow.com/questions/65814450/how-to-post-a-file-using-reqwest
let temp_file_read = opt_result!(TokioFile::open(&temp_file).await, "Read temp file failed: {}");
let temp_file_stream = FramedRead::new(temp_file_read, CustomBytesCodec::new(temp_file_len));
let temp_file_body = Body::wrap_stream(temp_file_stream);
let put_object_response = oss_client.put_body(
&oss_send_file_config.bucket, &temp_oss_filename, 600, temp_file_body).await?;
util_msg::clear_lastline();
if !put_object_response.status().is_success() {
return simple_error!("Put object failed, status: {}", put_object_response.status().as_u16());
}
information!("Put object success");
let object_url = oss_client.generate_signed_get_url(&oss_send_file_config.bucket, &temp_oss_filename, 600);
information!("Send URL to play security: {}", object_url);
let send_file_response = send_file(&client,
&oss_send_file_config.token,
&object_url,
&args.filename.clone().unwrap_or_else(|| get_filename(filename)),
args.keywords.as_deref().unwrap_or(""),
temp_key).await?;
information!("Send URL success, file id: {}", &send_file_response.id);
information!("Delete object: {}", &temp_oss_filename);
let delete_object_response = oss_client.delete_file(
&oss_send_file_config.bucket, &temp_oss_filename).await?;
if !delete_object_response.status().is_success() {
return simple_error!("Delete object failed, status: {}", delete_object_response.status().as_u16());
}
information!("Delete object success");
match fs::remove_file(&temp_file) {
Ok(_) => information!("Delete temp file success: {:?}", &temp_file),
Err(e) => warning!("Delete temp file failed: {}", e),
}
// check digest
let source_file_sha256 = hex::encode(digest_sha256(&source_file)?);
if source_file_sha256 != send_file_response.sha256 {
failure!("Check send file digest failed: {} vs {}", source_file_sha256, send_file_response.sha256);
return simple_error!("Check send file digest failed.");
}
if args.remove_source_file {
match fs::remove_file(&source_file) {
Ok(_) => information!("Delete source file success: {:?}", &source_file),
Err(e) => warning!("Delete source file failed: {}", e),
}
}
if let Some(cnd_url) = send_file_response.cdn_url {
success!("CDN URL: {}", cnd_url);
}
success!("File {} upload success", filename);
Ok(())
}
fn load_config(config: &Option<String>) -> XResult<OssSendFileConfig> {
let config = match config {
Some(config) => Some(config.clone()),
None => std::env::var(ENV_OSS_SEND_FILE_CONFIG).ok(),
};
if let Some(config_str) = &config {
if let Ok(oss_send_config) = serde_json::from_str::<OssSendFileConfig>(config_str) {
return Ok(oss_send_config);
}
if let Ok(config_vec) = STANDARD.decode(config_str) {
if let Ok(config_str_ori) = String::from_utf8(config_vec) {
if let Ok(oss_send_config) = serde_json::from_str::<OssSendFileConfig>(&config_str_ori) {
return Ok(oss_send_config);
}
}
}
}
let config_file_opt = util_file::read_config(
config,
&[OSS_SEND_FILE_CONFIG_FILE.to_string()],
);
let config_file = opt_value_result!(config_file_opt, "Config file not found.");
let config = opt_result!(
fs::read_to_string(&config_file), "Read file: {:?} failed: {}", config_file);
let oss_send_config: OssSendFileConfig = opt_result!(
serde_json::from_str(&config), "Parse file: {:?} failed: {}", config_file);
Ok(oss_send_config)
}
fn get_filename_ext(filename: &str) -> String {
let split_filename_parts: Vec<&str> = filename.split(".").collect();
split_filename_parts[split_filename_parts.len() - 1].to_string()
}
fn get_filename(filename: &str) -> String {
if filename.contains('/') {
let filename_parts = filename.split("/").collect::<Vec<&str>>();
filename_parts[filename_parts.len() - 1].to_string()
} else {
filename.to_string()
}
}
fn new_aes_key_and_nonce() -> ([u8; 16], Vec<u8>) {
let temp_key: [u8; 16] = rand::random();
let mut sha256 = Sha256::new();
sha256.update(&temp_key);
let sha256_digest = sha256.finalize();
let nonce = &sha256_digest.as_slice()[0..12];
(temp_key, nonce.to_vec())
}
fn encrypt(source_file: &PathBuf, dest_file: &PathBuf) -> XResult<[u8; 16]> {
if !source_file.exists() {
return simple_error!("File {:?} not exists.", source_file);
}
if dest_file.exists() {
return simple_error!("File {:?} exists.", dest_file);
}
let (temp_key, nonce) = new_aes_key_and_nonce();
let mut encryptor = Aes128GcmStreamEncryptor::new(temp_key, &nonce);
let mut source_file_read = File::open(source_file)?;
let mut dest_file_write = File::create(dest_file)?;
// let mut written = 0u64;
let mut buf: [u8; DEFAULT_BUF_SIZE] = [0u8; DEFAULT_BUF_SIZE];
loop {
let len = match source_file_read.read(&mut buf) {
Ok(0) => {
let (final_block, tag) = encryptor.finalize();
dest_file_write.write(&final_block)?;
// written += final_block.len() as u64;
dest_file_write.write(&tag)?;
// written += tag.len() as u64;
return Ok(temp_key);
}
Ok(len) => len,
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return simple_error!("Encrypt file failed: {}", e),
};
let encrypted = encryptor.update(&buf[0..len]);
dest_file_write.write(&encrypted)?;
// written += encrypted.len() as u64;
}
}
fn digest_sha256(source_file: &PathBuf) -> XResult<Vec<u8>> {
let mut sha256 = sha2::Sha256::new();
let content = opt_result!(fs::read(&source_file), "Read file: {:?} failed: {}", source_file);
sha256.update(&content);
let digest = sha256.finalize().as_slice().to_vec();
Ok(digest)
}
async fn request_sts(client: &Client, oss_send_file_config: &OssSendFileConfig) -> XResult<Sts> {
let mut params = HashMap::new();
params.insert("client_id", &oss_send_file_config.oidc.client_id);
params.insert("client_secret", &oss_send_file_config.oidc.client_secret);
params.insert("sub", &oss_send_file_config.oidc.sub);
let response = client.post(CREATE_STS_URL)
.form(&params)
.send()
.await?;
parse_sts_response(response).await
}
async fn send_file(client: &Client, token: &str, url: &str, title: &str, keywords: &str, key: [u8; 16]) -> XResult<SendFileResponse> {
let mut params = HashMap::new();
params.insert("jsonp", "1".to_string());
params.insert("token", token.to_string());
params.insert("url", url.to_string());
params.insert("title", title.to_string());
params.insert("keywords", keywords.to_string());
params.insert("encryption", STANDARD.encode(&key));
let response = client.post(ADD_DOC_URL)
.form(&params)
.send()
.await?;
if !response.status().is_success() {
return simple_error!("Add doc failed, status: {}", response.status().as_u16());
}
let response_bytes = response.bytes().await?.as_ref().to_vec();
let send_file_response: SendFileResponse = opt_result!(
serde_json::from_slice(&response_bytes), "Parse send file response failed: {}");
success!("Add doc id: {} success, sha256: {}", send_file_response.id, send_file_response.sha256);
Ok(send_file_response)
}
async fn parse_sts_response(response: Response) -> XResult<Sts> {
if !response.status().is_success() {
return simple_error!("Create STS failed, status: {}", response.status().as_u16());
}
let response_bytes = opt_result!(response.bytes().await, "Read STS failed: {}");
let response_value: Value = opt_result!(serde_json::from_slice(&response_bytes), "Parse STS response failed: {}");
let data_value = opt_value_result!(response_value.get("data"), "Parse STS response no data found.");
let data_value_str = serde_json::to_string(data_value).expect("Should not happen.");
let sts: Sts = opt_result!(serde_json::from_str(&data_value_str), "Parse STS response data failed: {}");
Ok(sts)
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20251015T193822+08:00.MEYCIQCHVvU0SXeLuxIAD19G
// PbuX9ZsYWBpsHL2aSo7MeelVhAIhAPMrEXIaiyaEDB8YtQfun1Sb+nwiAUeJvIOc9pKd5NwM

1264
post-rs/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

14
post-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "post-rs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
base64 = "0.21.0"
clap = { version = "4.1.8", features = ["derive"] }
reqwest = { version = "0.11.14", features = ["blocking", "json"] }
rust_util = "0.6.41"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93"

271
post-rs/src/main.rs Executable file
View File

@@ -0,0 +1,271 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! base64 = "0.21.0"
//! clap = { version = "4.1.8", features = ["derive"] }
//! reqwest = { version = "0.11.14", features = ["blocking", "json"] }
//! rust_util = "0.6.41"
//! serde = { version = "1.0.152", features = ["derive"] }
//! serde_json = "1.0.93"
//! ```
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use base64::Engine;
use clap::{arg, Parser};
use rust_util::{debugging, failure_and_exit, information, success, util_size, warning};
use rust_util::util_term::read_yes_no;
use serde_json::Value;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None, bin_name = "post.rs")]
struct Args {
/// Access Token, or from environment: POST_RS_TOKEN
#[arg(short, long)]
token: Option<String>,
/// FileName
#[arg(short, long)]
file_name: Option<String>,
/// Content Type
#[arg(short, long)]
content_type: Option<String>,
/// Description
#[arg(short, long)]
description: Option<String>,
/// Available after create, default 7d, 10m(10 minutes), 1h(1 hour), 1d(1 day), 1M(1 month), 1y(1 year)
#[arg(long)]
available_after_create: Option<String>,
/// Available after decrypt, default 10m, 10m(10 minutes), 1h(1 hour), 1d(1 day), 1M(1 month), 1y(1 year)
#[arg(long)]
available_after_decrypt: Option<String>,
/// Generate short URL, available minutes
#[arg(long)]
short_url_available_minutes: Option<u32>,
/// Password
#[arg(short, long)]
pass: Option<String>,
#[arg(required = true)]
file: PathBuf,
}
fn main() {
let args: Args = Args::parse();
let token = args.token.unwrap_or_else(
|| std::env::var("POST_RS_TOKEN").unwrap_or_else(
|_| failure_and_exit!("Token is required!")));
let file = args.file;
if !file.is_file() {
failure_and_exit!("File: {:?} not exists or it not a file.", file);
}
let file_name = args.file_name.unwrap_or_else(
|| file.file_name().map(
|f| f.to_str().map(ToString::to_string))
.flatten().unwrap_or_else(|| "unnamed".to_string()));
let content_type = args.content_type.unwrap_or_else(|| get_content_type(&file_name));
let description = args.description.unwrap_or_else(|| "n/a".to_string());
let available_after_create = args.available_after_create.unwrap_or_else(|| "7d".to_string());
let available_after_decrypt = args.available_after_decrypt.unwrap_or_else(|| "10m".to_string());
let password = args.pass;
let file_base64 = {
let file_bytes = fs::read(&file).unwrap_or_else(|e| {
failure_and_exit!("Read file: {:?} failed: {}", file, e)
});
if file_bytes.len() > 10 * 1024 * 1024 {
warning!("File: {:?} is large, size: {}", file, util_size::get_display_size(file_bytes.len() as i64));
} else {
information!("File: {:?} size: {}", file, util_size::get_display_size(file_bytes.len() as i64));
}
base64::engine::general_purpose::STANDARD.encode(&file_bytes)
};
information!("Sending file: {}", file_name);
let mut params = HashMap::new();
params.insert("pretty", "true");
params.insert("token", &token);
params.insert("dataBase64", &file_base64);
params.insert("fileName", &file_name);
params.insert("contentType", &content_type);
params.insert("description", &description);
params.insert("availableAfterCreate", &available_after_create);
params.insert("availableAfterDecrypt", &available_after_decrypt);
debugging!("Params: {:?}", serde_json::to_string_pretty(&params));
if let Some(pass) = &password {
params.insert("pass", pass);
}
let client = reqwest::blocking::Client::new();
let post_result = client.post("https://global.hatter.ink/secfile/post.json")
.form(&params)
.send();
match post_result {
Err(e) => failure_and_exit!("Post file: {} failed: {}",file_name, e),
Ok(response) => match response.text() {
Err(e) => failure_and_exit!("Post file: {} response failed: {}", file_name, e),
Ok(text) => {
success!("Post file: {} succeed: {}", file_name, &text);
if args.short_url_available_minutes.is_some() || read_yes_no("Generate One Time Link") {
let post_response: Value = serde_json::from_str(&text).unwrap();
if let Some(post_response_data) = post_response.get("data") {
if let Some(Value::String(full_link)) = post_response_data.get("fullLink") {
let mut params = HashMap::new();
params.insert("pretty", "true".to_string());
params.insert("targetUrl", full_link.to_string());
params.insert("aliveTimeMin", args.short_url_available_minutes.unwrap_or(10).to_string());
let otl_result = client.post("https://global.hatter.ink/onetimelink/add.json")
.form(&params)
.send();
if let Ok(response) = otl_result {
if let Ok(text) = response.text() {
success!("File one time link: {}", text);
}
}
}
}
}
}
}
}
}
fn get_content_type(file_name: &str) -> String {
let file_name = file_name.to_ascii_lowercase();
if file_name.ends_with(".txt")
|| file_name.ends_with(".text")
|| file_name.ends_with(".diff")
|| file_name.ends_with(".md")
|| file_name.ends_with(".markdown") {
"text/plain".into()
} else if file_name.ends_with(".aac") {
"audio/aac".into()
} else if file_name.ends_with(".avi") {
"video/x-msvideo".into()
} else if file_name.ends_with(".css") {
"text/css".into()
} else if file_name.ends_with(".csv") {
"text/csv".into()
} else if file_name.ends_with(".doc") {
"application/msword".into()
} else if file_name.ends_with(".docx") {
"application/vnd.openxmlformats-officedocument.wordprocessingml.document".into()
} else if file_name.ends_with(".eot") {
"application/vnd.ms-fontobject".into()
} else if file_name.ends_with(".epub") {
"application/epub+zip".into()
} else if file_name.ends_with(".gz") {
"application/gzip".into()
} else if file_name.ends_with(".dif") {
"image/gif".into()
} else if file_name.ends_with(".htm")
|| file_name.ends_with(".html") {
"text/html".into()
} else if file_name.ends_with(".ico") {
"image/vnd.microsoft.icon".into()
} else if file_name.ends_with(".jar") {
"application/java-archive".into()
} else if file_name.ends_with(".jpe")
|| file_name.ends_with(".jpg")
|| file_name.ends_with(".jpeg") {
"image/jpeg".into()
} else if file_name.ends_with(".js") {
"text/javascript".into()
} else if file_name.ends_with(".json") {
"application/json".into()
} else if file_name.ends_with(".jsonld") {
"application/ld+json".into()
} else if file_name.ends_with(".mid")
|| file_name.ends_with(".midi") {
"audio/midi".into()
} else if file_name.ends_with(".mp3") {
"audio/mpeg".into()
} else if file_name.ends_with(".mp4") {
"video/mp4".into()
} else if file_name.ends_with(".mpeg") {
"video/mpeg".into()
} else if file_name.ends_with(".mpkg") {
"application/vnd.apple.installer+xml".into()
} else if file_name.ends_with(".odp") {
"application/vnd.oasis.opendocument.presentation".into()
} else if file_name.ends_with(".ods") {
"application/vnd.oasis.opendocument.spreadsheet".into()
} else if file_name.ends_with(".odt") {
"application/vnd.oasis.opendocument.text".into()
} else if file_name.ends_with(".oga") {
"audio/ogg".into()
} else if file_name.ends_with(".ogv") {
"video/ogg".into()
} else if file_name.ends_with(".ogg") {
"application/ogg".into()
} else if file_name.ends_with(".otf") {
"font/otf".into()
} else if file_name.ends_with(".png") {
"image/png".into()
} else if file_name.ends_with(".pdf") {
"application/pdf".into()
} else if file_name.ends_with(".ppt") {
"application/vnd.ms-powerpoint".into()
} else if file_name.ends_with(".pptx") {
"application/vnd.openxmlformats-officedocument.presentationml.presentation".into()
} else if file_name.ends_with(".rar") {
"application/vnd.rar".into()
} else if file_name.ends_with(".rtf") {
"application/rtf".into()
} else if file_name.ends_with(".sh") {
"application/x-sh".into()
} else if file_name.ends_with(".svg") {
"image/svg+xml".into()
} else if file_name.ends_with(".tar") {
"application/x-tar".into()
} else if file_name.ends_with(".tif")
|| file_name.ends_with(".tiff") {
"image/tiff".into()
} else if file_name.ends_with(".ts") {
"video/mp2t".into()
} else if file_name.ends_with(".ttf") {
"font/ttf".into()
} else if file_name.ends_with(".wav") {
"audio/wav".into()
} else if file_name.ends_with(".weba") {
"audio/webm".into()
} else if file_name.ends_with(".webm") {
"video/webm".into()
} else if file_name.ends_with(".webp") {
"image/webp".into()
} else if file_name.ends_with(".woff") {
"font/woff".into()
} else if file_name.ends_with(".woff2") {
"font/woff2".into()
} else if file_name.ends_with(".xhtml") {
"application/xhtml+xml".into()
} else if file_name.ends_with(".xls") {
"application/vnd.ms-excel".into()
} else if file_name.ends_with(".xlsx") {
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".into()
} else if file_name.ends_with(".xml") {
"application/xml".into()
} else if file_name.ends_with(".zip") {
"application/zip".into()
} else if file_name.ends_with(".3gp") {
"video/3gpp".into()
} else if file_name.ends_with(".7z") {
"application/x-7z-compressed".into()
} else {
"application/octet-stream".into()
}
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250621T103237+08:00.MEUCIHc34Zy2KI58wxBFq/U5
// ANIjsHjMBhOKGuci4sBnWCQNAiEA0MBBIsmAWPXGupKewS5z8LP3ERHdj15CuFOXGmNuUfI=

1639
rpm-read-rs/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

10
rpm-read-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "rpm-read-rs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rpm-rs = "0.8.1"
rust_util = "0.6.41"

20
rpm-read-rs/src/main.rs Normal file
View File

@@ -0,0 +1,20 @@
use std::fs::File;
use std::io::BufReader;
use rpm::RPMPackage;
use rust_util::{failure_and_exit, information, opt_result};
fn main() {
let args = std::env::args().skip(1).collect::<Vec<_>>();
if args.is_empty() {
failure_and_exit!("Args is empty");
}
let file = &args[0];
let rpm_file = opt_result!(File::open(file), "Open file: {} failed: {}", file);
let mut buf_reader = BufReader::new(rpm_file);
let pkg = opt_result!(RPMPackage::parse(&mut buf_reader), "Read rpm: {} failed: {}", file);
information!("Lead: {:?}", pkg.metadata.lead);
information!("Header: {:?}", pkg.metadata.header);
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234746+08:00.MEUCICrO2MejPQurIkpdb8IJ
// pyfgiSlH567FvfcMIrjhx9ZAAiEArhv+crGq5d2l3/4ZunPSfVQ90Tb9xcbn8Rh9ga/HlYY=

7
script-config.json Normal file
View File

@@ -0,0 +1,7 @@
{
"file_ext": "rs",
"simple_script_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/single-scripts/$NAME",
"project_script_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/$NAME/src/main.rs",
"script_sub_dir": "src",
"skip_dirs": []
}

155
script-meta-v2.json Normal file
View File

@@ -0,0 +1,155 @@
{
"bit-address.rs": {
"script_name": "bit-address.rs",
"script_length": 4038,
"script_sha256": "54b6bfce07899c2cbf5c0b3743a552a79849e0650850b2c74e0489282bf157b2",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/bit-address-rs/src/main.rs",
"publish_time": 1737272563311,
"update_time": 1737647377228
},
"commit-msg.rs": {
"script_name": "commit-msg.rs",
"script_length": 6778,
"script_sha256": "b875fabee2f2ea8ceb0f4cd1ca6b175f22e995d150589a96ded2d0e5655232cc",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/commit-msg-rs/src/main.rs",
"publish_time": 1737272563311,
"update_time": 1737647377228
},
"connect.rs": {
"script_name": "connect.rs",
"script_length": 8102,
"script_sha256": "b0263a2056f6e600299a81a43f06d2bf841cf8cf9d533e8342e87a82038adabd",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/connect-rs/src/main.rs",
"publish_time": 1760367513436,
"update_time": 1761024735490
},
"current-time.rs": {
"script_name": "current-time.rs",
"script_length": 3462,
"script_sha256": "263093c71f906819e2d336a94510435a5ed07df49dac766f8d35c5e6097e3494",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/current-time-rs/src/main.rs",
"publish_time": 1737272563311,
"update_time": 1737647377228
},
"decrypt.rs": {
"script_name": "decrypt.rs",
"script_length": 3248,
"script_sha256": "93dd27b383f56985471c9b78965d6abd618e31d1db3b09c749324844879ce991",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/decrypt-rs/src/main.rs",
"publish_time": 1737272563311,
"update_time": 1737647377228
},
"derparse.rs": {
"script_name": "derparse.rs",
"script_length": 7529,
"script_sha256": "c05c8a17be4d25ab899d81bb2c4407af143a49d2b40c26dbb44d43974f20aa64",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/derparse-rs/src/main.rs",
"publish_time": 1737272563312,
"update_time": 1737647377228
},
"file-format.rs": {
"script_name": "file-format.rs",
"script_length": 1274,
"script_sha256": "f65c800169293e8e1a3caa56e4d5833aae34f4e81f2b0c5a011e1dd277a71789",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/file-format-rs/src/main.rs",
"publish_time": 1748622382967,
"update_time": 1748622382967
},
"helloworld.rs": {
"script_name": "helloworld.rs",
"script_length": 225,
"script_sha256": "230ed8ffd673de9cb585ba149492ff1280ace847c8ba9b4c2e66c0b6ab5aa1b5",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/single-scripts/helloworld.rs",
"single_script_file": true,
"publish_time": 1737272563312,
"update_time": 1737647377229
},
"keyring.rs": {
"script_name": "keyring.rs",
"script_length": 4134,
"script_sha256": "7858a0386ba7392406c8cb455d8ec48f62b284c02d20be566d8b9896927efd04",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/keyring-rs/src/main.rs",
"publish_time": 1760858747229,
"update_time": 1767341842395
},
"makepassword.rs": {
"script_name": "makepassword.rs",
"script_length": 2127,
"script_sha256": "88486b4186312e5fad2ed09ec4fc30b671101dcbc24dee56a3a62abb2a8ac2ce",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/makepassword-rs/src/main.rs",
"publish_time": 1737272563310,
"update_time": 1737647377227
},
"myip.rs": {
"script_name": "myip.rs",
"script_length": 1094,
"script_sha256": "939fdc876cd2990b84ece186c94a2d63dfabda23adf86462863c72a245e17410",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/myip-rs/src/main.rs",
"publish_time": 1737272563310,
"update_time": 1737647377227
},
"osssendfile.rs": {
"script_name": "osssendfile.rs",
"script_length": 14876,
"script_sha256": "a16d5f0d2da9f4c034a42ff7bb4caa434cc2673fd8f882fbb23dd16c21f18afa",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/osssendfile-rs/src/main.rs",
"publish_time": 1737272563311,
"update_time": 1760528318233
},
"post.rs": {
"script_name": "post.rs",
"script_length": 10669,
"script_sha256": "0448ecd3ddcb76ce18c20bd3eb8106c108c6775b88400f179b875772acaf7678",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/post-rs/src/main.rs",
"publish_time": 1737272563311,
"update_time": 1757430653320
},
"rpm-read.rs": {
"script_name": "rpm-read.rs",
"script_length": 798,
"script_sha256": "175a7214e8367838be3be5efeae194e89a0328aa462d5d7b412a25d29ca9f9de",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/rpm-read-rs/src/main.rs",
"publish_time": 1737272563312,
"update_time": 1737647377228
},
"script-sign.rs": {
"script_name": "script-sign.rs",
"script_length": 3190,
"script_sha256": "c373737d7c390c40ba4fcc25cbf99386f3b04bb80b848f4bd9ecc490b7f6c064",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/script-sign-rs/src/main.rs",
"publish_time": 1737272563311,
"update_time": 1737647377228
},
"script-verify.rs": {
"script_name": "script-verify.rs",
"script_length": 5783,
"script_sha256": "f864fe6ab80437e363859fb6fb3721b7368421868ef3980c68a5c8aa60c0d6f9",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/script-verify-rs/src/main.rs",
"publish_time": 1737563113466,
"update_time": 1757430653323
},
"ssh.rs": {
"script_name": "ssh.rs",
"script_length": 8096,
"script_sha256": "2e109554551755c3435218c5508edd2dd75f9f3aca3e40831a6c70e2e56d439d",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/ssh-rs/src/main.rs",
"publish_time": 1767355767325,
"update_time": 1767355767325
},
"sync.rs": {
"script_name": "sync.rs",
"script_length": 1978,
"script_sha256": "2218487f955e8021c2e4b5b56b9aa4bec6cde89839ae45449bb852c5696cb72e",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/sync-rs/src/main.rs",
"publish_time": 1737272563310,
"update_time": 1750428425867
},
"xattr.rs": {
"script_name": "xattr.rs",
"script_length": 2029,
"script_sha256": "20da6daa1cad0235f49d73f349226871960978333d1be62b73208b053b7d4c5a",
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/xattr-rs/src/main.rs",
"publish_time": 1737272563311,
"update_time": 1737647377228
}
}

92
script-meta.json Normal file
View File

@@ -0,0 +1,92 @@
{
"bit-address-rs": {
"script_name": "bit-address-rs",
"script_length": 4038,
"script_sha256": "54b6bfce07899c2cbf5c0b3743a552a79849e0650850b2c74e0489282bf157b2"
},
"commit-msg-rs": {
"script_name": "commit-msg-rs",
"script_length": 6778,
"script_sha256": "b875fabee2f2ea8ceb0f4cd1ca6b175f22e995d150589a96ded2d0e5655232cc"
},
"connect-rs": {
"script_name": "connect-rs",
"script_length": 8102,
"script_sha256": "b0263a2056f6e600299a81a43f06d2bf841cf8cf9d533e8342e87a82038adabd"
},
"current-time-rs": {
"script_name": "current-time-rs",
"script_length": 3462,
"script_sha256": "263093c71f906819e2d336a94510435a5ed07df49dac766f8d35c5e6097e3494"
},
"decrypt-rs": {
"script_name": "decrypt-rs",
"script_length": 3248,
"script_sha256": "93dd27b383f56985471c9b78965d6abd618e31d1db3b09c749324844879ce991"
},
"derparse-rs": {
"script_name": "derparse-rs",
"script_length": 7529,
"script_sha256": "c05c8a17be4d25ab899d81bb2c4407af143a49d2b40c26dbb44d43974f20aa64"
},
"file-format-rs": {
"script_name": "file-format-rs",
"script_length": 1274,
"script_sha256": "f65c800169293e8e1a3caa56e4d5833aae34f4e81f2b0c5a011e1dd277a71789"
},
"keyring-rs": {
"script_name": "keyring-rs",
"script_length": 4134,
"script_sha256": "7858a0386ba7392406c8cb455d8ec48f62b284c02d20be566d8b9896927efd04"
},
"makepassword-rs": {
"script_name": "makepassword-rs",
"script_length": 2127,
"script_sha256": "88486b4186312e5fad2ed09ec4fc30b671101dcbc24dee56a3a62abb2a8ac2ce"
},
"myip-rs": {
"script_name": "myip-rs",
"script_length": 1094,
"script_sha256": "939fdc876cd2990b84ece186c94a2d63dfabda23adf86462863c72a245e17410"
},
"osssendfile-rs": {
"script_name": "osssendfile-rs",
"script_length": 14876,
"script_sha256": "a16d5f0d2da9f4c034a42ff7bb4caa434cc2673fd8f882fbb23dd16c21f18afa"
},
"post-rs": {
"script_name": "post-rs",
"script_length": 10669,
"script_sha256": "0448ecd3ddcb76ce18c20bd3eb8106c108c6775b88400f179b875772acaf7678"
},
"rpm-read-rs": {
"script_name": "rpm-read-rs",
"script_length": 798,
"script_sha256": "175a7214e8367838be3be5efeae194e89a0328aa462d5d7b412a25d29ca9f9de"
},
"script-sign-rs": {
"script_name": "script-sign-rs",
"script_length": 3190,
"script_sha256": "c373737d7c390c40ba4fcc25cbf99386f3b04bb80b848f4bd9ecc490b7f6c064"
},
"script-verify-rs": {
"script_name": "script-verify-rs",
"script_length": 5783,
"script_sha256": "f864fe6ab80437e363859fb6fb3721b7368421868ef3980c68a5c8aa60c0d6f9"
},
"ssh-rs": {
"script_name": "ssh-rs",
"script_length": 8096,
"script_sha256": "2e109554551755c3435218c5508edd2dd75f9f3aca3e40831a6c70e2e56d439d"
},
"sync-rs": {
"script_name": "sync-rs",
"script_length": 1978,
"script_sha256": "2218487f955e8021c2e4b5b56b9aa4bec6cde89839ae45449bb852c5696cb72e"
},
"xattr-rs": {
"script_name": "xattr-rs",
"script_length": 2029,
"script_sha256": "20da6daa1cad0235f49d73f349226871960978333d1be62b73208b053b7d4c5a"
}
}

1029
script-sign-rs/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
[package]
name = "script-sign-rs"
version = "0.1.1"
edition = "2021"
[dependencies]
clap = { version = "4.5", features = ["derive"] }
rust_util = "0.6"
script-sign = "0.1"

8
script-sign-rs/README.md Normal file
View File

@@ -0,0 +1,8 @@
# script-sign
Signature format (last line):
```plain
// @SCRIPT-SIGNATURE-V1: <key-id>.<algotirhm>.<time>.<signature-value-in-base64>
```

107
script-sign-rs/src/main.rs Executable file
View File

@@ -0,0 +1,107 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! clap = { version = "4.5", features = ["derive"] }
//! rust_util = "0.6"
//! script-sign = "0.1"
//! ```
use clap::Parser;
use rust_util::{failure, information, success, warning};
use script_sign::{KeyMap, Script};
use std::fs;
use std::path::PathBuf;
/// Script signing tool
#[derive(Parser, Debug)]
#[command(version, about, long_about = None, bin_name = "script-sign.rs")]
struct Args {
/// Force sign script
#[arg(long)]
force: bool,
/// Script file path
scripts: Vec<PathBuf>,
}
fn main() {
let args = Args::parse();
let key_map = KeyMap::system();
let total_scripts = args.scripts.len();
if total_scripts == 0 {
warning!("No scripts assigned.");
return;
}
for (i, script_path) in args.scripts.iter().enumerate() {
information!(
"Signing {}/{}: {}",
(i + 1),
total_scripts,
script_path.display()
);
if !script_path.is_file() {
warning!("Not a file: {}", script_path.display());
continue;
}
let script_content = match fs::read_to_string(script_path) {
Ok(script_content) => script_content,
Err(e) => {
warning!("Read script: {} failed: {}", script_path.display(), e);
continue;
}
};
let mut script = match Script::parse(&script_content) {
Ok(script) => script,
Err(e) => {
warning!("Read script: {} failed: {}", script_path.display(), e);
continue;
}
};
let mut continue_sign = false;
if script.signature.is_some() {
match script.verify(&key_map) {
Ok(true) => {
if args.force {
continue_sign = true;
} else {
warning!("Script is singed, force sign script need --force flag.");
}
}
Ok(false) => {
continue_sign = true;
}
Err(e) => {
warning!("Verify script: {} failed: {}", script_path.display(), e);
}
}
} else {
continue_sign = true;
}
if continue_sign {
information!("Prepare sign script: {}", script_path.display());
match script.sign() {
Ok(_) => match fs::write(script_path, &script.as_string()) {
Ok(_) => {
success!("Sign script success: {}", script_path.display());
}
Err(e) => {
failure!("Sign script {} failed: {}", script_path.display(), e);
}
},
Err(e) => {
failure!("Sign script {} failed: {}", script_path.display(), e);
}
}
}
}
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234540+08:00.MEUCIAb0abnvE+G4FEjtZKVI
// HiXhtIOWiOT4fQrK/8Dy4iGCAiEAxGRSBDSdnsWJTfof/oJzOKDwlgEZoCpy9HSz3OQQH6M=

4
script-sign-rs/test.js Normal file
View File

@@ -0,0 +1,4 @@
console.log('hello world');
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T001551+08:00.MEQCIAS0qLGvA++l+8EeA2/t
// qHUZ1JtPfjExH1VAfN2ka4WyAiB+m2tkiwR8iK8a7DL96dr1HVC8MtYiPA5P9qJCPv3dJA==

1031
script-verify-rs/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
[package]
name = "script-verify-rs"
version = "0.1.1"
edition = "2021"
[dependencies]
clap = { version = "4.5", features = ["derive"] }
rust_util = "0.6"
script-sign = "0.1"
serde = { version = "1.0", features = ["serde_derive"] }
serde_json = "1.0"

View File

@@ -0,0 +1,8 @@
# script-verify
Signature format (last line):
```plain
// @SCRIPT-SIGNATURE-V1: <key-id>.<algotirhm>.<time>.<signature-value-in-base64>
```

164
script-verify-rs/src/main.rs Executable file
View File

@@ -0,0 +1,164 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! clap = { version = "4.5", features = ["derive"] }
//! rust_util = "0.6"
//! script-sign = "0.1"
//! serde = { version = "1.0", features = ["serde_derive"] }
//! serde_json = "1.0"
//! ```
use clap::Parser;
use rust_util::{failure, information, success, util_msg, warning};
use script_sign::{KeyMap, Script};
use std::fs;
use std::path::PathBuf;
use serde::Serialize;
/// Script signing tool
#[derive(Parser, Debug)]
#[command(version, about, long_about = None, bin_name = "script-verify.rs")]
struct Args {
/// JSON outputs
#[arg(long)]
json: bool,
/// Script file path
scripts: Vec<PathBuf>,
}
#[derive(Clone, Debug, Serialize)]
struct ScriptVerification {
name: String,
success: bool,
#[serde(skip_serializing_if = "Option::is_none")]
sign_key_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
sign_time: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
message: Option<String>,
}
fn main() {
let args = Args::parse();
if args.json {
util_msg::set_logger_std_out(false);
}
let key_map = KeyMap::system();
let total_scripts = args.scripts.len();
if total_scripts == 0 {
warning!("No scripts assigned.");
return;
}
let mut script_verifications = vec![];
for (i, script_path) in args.scripts.iter().enumerate() {
let script_path_display = script_path.display().to_string();
information!(
"Verifying {}/{}: {}",
(i + 1),
total_scripts,
script_path_display
);
if !script_path.is_file() {
warning!("Not a file: {}", script_path_display);
script_verifications.push(ScriptVerification {
name: script_path_display.clone(),
success: false,
sign_key_id: None,
sign_time: None,
message: Some(format!("Not a file: {}", script_path_display)),
});
continue;
}
let script_content = match fs::read_to_string(script_path) {
Ok(script_content) => script_content,
Err(e) => {
warning!("Read script: {} failed: {}", script_path_display, e);
script_verifications.push(ScriptVerification {
name: script_path_display.clone(),
success: false,
sign_key_id: None,
sign_time: None,
message: Some(format!("Read script: {} failed: {}", script_path_display, e)),
});
continue;
}
};
let script = match Script::parse(&script_content) {
Ok(script) => script,
Err(e) => {
warning!("Read script: {} failed: {}", script_path_display, e);
script_verifications.push(ScriptVerification {
name: script_path_display.clone(),
success: false,
sign_key_id: None,
sign_time: None,
message: Some(format!("Read script: {} failed: {}", script_path_display, e)),
});
continue;
}
};
if let Some(signature) = &script.signature {
match script.verify(&key_map) {
Ok(true) => {
success!(
"Verify script success: {}, key ID: {}, sign date: {}",
script_path_display,
signature.key_id,
signature.time
);
script_verifications.push(ScriptVerification {
name: script_path_display.clone(),
success: true,
sign_key_id: Some(signature.key_id.clone()),
sign_time: Some(signature.time.clone()),
message: None,
});
}
Ok(false) => {
failure!("Verify script failed: {}", script_path_display);
script_verifications.push(ScriptVerification {
name: script_path_display.clone(),
success: false,
sign_key_id: None,
sign_time: None,
message: Some(format!("Verify script failed: {}", script_path_display)),
});
}
Err(e) => {
warning!("Verify script: {} failed: {}", script_path_display, e);
script_verifications.push(ScriptVerification {
name: script_path_display.clone(),
success: false,
sign_key_id: None,
sign_time: None,
message: Some(format!("Verify script: {} failed: {}", script_path_display, e)),
});
}
}
} else {
warning!("Script is not signed: {}", script_path_display);
script_verifications.push(ScriptVerification {
name: script_path_display.clone(),
success: false,
sign_key_id: None,
sign_time: None,
message: Some(format!("Script is not signed: {}", script_path_display)),
});
}
}
if args.json {
println!("{}", serde_json::to_string_pretty(&script_verifications).unwrap());
}
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250909T231004+08:00.MEQCIDSni3F6bS8F9SD6tjdL
// 6P8BkVrqJn1FwKUhro7nbJHWAiAVvDq/M4qpb1LutG0sw8zqx2dNeOpzDRNneEkumUsOlg==

4
script-verify-rs/test.js Normal file
View File

@@ -0,0 +1,4 @@
console.log('hello world');
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T001551+08:00.MEQCIAS0qLGvA++l+8EeA2/t
// qHUZ1JtPfjExH1VAfN2ka4WyAiB+m2tkiwR8iK8a7DL96dr1HVC8MtYiPA5P9qJCPv3dJA==

8
single-scripts/helloworld.rs Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/env runrs
fn main() {
println!("Hello World.");
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234248+08:00.MEYCIQCt4DX+j7+yKgXnpFcj
// IjLGvNVbOyR5F6J4b4zcxGke7wIhAMaHxQuro46rcMFqBn8X7wA0u9rYl3I+QdL5/6LKYck7

414
ssh-rs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,414 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anstream"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys",
]
[[package]]
name = "bitflags"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "clap"
version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itoa"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]]
name = "libredox"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "memchr"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "proc-macro2"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "rust_util"
version = "0.6.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01736dfb1c97fec6b874d4939aac6db3b748c61cfd62183c7b80c4f1db003635"
dependencies = [
"lazy_static",
"libc",
"term",
"term_size",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.148"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "ssh-rs"
version = "0.1.0"
dependencies = [
"clap",
"rust_util",
"serde",
"serde_json",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "zmij"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de9211a9f64b825911bdf0240f58b7a8dac217fe260fc61f080a07f61372fbd5"

10
ssh-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "ssh-rs"
version = "0.1.0"
edition = "2024"
[dependencies]
rust_util = "0.6.50"
clap = { version = "4.5.49", features = ["derive"] }
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.145"

259
ssh-rs/src/main.rs Executable file
View File

@@ -0,0 +1,259 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! rust_util = "0.6.50"
//! clap = { version = "4.5.49", features = ["derive"] }
//! serde = { version = "1.0.228", features = ["derive"] }
//! serde_json = "1.0.145"
//! ```
use clap::Parser;
use rust_util::{
XResult, debugging, failure_and_exit, iff, information, opt_result, simple_error, success,
util_cmd, util_env, util_file, util_term,
};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::process::Command;
#[derive(Debug, Parser)]
#[command(name = "ssh-rs", bin_name = "ssh.rs")]
#[command(about = "SSH util", long_about = None)]
struct SshRsArgs {
/// Forward agent
#[arg(long, short = 'f')]
pub forward_agent: Option<bool>,
/// Proxy
#[arg(long, short = 'p')]
pub proxy: Option<bool>,
/// [username@]host
pub username_and_host: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
struct SshConfig {
pub default_forward_agent: Option<bool>,
pub default_proxy: Option<bool>,
pub default_username: Option<String>,
pub profiles: BTreeMap<String, SshProfile>,
}
#[derive(Debug, Serialize, Deserialize)]
struct SshProfile {
pub default_username: Option<String>,
pub alias: Option<Vec<String>>,
pub host: String,
pub proxy: Option<bool>,
pub forward_agent: Option<bool>,
pub comment: Option<String>,
}
impl SshConfig {
fn find_profiles(&self, profile: &str) -> Vec<(&String, &SshProfile)> {
let mut found = vec![];
for (k, v) in &self.profiles {
if k == profile {
found.push((k, v));
} else if let Some(alias) = &v.alias {
if alias.contains(&profile.to_string()) {
found.push((k, v));
}
}
}
found
}
}
const ENV_SSH_RS_CONFIG_FILE: &str = "SSH_RS_CONFIG_FILE";
const SSH_RS_CONFIG_FILE: &str = "~/.config/ssh-rs-config.json";
const CMD_SSH: &str = "ssh";
fn main() -> XResult<()> {
let args = SshRsArgs::parse();
let ssh_rs_config = load_ssh_rs_config()?;
let username_and_host = match args.username_and_host {
None => {
print_when_no_args(&ssh_rs_config);
return Ok(());
}
Some(username_and_host) => username_and_host,
};
let (username, host) = parse_username_and_host(&username_and_host)?;
let profile = match_profile(&ssh_rs_config, &host)?;
debugging!("Found profile: {:#?}", profile);
let ssh_forward_agent = args.forward_agent.clone().unwrap_or_else(|| {
profile.forward_agent.unwrap_or_else(|| //-
ssh_rs_config.default_forward_agent.unwrap_or(false))
});
let ssh_proxy = args.proxy.clone().unwrap_or_else(|| {
profile.proxy.unwrap_or_else(|| //-
ssh_rs_config.default_proxy.unwrap_or(false))
});
let ssh_username = username.unwrap_or_else(|| {
profile.default_username.clone().unwrap_or_else(|| {
ssh_rs_config
.default_username
.clone()
.unwrap_or_else(|| "root".to_string())
})
});
let ssh_host = profile.host.clone();
let mut cmd = Command::new(CMD_SSH);
if ssh_forward_agent {
cmd.args(&["-o", "ForwardAgent=yes"]);
}
if ssh_proxy {
cmd.args(&["-o", "ProxyCommand=nc -X 5 -x 127.0.0.1:1080 %h %p"]);
}
cmd.arg(&format!("{}@{}", ssh_username, ssh_host));
success!(
"{} {}",
CMD_SSH,
cmd.get_args()
.map(|s| s.to_string_lossy().to_string())
.collect::<Vec<_>>()
.join(" ")
);
match util_cmd::run_command_and_wait(&mut cmd) {
Ok(exit_status) => {
debugging!("Command exited with status: {}", exit_status);
if !exit_status.success() {
failure_and_exit!("Exit with error: {}", exit_status);
}
}
Err(err) => {
failure_and_exit!("SSH command failed: {}", err);
}
}
Ok(())
}
fn match_profile<'a>(ssh_rs_config: &'a SshConfig, host: &String) -> XResult<&'a SshProfile> {
let profiles = ssh_rs_config.find_profiles(&host);
if profiles.is_empty() {
return simple_error!("Profile not found");
}
if profiles.len() > 1 {
let profile_names = profiles
.iter()
.map(|p| p.0.to_string())
.collect::<Vec<_>>()
.join(", ");
return simple_error!("Multiple profiles found: {}", profile_names);
}
Ok(profiles[0].1)
}
fn print_when_no_args(ssh_rs_config: &SshConfig) {
success!("Total {} server(s):", ssh_rs_config.profiles.len());
let mut max_profile_id_len = 0_usize;
let mut max_host_len = 0_usize;
for (profile_id, profile) in &ssh_rs_config.profiles {
if profile_id.len() > max_profile_id_len {
max_profile_id_len = profile_id.len();
}
if profile.host.len() > max_host_len {
max_host_len = profile.host.len();
}
}
for (profile_id, profile) in &ssh_rs_config.profiles {
let features = make_features(
profile.forward_agent.unwrap_or(false),
profile.proxy.unwrap_or(false),
);
println!(
"- {} : {}{} {}{}{} # {}{}",
pad(profile_id, max_profile_id_len),
util_term::GREEN,
pad(&profile.host, max_host_len),
util_term::YELLOW,
match &profile.alias {
None => {
"".to_string()
}
Some(alias) => {
format!(
"alias{}: [{}]",
iff!(alias.len() == 1, " ", "es"),
alias.join(", ")
)
}
},
util_term::END,
profile.comment.clone().unwrap_or_else(|| "-".to_string()),
iff!(
features.is_empty(),
"".to_string(),
format!(" ;[{}]", features.join(", "))
)
);
}
let features = make_features(
ssh_rs_config.default_forward_agent.unwrap_or(false),
ssh_rs_config.default_proxy.unwrap_or(false),
);
if !features.is_empty() {
println!();
information!("Global default features: [{}]", features.join(", "));
}
}
fn pad(str: &str, width: usize) -> String {
if str.len() >= width {
return str.to_string();
}
format!("{}{}", str, " ".repeat(width - str.len()))
}
fn make_features(forward_agent: bool, proxy: bool) -> Vec<String> {
let mut features = vec![];
if forward_agent {
features.push("forward_agent".to_string());
}
if proxy {
features.push("proxy".to_string());
}
features
}
fn parse_username_and_host(username_and_host: &str) -> XResult<(Option<String>, String)> {
if username_and_host.is_empty() {
return simple_error!("Empty username@host");
}
let username_and_host_parts = username_and_host.split("@").collect::<Vec<_>>();
if username_and_host_parts.len() == 1 {
return Ok((None, username_and_host_parts[0].to_string()));
}
if username_and_host_parts.len() > 2 {
return simple_error!("Bad username@host: {}", username_and_host);
}
Ok((
Some(username_and_host_parts[0].to_string()),
username_and_host_parts[1].to_string(),
))
}
fn load_ssh_rs_config() -> XResult<SshConfig> {
let config_file = get_ssh_rs_config_file();
let config_content = util_file::read_file_content(&config_file)?;
let config: SshConfig = opt_result!(
serde_json::from_str(config_content.as_str()),
"Parse config failed: {}"
);
Ok(config)
}
fn get_ssh_rs_config_file() -> String {
util_env::env_var(ENV_SSH_RS_CONFIG_FILE).unwrap_or_else(|| SSH_RS_CONFIG_FILE.to_string())
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260102T200840+08:00.MEUCIQCIoEsCJwGL/nO9MUwA
// q3eig5RAt+p0uE4YJPn4wIJtuwIgA+n+sXBgtYjBNZ0lDfB1+fVC7N/3K/LjeWHkxv3/J8k=

View File

@@ -38,7 +38,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
return Ok(());
}
};
let sync_url = "https://playsecurity.org/update_pages?".to_owned() + &page_name;
let sync_url = "https://play.hatter.me/update_pages?".to_owned() + &page_name;
information!("curl URL: {}", sync_url);
Command::new("curl").args(&[sync_url]).spawn()?.wait()?;
@@ -56,4 +56,7 @@ pub fn find_parents_exists_dir(dir: &str) -> Option<PathBuf> {
if !path.pop() { return None; }
}
}
}
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250620T220543+08:00.MEUCIHsFQ1sf53x3ATTLFkMQ
// oUau9y550grtnm7yGglEoDI/AiEAgZcouLIJXHP042IFnhkTljMo67O9Cs6MlpvNT+BzOA8=

461
update-meta-rs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,461 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "async-trait"
version = "0.1.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "backtrace"
version = "0.3.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bytes"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
[[package]]
name = "cc"
version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cpufeatures"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "gimli"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.156"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "miniz_oxide"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
]
[[package]]
name = "object"
version = "0.36.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9"
dependencies = [
"memchr",
]
[[package]]
name = "pin-project-lite"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "proc-macro2"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_users"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "rust_util"
version = "0.6.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bca5d3493eb29d08dc76ee784a78723fe366fec5dfe67ab37da9d50fb868f7c"
dependencies = [
"lazy_static",
"libc",
"term",
"term_size",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustversion"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "serde"
version = "1.0.208"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.208"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha256"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0"
dependencies = [
"async-trait",
"bytes",
"hex",
"sha2",
"tokio",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio"
version = "1.39.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
dependencies = [
"backtrace",
"bytes",
"pin-project-lite",
]
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "update-meta-rs"
version = "0.1.0"
dependencies = [
"rust_util",
"serde",
"serde_json",
"sha256",
]
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

10
update-meta-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "update-meta-rs"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rust_util = "0.6"
sha256 = "1.5"

248
update-meta-rs/src/main.rs Executable file
View File

@@ -0,0 +1,248 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! serde = { version = "1.0", features = ["derive"] }
//! serde_json = "1.0"
//! sha256 = "1.5"
//! rust_util = { version = "0.6" }
//! ```
use rust_util::{
debugging, failure_and_exit, iff, opt_result, opt_value_result, success, util_time, warning,
XResult,
};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fs;
use std::option::Option;
use std::path::PathBuf;
const SCRIPT_META_FILE: &str = "script-meta-v2.json";
const SCRIPT_CONFIG_FILE: &str = "script-config.json";
const SINGLE_SCRIPTS_DIR: &str = "single-scripts";
#[derive(Debug, Deserialize)]
struct ScriptConfig {
file_ext: String,
simple_script_url: String,
project_script_url: String,
script_sub_dir: Option<String>,
skip_dirs: Vec<String>,
}
impl ScriptConfig {
fn skip_dir(&self, dir: &str) -> bool {
for skip_dir in &self.skip_dirs {
if skip_dir == dir {
return true;
}
}
dir == "update-meta-rs" || dir == SINGLE_SCRIPTS_DIR || dir.starts_with(".")
}
}
#[derive(Serialize, Deserialize)]
struct ScriptMeta {
script_name: String,
script_length: u64,
script_sha256: String,
script_full_url: String,
#[serde(skip_serializing_if = "Option::is_none")]
single_script_file: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
publish_time: Option<u128>,
#[serde(skip_serializing_if = "Option::is_none")]
update_time: Option<u128>,
}
fn main() -> XResult<()> {
if fs::metadata(SCRIPT_CONFIG_FILE).is_err() {
failure_and_exit!("Script config file {} not found.", SCRIPT_CONFIG_FILE);
}
if fs::metadata(SCRIPT_META_FILE).is_err() {
failure_and_exit!("Script meta file {} not found.", SCRIPT_META_FILE);
}
let script_config_content = opt_result!(
fs::read_to_string(SCRIPT_CONFIG_FILE),
"Read {}, failed: {}",
SCRIPT_CONFIG_FILE
);
let script_config: ScriptConfig = opt_result!(
serde_json::from_str(&script_config_content),
"Parse {}, failed: {}",
SCRIPT_CONFIG_FILE
);
debugging!("Script config: {:#?}", script_config);
let former_script_meta_map = read_script_meta_map_from_file();
let mut script_meta_map = BTreeMap::new();
let current_read_dir = opt_result!(fs::read_dir("."), "Read dir '.' failed: {}");
for dir in current_read_dir {
let dir_entry = opt_result!(dir, "Get dir failed: {}");
let dir_file_type = opt_result!(dir_entry.file_type(), "Get dir type failed: {}");
let file_name_os_string = dir_entry.file_name();
let script_dir = opt_value_result!(file_name_os_string.to_str(), "Cannot get file name.");
if !dir_file_type.is_dir() {
debugging!("Skip none dir: {}", script_dir);
continue;
}
if script_config.skip_dir(&script_dir) {
debugging!("Skip update skip dirs: {}", script_dir);
continue;
}
let abs_dir_entry = std::path::absolute(&dir_entry.path())?;
let mut main_script = abs_dir_entry;
if let Some(sub_dir) = &script_config.script_sub_dir {
main_script = main_script.join(sub_dir);
}
main_script = main_script.join(format!("main.{}", script_config.file_ext));
if let Some(script_file_name) =
translate_script_dir_to_script_name(script_dir, &script_config)
{
script_meta_map.insert(
script_file_name.clone(),
read_script_meta(
script_dir,
script_file_name.clone(),
&main_script,
false,
&script_config,
&former_script_meta_map,
)?,
);
}
}
if let Ok(single_script_meta) = fs::metadata(SINGLE_SCRIPTS_DIR) {
if single_script_meta.is_dir() {
let single_scripts_read_dir =
opt_result!(fs::read_dir(SINGLE_SCRIPTS_DIR), "Read dir '.' failed: {}");
for file in single_scripts_read_dir {
let file_entry = opt_result!(file, "Get dir failed: {}");
let dir_file_type = opt_result!(file_entry.file_type(), "Get dir type failed: {}");
let file_name_os_string = file_entry.file_name();
let script_file =
opt_value_result!(file_name_os_string.to_str(), "Cannot get file name.");
if !dir_file_type.is_file() {
debugging!("Skip none file: {}", script_file);
continue;
}
let abs_file_entry = std::path::absolute(&file_entry.path())?;
let script_file_ext = format!(".{}", script_config.file_ext);
if !script_file.ends_with(&script_file_ext) {
continue;
}
let script_file_name = script_file.to_string();
if script_meta_map.contains_key(&script_file_name) {
warning!("Script: {script_file_name} exists.");
continue;
}
script_meta_map.insert(
script_file_name.clone(),
read_script_meta(
"",
script_file_name.clone(),
&abs_file_entry,
true,
&script_config,
&former_script_meta_map,
)?,
);
}
}
}
let script_meta_json = serde_json::to_string_pretty(&script_meta_map)?;
fs::write(SCRIPT_META_FILE, script_meta_json.as_bytes())?;
success!("Update file: {} succeed.", SCRIPT_META_FILE);
Ok(())
}
fn read_script_meta_map_from_file() -> BTreeMap<String, ScriptMeta> {
let script_meta_content = match fs::read_to_string(SCRIPT_META_FILE) {
Ok(script_meta_content) => script_meta_content,
Err(_) => return BTreeMap::new(),
};
serde_json::from_str(&script_meta_content).unwrap_or_default()
}
// translate filename-ext to filename.ext
fn translate_script_dir_to_script_name(
script_dir: &str,
script_config: &ScriptConfig,
) -> Option<String> {
let script_dir_ext = format!("-{}", script_config.file_ext);
if script_dir.ends_with(&script_dir_ext) {
let remove_ext_dir_name = script_dir
.chars()
.take(script_dir.len() - script_dir_ext.len())
.collect::<String>();
Some(format!("{remove_ext_dir_name}.{}", script_config.file_ext))
} else {
None
}
}
fn read_script_meta(
script_dir: &str,
script_name: String,
script_path: &PathBuf,
is_simple_script: bool,
script_config: &ScriptConfig,
former_script_meta_map: &BTreeMap<String, ScriptMeta>,
) -> XResult<ScriptMeta> {
let script_meta = opt_result!(
script_path.metadata(),
"Read file: {:?} meta failed: {}",
script_path
);
let script_path_content = fs::read(script_path)?;
let script_sha256 = sha256::digest(&script_path_content);
let script_full_url = if is_simple_script {
script_config
.simple_script_url
.replace("$NAME", &script_name)
} else {
script_config
.project_script_url
.replace("$NAME", script_dir)
};
let single_script_file = iff!(is_simple_script, Some(true), None);
let former_script_meta = former_script_meta_map.get(&script_name);
let publish_time = Some(
former_script_meta
.map(|m| m.publish_time)
.flatten()
.unwrap_or_else(|| util_time::get_current_millis()),
);
let is_file_same = former_script_meta
.map(|m| m.script_sha256 == script_sha256)
.unwrap_or(false);
let update_time = Some(if is_file_same {
former_script_meta
.map(|m| m.update_time)
.flatten()
.unwrap_or_else(|| util_time::get_current_millis())
} else {
util_time::get_current_millis()
});
Ok(ScriptMeta {
script_name: script_name.clone(),
script_length: script_meta.len(),
script_sha256,
script_full_url,
single_script_file,
publish_time,
update_time,
})
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234659+08:00.MEQCIGh/CL6KqLdAS2S6pLJ4
// l2OA+iZbMAtCKI2/+JdodvygAiBaDWCLWk8LRamwVXpF/Wz7U3CINzwRLKva6Pl+GnJ2CQ==

79
update-meta-v1.rs Executable file
View File

@@ -0,0 +1,79 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! serde = { version = "1.0", features = ["derive"] }
//! serde_json = "1.0"
//! sha256 = "1.5"
//! rust_util = { version = "0.6" }
//! ```
use rust_util::{debugging, failure_and_exit, opt_result, opt_value_result, success, XResult};
use serde::Serialize;
use std::collections::BTreeMap;
use std::fs;
use std::path::PathBuf;
const SCRIPT_META_FILE: &str = "script-meta.json";
#[derive(Serialize)]
struct ScriptMeta {
script_name: String,
script_length: u64,
script_sha256: String,
}
fn main() -> XResult<()> {
if fs::metadata(SCRIPT_META_FILE).is_err() {
failure_and_exit!("Script meta file {} not found.", SCRIPT_META_FILE);
}
let mut script_meta_map = BTreeMap::new();
let current_read_dir = opt_result!(fs::read_dir("."), "Read dir '.' failed: {}");
for dir in current_read_dir {
let dir_entry = opt_result!(dir, "Get dir failed: {}");
let dir_file_type = opt_result!(dir_entry.file_type(), "Get dir type failed: {}");
let file_name_os_string = dir_entry.file_name();
let script_dir = opt_value_result!(file_name_os_string.to_str(), "Cannot get file name.");
if !dir_file_type.is_dir() {
debugging!("Skip none dir: {}", script_dir);
continue;
}
if "update-meta-rs" == script_dir || "single-scripts" == script_dir || script_dir.starts_with(".") {
debugging!("Skip update meta rs: {}", script_dir);
continue;
}
let abs_dir_entry = std::path::absolute(&dir_entry.path())?;
let main_rs = abs_dir_entry
.join("src")
.join("main.rs");
script_meta_map.insert(
script_dir.to_string(),
read_script_meta(script_dir, &main_rs)?,
);
}
let script_meta_json = serde_json::to_string_pretty(&script_meta_map)?;
fs::write(SCRIPT_META_FILE, script_meta_json.as_bytes())?;
success!("Update file: {} succeed.", SCRIPT_META_FILE);
Ok(())
}
fn read_script_meta(file_name: &str, main_rs: &PathBuf) -> XResult<ScriptMeta> {
let main_rs_meta = opt_result!(main_rs.metadata(), "Read file: {:?} meta failed: {}", main_rs);
let main_rs_content = fs::read(main_rs)?;
let script_sha256 = sha256::digest(&main_rs_content);
Ok(ScriptMeta {
script_name: file_name.to_string(),
script_length: main_rs_meta.len(),
script_sha256,
})
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234717+08:00.MEUCIFFpFBYw5f4SzufUZI9j
// DI+Jm+U6pfFpjFdKdp+oE7OeAiEAuzj3FFaiJywjUXce1PnWq44f4Bxgn049DoF6rda90kY=

View File

@@ -1 +1,4 @@
ls | grep '\-rs$' > file-meta.txt
ls | grep -v update-meta-rs | grep '\-rs$' > file-meta.txt
./update-meta-rs/src/main.rs
./update-meta-v1.rs

323
xattr-rs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,323 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "bitflags"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "errno"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags",
"libc",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "proc-macro2"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "rust_util"
version = "0.6.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bca5d3493eb29d08dc76ee784a78723fe366fec5dfe67ab37da9d50fb868f7c"
dependencies = [
"lazy_static",
"libc",
"term",
"term_size",
]
[[package]]
name = "rustix"
version = "0.38.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "rustversion"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]]
name = "syn"
version = "2.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "xattr"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909"
dependencies = [
"libc",
"linux-raw-sys",
"rustix",
]
[[package]]
name = "xattr-rs"
version = "0.1.0"
dependencies = [
"rust_util",
"xattr",
]

8
xattr-rs/Cargo.toml Normal file
View File

@@ -0,0 +1,8 @@
[package]
name = "xattr-rs"
version = "0.1.0"
edition = "2021"
[dependencies]
rust_util = "0.6.47"
xattr = "1.4.0"

60
xattr-rs/src/main.rs Executable file
View File

@@ -0,0 +1,60 @@
#!/usr/bin/env runrs
//! ```cargo
//! [dependencies]
//! rust_util = "0.6.47"
//! xattr = "1.4.0"
//! ```
use rust_util::{failure, failure_and_exit, information};
fn main() {
let args = std::env::args().skip(1).collect::<Vec<_>>();
if args.is_empty() {
failure_and_exit!("No argument is assigned.");
}
for filename in &args {
match xattr::list(filename) {
Err(e) => {
failure!("Error read file: {filename}, error: {e}");
}
Ok(xattrs) => {
println!("File: {filename}");
for (_, xattr) in xattrs.enumerate() {
let clone_xattr = xattr.clone();
let xattr_name = match clone_xattr.to_str() {
None => {
continue;
}
Some(xattr_name) => xattr_name,
};
println!("{xattr_name}: ");
match xattr::get(filename, xattr) {
Err(e) => {
println!(" - read xattr: {xattr_name}, failed: {e}");
}
Ok(Some(value)) => {
println!(
"> {}",
String::from_utf8_lossy(value.as_ref())
.to_string()
.lines()
.collect::<Vec<_>>()
.join("\n> \n")
);
}
Ok(None) => {
// DO NOTHING
}
}
}
}
}
}
information!("use xattr -c <filename> to remove xattrs");
}
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250123T234640+08:00.MEUCIHb5YA6PBhddytgrgaam
// t0pnnQzoa0g3j80PISF91JYzAiEA7FXyF4RyK4ftu9FcKck+xTuF4aiiFoSnbrJYaxH8c1E=