diff --git a/.cargo/config.toml b/.cargo/config.toml index 484657a..6481193 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -3,7 +3,6 @@ rustflags = ["-C", "target-feature=+crt-static"] [target.x86_64-unknown-linux-musl] rustflags = ["-C", "target-feature=-crt-static"] -linker = "musl-gcc" [target.x86_64-apple-darwin] rustflags = ["-C", "target-feature=-crt-static"] diff --git a/Cargo.lock b/Cargo.lock index 8bb8dc5..f91cf94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,9 +24,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -39,9 +39,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -54,59 +54,41 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys", ] -[[package]] -name = "anyhow" -version = "1.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" - -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "bitflags" -version = "2.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" - [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "cc" -version = "1.2.39" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", "shlex", @@ -114,15 +96,15 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ "iana-time-zone", "js-sys", @@ -143,19 +125,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.48" +version = "4.5.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806" dependencies = [ "clap_builder", - "clap_derive", ] [[package]] name = "clap_builder" -version = "4.5.48" +version = "4.5.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2" dependencies = [ "anstream", "anstyle", @@ -163,23 +144,11 @@ dependencies = [ "strsim", ] -[[package]] -name = "clap_derive" -version = "4.5.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "clap_lex" -version = "0.7.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" [[package]] name = "colorchoice" @@ -189,15 +158,15 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "console" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" +checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" dependencies = [ "encode_unicode", "libc", "once_cell", "unicode-width", - "windows-sys 0.61.1", + "windows-sys", ] [[package]] @@ -242,41 +211,14 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ - "generic-array 0.14.7", + "generic-array", "typenum", ] -[[package]] -name = "derive_more" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - -[[package]] -name = "destructure_traitobject" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7" - [[package]] name = "either" version = "1.15.0" @@ -290,22 +232,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] -name = "equivalent" -version = "1.0.2" +name = "fern" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "4316185f709b23713e41e3195f90edef7fb00c3ed4adc79769cf09cc762a3b29" +dependencies = [ + "log", +] [[package]] name = "find-msvc-tools" -version = "0.1.2" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "generic-array" @@ -317,39 +256,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "generic-array" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c8444bc9d71b935156cc0ccab7f622180808af7867b1daae6547d773591703" -dependencies = [ - "typenum", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi", -] - -[[package]] -name = "hashbrown" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "hermit-abi" version = "0.5.2" @@ -362,17 +268,11 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "humantime" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" - [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -392,21 +292,11 @@ dependencies = [ "cc", ] -[[package]] -name = "indexmap" -version = "2.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" -dependencies = [ - "equivalent", - "hashbrown", -] - [[package]] name = "indicatif" -version = "0.18.0" +version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a646d946d06bedbbc4cac4c218acf4bbf2d87757a784857025f4d447e4e1cd" +checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" dependencies = [ "console", "portable-atomic", @@ -421,26 +311,20 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" 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" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "js-sys" -version = "0.3.81" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -448,75 +332,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.176" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" - -[[package]] -name = "lock_api" -version = "0.4.13" +version = "0.2.182" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" -dependencies = [ - "autocfg", - "scopeguard", -] +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" [[package]] name = "log" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" -dependencies = [ - "serde", -] - -[[package]] -name = "log-mdc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" - -[[package]] -name = "log4rs" -version = "1.4.0" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e947bb896e702c711fccc2bf02ab2abb6072910693818d1d6b07ee2b9dfd86c" -dependencies = [ - "anyhow", - "arc-swap", - "chrono", - "derive_more", - "fnv", - "humantime", - "libc", - "log", - "log-mdc", - "mock_instant", - "parking_lot", - "rand", - "serde", - "serde-value", - "serde_json", - "serde_yaml", - "thiserror", - "thread-id", - "typemap-ors", - "unicode-segmentation", - "winapi", -] - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "mock_instant" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce6dd36094cac388f119d2e9dc82dc730ef91c32a6222170d630e5414b956e6" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "num-traits" @@ -545,62 +369,21 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" - -[[package]] -name = "ordered-float" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" -dependencies = [ - "num-traits", -] - -[[package]] -name = "parking_lot" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.6", -] +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -612,59 +395,24 @@ dependencies = [ "aes", "chrono", "clap", - "generic-array 1.2.0", + "fern", + "generic-array", "hex", "indicatif", "log", - "log4rs", "num_cpus", "rayon", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom", -] - [[package]] name = "rayon" version = "1.11.0" @@ -685,111 +433,18 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.5.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" -dependencies = [ - "bitflags", -] - [[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 = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[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-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" -dependencies = [ - "ordered-float", - "serde", -] - -[[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 = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - [[package]] name = "strsim" version = "0.11.1" @@ -798,104 +453,38 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.106" +version = "2.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "thiserror" -version = "2.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread-id" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99043e46c5a15af379c06add30d9c93a6c0e8849de00d244c4a2c417da128d80" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "typemap-ors" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68c24b707f02dd18f1e4ccceb9d49f2058c2fb86384ef9972592904d7a28867" -dependencies = [ - "unsafe-any-ors", -] - [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-ident" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "unicode-width" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" - -[[package]] -name = "unicode-xid" -version = "0.2.6" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unit-prefix" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817" - -[[package]] -name = "unsafe-any-ors" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a303d30665362d9680d7d91d78b23f5f899504d4f08b3c4cf08d055d87c0ad" -dependencies = [ - "destructure_traitobject", -] - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" [[package]] name = "utf8parse" @@ -909,29 +498,11 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen", -] - [[package]] name = "wasm-bindgen" -version = "0.2.104" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", @@ -940,25 +511,11 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - [[package]] name = "wasm-bindgen-macro" -version = "0.2.104" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -966,22 +523,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.104" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.104" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] @@ -996,33 +553,11 @@ dependencies = [ "wasm-bindgen", ] -[[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-core" -version = "0.62.1" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", @@ -1033,9 +568,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.1" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -1044,9 +579,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.2" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -1055,206 +590,33 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-result" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] [[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" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.4", -] - -[[package]] -name = "windows-sys" -version = "0.61.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] - -[[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.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/Cargo.toml b/Cargo.toml index b8e2d16..87c5364 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,14 +13,14 @@ include = ["src/**", "Cargo.toml", "README*", "LICENSE*"] [dependencies] -clap = { version = "4.5.2", features = ["derive"] } +clap = { version = "4.5.2", features = ["cargo"] } aes = "0.8.4" hex = "0.4.3" indicatif = "0.18.0" rayon = "1.9.0" -generic-array = "1.2.0" +generic-array = "0.14.7" log = "0.4" -log4rs = "1.0" +fern = "0.7.1" chrono = "0.4" num_cpus = "1.17.0" @@ -38,6 +38,6 @@ path = "src/lib.rs" crate-type = ["cdylib", "rlib"] [[bin]] -name = "ps3decrs" +name = "ps3dec" path = "src/main.rs" diff --git a/README.md b/README.md index d334dfc..88e6eb1 100644 --- a/README.md +++ b/README.md @@ -28,33 +28,26 @@ keeping the data in memory. Decrypting MX vs. ATV Untamed (USA) in less than 2 seconds on a fast enough rig! sometimes increasing the thread count too high might add a slight overhead for the dec process to start. - - Please bear in mind this demonstration is done on some very idealistic conditions with a very good CPU and a good SSD. - - https://github.com/user-attachments/assets/978c1827-d788-449a-a52f-6743e94cb4db - ## Usage -| Option | Description | Note | -|-----------------|-------------------------------------------------------------------|-----------------------------------------------------------| -| `--iso` | For the ISO file | | -| `--dk` | For decryption key, a base-16 hex key | | -| `--tc` | Thread count, specifies the number of threads | Be careful with this one | -| `--auto` | Enables automatic key detection and decryption | Will only work if there is the key in the **keys** folder | -| `--skip` | Disables the press any key to exit after decryption | | -| `--output_dir` | output directory destination for the decrypted iso | | -| `--output_name` | output file name for the decrypted iso | | -| `--chunk-size` | how big the chunk of the iso is processed at the same time in MIB | Read down below about chunk size section. | - +| Option | Description | Note | +|--------------------------|-------------------------------------------------------------------|-------------------------------------------------------------| +| `-k`, `--decryption_key` | For decryption key, a base-16 hex key | | +| `-t`, `--num_threads` | Thread count, specifies the number of threads | Be careful with this one | +| `--auto` | Enables automatic key detection and decryption | Will only work if there is the key in the **./keys** folder | +| `-s`, `--skip` | Disables the press any key to exit after decryption | | +| `-o`, `--output_dir` | output directory destination for the decrypted iso | | +| `-n`, `--output_name` | output file name for the decrypted iso | | +| `-c`, `--chunk_size` | how big the chunk of the iso is processed at the same time in MIB | Read down below about chunk size section. | ``` -ps3dec.exe --iso game.iso --dk yourdecryptionkey --tc 64 --chunk-size 16 +ps3dec game.iso -k yourdecryptionkey -t 64 -c 16 ``` If you don't want to keep changing your decryption key every time you can use --auto flag , which will look @@ -63,11 +56,11 @@ here [Aldostools dkeys](https://ps3.aldostools.org/dkey.html) , to note that o key are compatible. ``` -ps3dec.exe --iso game.iso --auto --tc 64 +ps3dec game.iso --auto -t 64 ``` ### about chunk size parameter -I have added a new flag called `--chunk-size` It defines how many bytes you read, decrypt, and write per thread! +I have added a new flag called `--chunk_size` It defines how many bytes you read, decrypt, and write per thread! we batch sectors in a chunk and decrypt them then write to disk. this was a request, and I am not sure how much benefit this can bring besides tweaking ram and disk usage. diff --git a/src/args.rs b/src/args.rs deleted file mode 100644 index 7f6faab..0000000 --- a/src/args.rs +++ /dev/null @@ -1,36 +0,0 @@ - -#[derive(Debug, clap::Parser)] -#[clap( - author, version, - about = "PS3dec Remake is a remake of the original PS3 DISC decryption tool in rust", - long_about = "PS3Dec is a tool to decrypt PS3 Redump ISOs..." -)] -pub struct Ps3decargs { - #[clap(help = "Path to the PS3 ISO file to decrypt.")] - pub iso: String, - - #[clap(short = 'k', long = "dk", help = "Decryption key (32 hex).", conflicts_with = "auto")] - pub dk: Option, - - #[clap(short = 't', long = "tc", help = "Thread count.", default_value = "32")] - pub tc: usize, - - #[clap(short, long, help = "Autodetect key from ISO name.", action = clap::ArgAction::SetTrue)] - pub auto: bool, - - #[clap(short = 's', long = "skip", help = "Skip exit confirmation.", action = clap::ArgAction::SetTrue)] - pub skip: bool, - - #[clap(short = 'o', long = "output-dir", help = "Output directory.")] - pub output_dir: Option, - - #[clap(short = 'n', long = "output-name", help = "Output filename (without extension).")] - pub output_name: Option, - - #[clap(long = "chunk-size", help = "Chunk size in MiB.")] - pub chunk_size: Option, -} - - - -pub const DEFAULT_CHUNK: Option = Some(16 * 1024 * 1024); diff --git a/src/autodetect.rs b/src/autodetect.rs index be42ba3..498d4bf 100644 --- a/src/autodetect.rs +++ b/src/autodetect.rs @@ -2,7 +2,7 @@ use log::{info, warn}; use std::fs; // Only usable if the keys folder exists -pub fn detect_key(game_name: String) -> Result, String> { +pub fn detect_key(game_name: &str) -> Result, String> { match fs::read_dir("keys") { Ok(files) => { for entry in files { @@ -11,9 +11,9 @@ pub fn detect_key(game_name: String) -> Result, String> { if filepath.is_file() && filepath - .file_name() - .and_then(|n| n.to_str()) - .is_some_and(|filename| filename.contains(&game_name)) + .file_name() + .and_then(|n| n.to_str()) + .is_some_and(|filename| filename.contains(&game_name)) { let msg = format!("Found key: {}", filepath.display()); info!("{}", &msg); @@ -44,4 +44,4 @@ pub fn detect_key(game_name: String) -> Result, String> { Err(e.to_string()) } } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index c89cb9c..916f0c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,8 @@ pub mod autodetect; pub mod utils; -pub mod args; use aes::Aes128Dec; -use aes::cipher::{KeyInit, BlockDecryptMut}; use aes::cipher::generic_array::{GenericArray, typenum::U16}; +use aes::cipher::{BlockDecryptMut, KeyInit}; use hex::decode; use indicatif::{ProgressBar, ProgressStyle}; use log::info; @@ -13,30 +12,28 @@ use std::io::{self, BufReader}; use std::path::Path; use std::sync::Arc; use std::time::Instant; -use utils::{ extract_regions, generate_iv, is_encrypted}; +use utils::{extract_regions, generate_iv, is_encrypted}; const SECTOR_SIZE: usize = 2048; -use crate::args::DEFAULT_CHUNK; - +pub const DEFAULT_CHUNK: usize = 16 * 1024 * 1024; pub fn decrypt( - file_path: String, + file_path: &Path, decryption_key: &str, - thread_count: usize, - output_dir: Option, - output_name: Option, - chunk_size: Option, + num_threads: usize, + output_dir: Option<&Path>, + output_name: Option<&Path>, + chunk_bytes: usize, ) -> io::Result<()> { info!("Starting decryption process."); let start_time = Instant::now(); rayon::ThreadPoolBuilder::new() - .num_threads(thread_count.max(1)) + .num_threads(num_threads.max(1)) .build_global() .unwrap_or_else(|e| info!("Failed to set thread count, using default: {}", e)); - let key_bytes = decode(decryption_key.trim()) - .map_err(|e| io::Error::other(e.to_string()))?; + let key_bytes = decode(decryption_key.trim()).map_err(|e| io::Error::other(e.to_string()))?; if key_bytes.len() != 16 { return Err(io::Error::other( "decryption key must be 16 bytes (32 hex chars)", @@ -55,7 +52,7 @@ pub fn decrypt( info!( "File size: {:.2} MB, Total sectors: {}", - total_size as f64 / 1_048_576.0, + total_size as f64 / (1024.0 * 1024.0), total_sectors ); @@ -65,26 +62,25 @@ pub fn decrypt( let in_file = Arc::new(input_file); let output_file_path = if let Some(dir) = output_dir { - let path = Path::new(&file_path); let file_name = if let Some(name) = output_name { - format!("{name}.iso") + name.with_extension("iso") } else { - let stem = path.file_stem().and_then(|s| s.to_str()).unwrap_or("decrypted"); - format!("{stem}_decrypted.iso") + file_path.with_extension("dec.iso") }; let output_dir_path = Path::new(&dir); if !output_dir_path.exists() { fs::create_dir_all(output_dir_path)?; } - output_dir_path.join(file_name).to_string_lossy().to_string() + output_dir_path.join(file_name) } else if let Some(name) = output_name { - format!("{name}.iso") + name.with_extension("iso") } else { - format!("{file_path}_decrypted.iso") + file_path.with_extension("dec.iso") }; - info!("Output will be written to: {}", output_file_path); + info!("Output will be written to: {}", output_file_path.display()); - let out_file = OpenOptions::create(OpenOptions::new().write(true), true).open(&output_file_path)?; + let out_file = + OpenOptions::create(OpenOptions::new().write(true), true).open(&output_file_path)?; out_file.set_len(total_size)?; let out_file = Arc::new(out_file); @@ -95,62 +91,64 @@ pub fn decrypt( .unwrap() .progress_chars("█▓▒░"), ); - let chunk_bytes = chunk_size - .map(|mib| mib.saturating_mul(1024 * 1024)) - .unwrap_or(DEFAULT_CHUNK.unwrap()); let chunk_sectors = (chunk_bytes / SECTOR_SIZE).max(1); let tasks: Vec<(usize, usize)> = (0..total_sectors) .step_by(chunk_sectors) .map(|s| (s, (s + chunk_sectors).min(total_sectors))) .collect(); - tasks.into_par_iter().for_each(|(start_sector, end_sector)| { - let mut buf = vec![0u8; SECTOR_SIZE * (end_sector - start_sector)]; - if let Err(e) = utils::read_exact_at( - &in_file, - &mut buf, - (start_sector as u64) * (SECTOR_SIZE as u64), - ) { - eprintln!("Error reading data: {}", e); - return; - } - - let mut aes_core = Aes128Dec::new(&key_ga); - for (i, sector) in buf.chunks_mut(SECTOR_SIZE).enumerate() { - let sector_index = start_sector + i; - if !is_encrypted(®ions, sector_index as u64, sector) { - continue; + tasks + .into_par_iter() + .for_each(|(start_sector, end_sector)| { + let mut buf = vec![0u8; SECTOR_SIZE * (end_sector - start_sector)]; + if let Err(e) = utils::read_exact_at( + &in_file, + &mut buf, + (start_sector as u64) * (SECTOR_SIZE as u64), + ) { + eprintln!("Error reading data: {}", e); + return; } - let iv_ga = generate_iv(sector_index as u64); - let mut prev = [0u8; 16]; - prev.copy_from_slice(iv_ga.as_slice()); + let mut aes_core = Aes128Dec::new(&key_ga); + for (i, sector) in buf.chunks_mut(SECTOR_SIZE).enumerate() { + let sector_index = start_sector + i; + if !is_encrypted(®ions, sector_index as u64, sector) { + continue; + } + + let iv_ga = generate_iv(sector_index as u64); + let mut prev = [0u8; 16]; + prev.copy_from_slice(iv_ga.as_slice()); - for block in sector.chunks_exact_mut(16) { - let mut cur = [0u8; 16]; - cur.copy_from_slice(block); + for block in sector.chunks_exact_mut(16) { + let mut cur = [0u8; 16]; + cur.copy_from_slice(block); - aes_core.decrypt_block_mut(GenericArray::from_mut_slice(block)); - for k in 0..16 { - block[k] ^= prev[k]; + aes_core.decrypt_block_mut(GenericArray::from_mut_slice(block)); + for k in 0..16 { + block[k] ^= prev[k]; + } + prev = cur; } - prev = cur; } - } - let off = (start_sector as u64) * (SECTOR_SIZE as u64); - if let Err(e) = utils::write_all_at(&out_file, &buf, off) { - eprintln!("Error writing data at offset {}: {}", off, e); - } + let off = (start_sector as u64) * (SECTOR_SIZE as u64); + if let Err(e) = utils::write_all_at(&out_file, &buf, off) { + eprintln!("Error writing data at offset {}: {}", off, e); + } - progress_bar.inc((end_sector - start_sector) as u64); - }); + progress_bar.inc((end_sector - start_sector) as u64); + }); progress_bar.finish_with_message("Decryption completed"); let elapsed = start_time.elapsed(); - info!("Decryption completed in {:.2} seconds.", elapsed.as_secs_f64()); - info!("Data written to {}", output_file_path); + info!( + "Decryption completed in {:.2} seconds.", + elapsed.as_secs_f64() + ); + info!("Data written to {}", output_file_path.display()); Ok(()) } diff --git a/src/main.rs b/src/main.rs index 67a623d..a400e88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,126 +1,160 @@ - -use clap::Parser; -use log::{ error, info}; +use clap::{Arg, ArgAction, command, crate_authors, crate_version}; +use log::{error, info}; +use std::env; use std::io::{self}; -use std::path::Path; -use std::{env,}; +use std::path::PathBuf; use std::process::exit; -pub mod args; pub mod autodetect; pub mod utils; +use ps3dec::DEFAULT_CHUNK; -pub use utils::{ - read_exact_at, write_all_at, extract_regions, generate_iv, is_encrypted, - setup_logging, -}; -use crate::args::{Ps3decargs, DEFAULT_CHUNK}; +// use crate::args::{DEFAULT_CHUNK, Ps3decargs}; use crate::autodetect::detect_key; use crate::utils::key_validation; +pub use utils::{ + extract_regions, generate_iv, is_encrypted, read_exact_at, setup_logging, write_all_at, +}; // Either drag and drop which will auto-detect key, OR launch through CLI. fn main() -> io::Result<()> { - let args: Vec = env::args().collect(); - if args.len() == 2 && args[1] == "--help" { - let _ = Ps3decargs::parse_from(["", "--help"]); - return Ok(()); - } setup_logging().expect("Failed to setup logging"); - let ps3_args = Ps3decargs::parse(); - if args.len() == 2 { - // drag & drop / single-arg path - let raw = &args[1]; - let dragdrop = raw.trim_matches(|c| c == '"' || c == '\''); - let path = Path::new(dragdrop); - let is_iso = path - .extension() - .and_then(|e| e.to_str()) - .map(|e| e.eq_ignore_ascii_case("iso")) - .unwrap_or(false); + let matches = command!() + .author(crate_authors!("\n")) + .version(crate_version!()) + .about("PS3dec Remake is a remake of the original PS3 DISC decryption tool in rust") + .long_about("PS3Dec is a tool to decrypt PS3 Redump ISOs...") + .arg( + Arg::new("iso") + .help("Path to the PS3 ISO file to decrypt.") + .required(true), + ) + .arg( + Arg::new("decryption_key") + .short('k') + .long("decryption-key") + .help("Decryption key (32 hex).") + .conflicts_with("auto"), + ) + .arg( + Arg::new("num_threads") + .short('t') + .long("num_threads") + .help("Number of threads to use for decryption.") + .default_value("16"), + ) + .arg( + Arg::new("auto") + .long("auto") + .help("Autodetect key from ISO name.") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new("skip") + .short('s') + .long("skip") + .help("Skip exit confirmation.") + .action(ArgAction::SetTrue), + ) + .arg( + Arg::new("output_dir") + .short('o') + .long("output_dir") + .help("Output directory."), + ) + .arg( + Arg::new("output_name") + .short('n') + .long("output_name") + .help("Output filename (without extension)."), + ) + .arg( + Arg::new("chunk_size") + .short('c') + .long("chunk_size") + .help("Chunk size in MiB."), // can't use default_value() because clap is ass + ) + .get_matches(); - if is_iso { - let filename = path.file_stem().and_then(|f| f.to_str()).unwrap_or(""); + // Can't directly convert to PathBuf because yet again clap is ass. + let Some(iso_path) = matches.get_one::("iso") else { + error!("The iso path must be a valid path"); + exit(1); + }; + let iso_path = PathBuf::from(iso_path); + + let is_iso = iso_path + .extension() + .and_then(|e| e.to_str()) + .map(|e| e.eq_ignore_ascii_case("iso")) + .unwrap_or(false); + if !is_iso { + error!("The file must be an ISO file with .iso extension"); + exit(1); + } - info!("ISO path: {}", path.display()); - if let Ok(c) = path.canonicalize() { - info!("Canonical path: {}", c.display()); - } - info!("Filename used for key lookup: {}", filename); + let filename = iso_path.file_stem().and_then(|f| f.to_str()).unwrap_or(""); + info!("ISO path: {}", iso_path.display()); + if let Ok(c) = iso_path.canonicalize() { + info!("Canonical path: {}", c.display()); + } + info!("Filename used for key lookup: {}", filename); - match detect_key(filename.to_string()) { - Ok(Some(key)) => { - info!("Detected key for {}: {}", filename, key); - ps3dec::decrypt(dragdrop.to_string(), &key, num_cpus::get(), None, None,DEFAULT_CHUNK)?; - } - _ => error!("No key found for {}", filename), - } + let decryption_key = if matches.get_flag("auto") { + if let Ok(Some(key)) = detect_key(filename) { + info!("Auto-detected key for {}: {}", filename, key); + key } else { - error!("The file must be an ISO file with .iso extension"); + error!("No key could be auto-detected for {}", filename); + exit(1); } - } else if args.len() > 1 { - let ps3_args = Ps3decargs::parse(); - let p = Path::new(&ps3_args.iso); - let is_iso = p - .extension() - .and_then(|e| e.to_str()) - .map(|e| e.eq_ignore_ascii_case("iso")) - .unwrap_or(false); - if !is_iso { - error!("The file must be an ISO file with .iso extension"); - return Ok(()); + } else if let Some(key) = matches.get_one::("decryption_key") { + if key_validation(&key) { + info!("Using provided decryption key: {}", key); + key.clone() + } else { + error!("Invalid PS3 decryption key format."); + exit(1); } + } else { + error!("Decryption key is required unless '--auto' is specified."); + exit(1); + }; - let filename = p.file_stem().and_then(|f| f.to_str()).unwrap_or(""); - info!("ISO path: {}", p.display()); - if let Ok(c) = p.canonicalize() { - info!("Canonical path: {}", c.display()); - } - info!("Filename used for key lookup: {}", filename); + let num_threads = matches.get_one::("num_threads").unwrap(); + let num_threads = usize::from_str_radix(num_threads, 10).unwrap(); + let output_dir = matches + .get_one::("output_dir") + .map(|f| f.as_path()); + let output_name = matches + .get_one::("output_name") + .map(|f| f.as_path()); - if ps3_args.auto { - if let Ok(Some(key)) = detect_key(filename.to_string()) { - info!("Auto-detected key for {}: {}", filename, key); - ps3dec::decrypt( - ps3_args.iso, - &key, - ps3_args.tc, - ps3_args.output_dir, - ps3_args.output_name, - ps3_args.chunk_size - )?; - } else { - error!("No key could be auto-detected for {}", filename); - } - } else if let Some(dk) = ps3_args.dk { - if key_validation(&dk) { - info!("Using provided decryption key: {}", dk); - ps3dec::decrypt( - ps3_args.iso, - &dk, - ps3_args.tc, - ps3_args.output_dir, - ps3_args.output_name, - ps3_args.chunk_size, - )?; - } else { - error!("Error: Invalid PS3 decryption key format."); - } - } else { - error!("Error: Decryption key is required unless '--auto' is specified."); - } + let chunk_bytes = match matches.get_one::("chunk_size") { + Some(s) => usize::from_str_radix(s, 10) + .map(|mib| mib.saturating_mul(1024 * 1024)) + .unwrap(), + None => DEFAULT_CHUNK, + }; - } else { - error!("Please provide an ISO file path. Use --help for more information."); - exit(0) - } + ps3dec::decrypt( + &iso_path, + &decryption_key, + num_threads, + output_dir, + output_name, + chunk_bytes, + )?; - if !ps3_args.skip { + if !matches.get_flag("skip") { info!("Job done, press any button to exit..."); let mut input_string = String::new(); - io::stdin().read_line(&mut input_string).expect("Failed to read line"); + io::stdin() + .read_line(&mut input_string) + .expect("Failed to read line"); info!("Ciao!"); } Ok(()) -} \ No newline at end of file +} diff --git a/src/utils.rs b/src/utils.rs index bb7b8d7..d467a01 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,16 +1,11 @@ use aes::cipher::consts::U16; use aes::cipher::generic_array::GenericArray; use chrono::Local; -use log::{info, warn, LevelFilter}; +use fern::Dispatch; +use log::{LevelFilter, info, warn}; use std::fs::File; +use std::io::{Read, Seek, SeekFrom}; use std::{fs, io}; -use std::io::{ Read, Seek, SeekFrom}; -use log4rs::{ - append::{console::ConsoleAppender, file::FileAppender}, - config::{Appender, Config, Root}, - encode::pattern::PatternEncoder, -}; - #[cfg(unix)] use std::os::unix::fs::FileExt as _; @@ -18,12 +13,13 @@ use std::os::unix::fs::FileExt as _; use std::os::windows::fs::FileExt as _; use std::path::Path; - #[cfg(unix)] pub fn read_exact_at(file: &File, mut buf: &mut [u8], mut off: u64) -> io::Result<()> { while !buf.is_empty() { let n = file.read_at(buf, off)?; - if n == 0 { return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "read_at=0")); } + if n == 0 { + return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "read_at=0")); + } buf = &mut buf[n..]; off += n as u64; } @@ -33,7 +29,9 @@ pub fn read_exact_at(file: &File, mut buf: &mut [u8], mut off: u64) -> io::Resul pub fn read_exact_at(file: &File, mut buf: &mut [u8], mut off: u64) -> io::Result<()> { while !buf.is_empty() { let n = file.seek_read(buf, off)?; - if n == 0 { return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "seek_read=0")); } + if n == 0 { + return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "seek_read=0")); + } buf = &mut buf[n..]; off += n as u64; } @@ -44,7 +42,9 @@ pub fn read_exact_at(file: &File, mut buf: &mut [u8], mut off: u64) -> io::Resul pub fn write_all_at(file: &File, mut buf: &[u8], mut off: u64) -> io::Result<()> { while !buf.is_empty() { let n = file.write_at(buf, off)?; - if n == 0 { return Err(io::Error::new(io::ErrorKind::WriteZero, "write_at=0")); } + if n == 0 { + return Err(io::Error::new(io::ErrorKind::WriteZero, "write_at=0")); + } buf = &buf[n..]; off += n as u64; } @@ -54,14 +54,15 @@ pub fn write_all_at(file: &File, mut buf: &[u8], mut off: u64) -> io::Result<()> pub fn write_all_at(file: &File, mut buf: &[u8], mut off: u64) -> io::Result<()> { while !buf.is_empty() { let n = file.seek_write(buf, off)?; - if n == 0 { return Err(io::Error::new(io::ErrorKind::WriteZero, "seek_write=0")); } + if n == 0 { + return Err(io::Error::new(io::ErrorKind::WriteZero, "seek_write=0")); + } buf = &buf[n..]; off += n as u64; } Ok(()) } - pub struct Region { start: u64, end: u64, @@ -105,8 +106,6 @@ pub fn is_encrypted(regions: &[Region], sector: u64, sector_data: &[u8]) -> bool regions.iter().any(|r| sector >= r.start && sector < r.end) } - - // Splitting the cake pub fn extract_regions(reader: &mut R) -> io::Result> { let mut header = [0u8; 4096]; @@ -138,33 +137,25 @@ pub fn extract_regions(reader: &mut R) -> io::Result Ok(regions) } - pub fn setup_logging() -> Result<(), Box> { let log_dir = Path::new("log"); fs::create_dir_all(log_dir)?; let now = Local::now(); let log_file_name = format!("log/{}.log", now.format("%Y-%m-%d_%H-%M-%S")); - let fmt = "{d(%Y-%m-%d %H:%M:%S)} [{l}] - {m}\n"; - - let stdout = ConsoleAppender::builder() - .encoder(Box::new(PatternEncoder::new(fmt))) - .build(); - - let logfile = FileAppender::builder() - .encoder(Box::new(PatternEncoder::new(fmt))) - .build(log_file_name)?; - - let config = Config::builder() - .appender(Appender::builder().build("stdout", Box::new(stdout))) - .appender(Appender::builder().build("logfile", Box::new(logfile))) - .build( - Root::builder() - .appender("stdout") - .appender("logfile") - .build(LevelFilter::Trace), - )?; + Dispatch::new() + .format(move |out, message, record| { + out.finish(format_args!( + "{} [{}] - {}", + now.format("%Y-%m-%d_%H-%M-%S"), + record.level(), + message + )) + }) + .level(LevelFilter::Debug) + .chain(std::io::stdout()) + .chain(fern::log_file(log_file_name)?) + .apply()?; - log4rs::init_config(config)?; Ok(()) }