1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-08-10 22:41:43 +02:00

Начало компоненты FTP

This commit is contained in:
Anton Titovets
2025-07-16 17:28:26 +03:00
parent a8c8c3aa9a
commit a842d098e5
15 changed files with 1451 additions and 0 deletions

BIN
docs/docusaurus/static/img/APIs/FTP.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
media/FTP.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

791
src/addins/ftp/Cargo.lock generated Normal file
View File

@@ -0,0 +1,791 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "addin1c"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef34e8b7ff4c43e87491a4cc30a4779a9f67c50db43378a36362c7a56246e05b"
dependencies = [
"smallvec",
"utf16_lit",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[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 = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bitflags"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "bumpalo"
version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
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.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"windows-link",
]
[[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-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[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 = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "futures-core"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-io"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-lite"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"parking",
"pin-project-lite",
]
[[package]]
name = "getrandom"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi",
]
[[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 = "itoa"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "js-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "lazy-regex"
version = "3.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60c7310b93682b36b98fa7ea4de998d3463ccbebd94d935d6b48ba5b6ffa7126"
dependencies = [
"lazy-regex-proc_macros",
"once_cell",
"regex",
]
[[package]]
name = "lazy-regex-proc_macros"
version = "3.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ba01db5ef81e17eb10a5e0f2109d1b3a3e29bac3070fdbd7d156bf7dbd206a1"
dependencies = [
"proc-macro2",
"quote",
"regex",
"syn",
]
[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "linux-raw-sys"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
[[package]]
name = "log"
version = "0.4.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "native-tls"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[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.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
[[package]]
name = "openssl"
version = "0.10.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-probe"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-sys"
version = "0.9.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "opi_mysql"
version = "0.1.0"
dependencies = [
"addin1c",
"native-tls",
"serde",
"serde_json",
"socks",
"suppaftp",
]
[[package]]
name = "parking"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[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 = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustix"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "rustversion"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "schannel"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
dependencies = [
"windows-sys",
]
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "serde"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.134"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socks"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b"
dependencies = [
"byteorder",
"libc",
"winapi",
]
[[package]]
name = "suppaftp"
version = "6.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9d869e942cc5f349ad91645925a9e6b570f62c4c170ad1c7b92b867bd16bd54"
dependencies = [
"chrono",
"futures-lite",
"lazy-regex",
"log",
"native-tls",
"thiserror",
]
[[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 = "tempfile"
version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [
"fastrand",
"getrandom",
"once_cell",
"rustix",
"windows-sys",
]
[[package]]
name = "thiserror"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
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 = "utf16_lit"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14706d2a800ee8ff38c1d3edb873cd616971ea59eb7c0d046bb44ef59b06a1ae"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[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.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-link"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[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 = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]

22
src/addins/ftp/Cargo.toml Normal file
View File

@@ -0,0 +1,22 @@
[package]
name = "opi_mysql"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[profile.release]
lto = "fat" # Enable Link Time Optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
panic = "abort" # Abort on panic
strip = true # Automatically strip symbols from the binary.
opt-level = "z"
[dependencies]
addin1c = "0.5.0"
suppaftp = { version = "6.3.0", features = ["native-tls", "secure"] }
serde_json = "1.0"
serde = { version = "1.0.217", features = ["derive"] }
native-tls = "0.2.14"
socks = "0.3.4"

View File

@@ -0,0 +1,15 @@
"MAIN ---"
linux-vdso.so.1 (0x00007ffec07be000)
libssl.so.3 => /lib64/libssl.so.3 (0x000075673a000000)
libcrypto.so.3 => /lib64/libcrypto.so.3 (0x0000756739800000)
libm.so.6 => /lib64/libm.so.6 (0x0000756739400000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000756739000000)
libc.so.6 => /lib64/libc.so.6 (0x0000756738c00000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000756738800000)
/lib64/ld-linux-x86-64.so.2 (0x000075673a600000)
libz.so.1 => /lib64/libz.so.1 (0x0000756738400000)
GLIBC_2.2.5
GLIBC_2.3
GLIBC_2.3.4
GLIBC_2.14
GLIBC_2.17

9
src/addins/ftp/release.bat vendored Normal file
View File

@@ -0,0 +1,9 @@
@echo off
:: Установить переменную
set CARGO_NAME=opi_mysql
set LIB_NAME=OPI_MySQL
set ADDIN_DIR=%~dp0
set FOLV=true
call ../build.bat

View File

@@ -0,0 +1,364 @@
mod ftp_client;
use addin1c::{name, Variant};
use crate::core::getset;
use serde_json::json;
use suppaftp::{FtpStream, NativeTlsConnector, NativeTlsFtpStream};
use suppaftp::native_tls::TlsConnector;
use suppaftp::types::Mode;
use serde::Deserialize;
use crate::component::ftp_client::FtpClient;
use std::net::TcpStream;
use std::sync::{Arc, Mutex};
use socks::{Socks4Stream, Socks5Stream};
// МЕТОДЫ КОМПОНЕНТЫ -------------------------------------------------------------------------------
// Синонимы
pub const METHODS: &[&[u16]] = &[
name!("Connect"),
name!("UpdateSettings"),
name!("UpdateProxy"),
name!("SetTLS")
];
// Число параметров функций компоненты
pub fn get_params_amount(num: usize) -> usize {
match num {
0 => 0,
1 => 1,
2 => 1,
3 => 3,
_ => 0,
}
}
// Соответствие функций Rust функциям компоненты
// Вызовы должны быть обернуты в Box::new
pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn getset::ValueType> {
match num {
0 => Box::new(obj.initialize()),
1 => {
let json_string = params[0].get_string().unwrap_or("".to_string());
Box::new(obj.update_settings(&json_string))
},
2 => {
let json_string = params[0].get_string().unwrap_or("".to_string());
Box::new(obj.update_proxy(&json_string))
},
3 => {
let use_tls = params[0].get_bool().unwrap_or(false);
let accept_invalid_certs = params[1].get_bool().unwrap_or(false);
let ca_cert_path = params[2].get_string().unwrap_or("".to_string());
Box::new(obj.set_tls(use_tls, accept_invalid_certs, &ca_cert_path))
}
_ => Box::new(false), // Неверный номер команды
}
}
// -------------------------------------------------------------------------------------------------
// ПОЛЯ КОМПОНЕНТЫ ---------------------------------------------------------------------------------
// Синонимы
pub const PROPS: &[&[u16]] = &[];
#[derive(Deserialize, Debug)]
struct FtpProxySettings {
server: String,
port: u16,
login: Option<String>,
password: Option<String>,
proxy_type: Option<String>, // "http", "socks4", "socks5"
}
#[derive(Deserialize, Debug)]
struct FtpSettings {
domain: Option<String>,
port: Option<u16>,
login: Option<String>,
password: Option<String>,
passive: Option<bool>,
timeout: Option<u64>,
}
pub struct AddIn {
domain: String,
port: u16,
login: Option<String>,
password: Option<String>,
passive: bool,
timeout: u64,
// TLS
use_tls: bool,
accept_invalid_certs: bool,
ca_cert_path: String,
client: Option<Arc<Mutex<FtpClient>>>,
// Proxy
proxy_server: Option<String>,
proxy_port: Option<u16>,
proxy_login: Option<String>,
proxy_password: Option<String>,
proxy_type: Option<String>,
}
impl AddIn {
pub fn new() -> Self {
AddIn {
client: None,
domain: String::new(),
port: 21,
login: None,
password: None,
passive: true,
timeout: 120,
use_tls: false,
accept_invalid_certs: false,
ca_cert_path: String::new(),
// Инициализация полей прокси
proxy_server: None,
proxy_port: None,
proxy_login: None,
proxy_password: None,
proxy_type: None,
}
}
pub fn update_settings(&mut self, json_data: &str) -> String {
let json_struct: FtpSettings = match serde_json::from_str(json_data){
Ok(s) => s,
Err(e) => return Self::process_error(&e.to_string()),
};
if let Some(domain) = json_struct.domain {
self.domain = domain;
}
if let Some(port) = json_struct.port {
self.port = port;
}
if let Some(passive) = json_struct.passive {
self.passive = passive;
}
if let Some(timeout) = json_struct.timeout {
self.timeout = timeout;
}
self.login = json_struct.login.or(self.login.clone());
self.password = json_struct.password.or(self.password.clone());
json!({"result": true}).to_string()
}
pub fn update_proxy(&mut self, json_data: &str) -> String {
let json_struct: FtpProxySettings = match serde_json::from_str(json_data){
Ok(s) => s,
Err(e) => return Self::process_error(&e.to_string()),
};
self.proxy_server = Some(json_struct.server);
self.proxy_port = Some(json_struct.port);
self.proxy_login = json_struct.login;
self.proxy_password = json_struct.password;
self.proxy_type = json_struct.proxy_type;
json!({"result": true}).to_string()
}
pub fn initialize(&mut self) -> String {
if self.domain.is_empty() {
return Self::process_error("Address must be initialized");
}
let tcp_stream = match self.create_tcp_connection() {
Ok(stream) => stream,
Err(e) => return e,
};
let client = match self.configure_ftp_client(tcp_stream) {
Ok(client) => client,
Err(e) => return e,
};
let login: Option<&str> = self.login.as_deref();
let password: Option<&str> = self.password.as_deref();
self.client = match client.login(login, password) {
Ok(auth) => Some(Arc::new(Mutex::new(auth))),
Err(e) => return Self::process_error(&e.to_string()),
};
json!({"result": true}).to_string()
}
fn configure_ftp_client(
&mut self,
tcp_stream: TcpStream,
) -> Result<FtpClient, String> {
let mode = if self.passive { Mode::Passive } else { Mode::Active };
if self.use_tls {
let tls_connector = self.get_tls_connector()?;
let ftp_stream = NativeTlsFtpStream::connect_with_stream(tcp_stream)
.map_err(|e| Self::process_error(&e.to_string()))?;
let mut secure_stream = ftp_stream
.into_secure(NativeTlsConnector::from(tls_connector), &self.domain)
.map_err(|e| Self::process_error(&e.to_string()))?;
secure_stream.set_mode(mode);
secure_stream.set_passive_nat_workaround(true);
Ok(FtpClient::Secure(secure_stream))
} else {
let mut ftp_stream = FtpStream::connect_with_stream(tcp_stream)
.map_err(|e| Self::process_error(&e.to_string()))?;
ftp_stream.set_mode(mode);
ftp_stream.set_passive_nat_workaround(true);
Ok(FtpClient::Insecure(ftp_stream))
}
}
fn create_tcp_connection(&self) -> Result<TcpStream, String> {
if let (Some(proxy_server), Some(proxy_port), Some(proxy_type)) =
(&self.proxy_server, &self.proxy_port, &self.proxy_type)
{
let target_addr = (self.domain.as_str(), self.port);
let proxy_addr = format!("{}:{}", proxy_server, proxy_port);
match proxy_type.to_lowercase().as_str() {
"socks5" => self.connect_via_socks5(&proxy_addr, target_addr),
"socks4" => self.connect_via_socks4(&proxy_addr, target_addr),
_ => Err(Self::process_error("Unsupported proxy type")),
}
} else {
self.connect_direct()
}
}
fn connect_via_socks5(&self, proxy_addr: &str, target_addr: (&str, u16)) -> Result<TcpStream, String> {
let stream = if let (Some(user), Some(pass)) = (&self.proxy_login, &self.proxy_password) {
Socks5Stream::connect_with_password(proxy_addr, target_addr, user, pass)
} else {
Socks5Stream::connect(proxy_addr, target_addr)
};
stream.map(|s| s.into_inner())
.map_err(|e| Self::process_error(&format!("SOCKS5 error: {}", e)))
}
fn connect_via_socks4(&self, proxy_addr: &str, target_addr: (&str, u16)) -> Result<TcpStream, String> {
let stream = if let Some(user) = &self.proxy_login {
Socks4Stream::connect(proxy_addr, target_addr, user)
} else {
Socks4Stream::connect(proxy_addr, target_addr, "")
};
stream.map(|s| s.into_inner())
.map_err(|e| Self::process_error(&format!("SOCKS4 error: {}", e)))
}
fn connect_direct(&self) -> Result<TcpStream, String> {
let addr = format!("{}:{}", &self.domain, &self.port);
TcpStream::connect(&addr).map_err(|e| Self::process_error(&format!("Direct connection error: {}", e)))
}
pub fn close_connection(&mut self) -> String {
if let Some(client) = self.client.take() {
match client.lock() {
Ok(mut locked_client) => {
match &mut *locked_client {
FtpClient::Secure(stream) => _ = stream.quit(),
FtpClient::Insecure(stream) => _ = stream.quit(),
}
}
Err(e) => return Self::process_error(&format!("Failed to lock client: {}", e)),
}
}
json!({"result": true}).to_string()
}
pub fn set_tls(&mut self, use_tls: bool, accept_invalid_certs: bool, ca_cert_path: &str) -> String {
if self.client.is_some(){
return Self::process_error("TLS settings can only be set before the connection is established");
};
self.accept_invalid_certs = accept_invalid_certs;
self.ca_cert_path = ca_cert_path.to_string();
self.use_tls = use_tls;
json!({"result": true}).to_string()
}
fn get_tls_connector(&mut self) -> Result<TlsConnector, String> {
let mut tls_builder = TlsConnector::builder();
tls_builder.danger_accept_invalid_certs(self.accept_invalid_certs);
if !self.ca_cert_path.is_empty() {
let cert_data = std::fs::read(&self.ca_cert_path)
.map_err(|e| Self::process_error(&e.to_string()))?;
let cert = native_tls::Certificate::from_pem(&cert_data)
.map_err(|e| Self::process_error(&e.to_string()))?;
tls_builder.add_root_certificate(cert);
}
match tls_builder.build(){
Ok(connector) => Ok(connector),
Err(e) => Err(Self::process_error(&e.to_string())),
}
}
fn process_error(e: &str) -> String{
json!({
"result": false,
"error": e
}).to_string()
}
pub fn get_field_ptr(&self, index: usize) -> *const dyn getset::ValueType {
match index {
_ => panic!("Index out of bounds"),
}
}
pub fn get_field_ptr_mut(&mut self, index: usize) -> *mut dyn getset::ValueType { self.get_field_ptr(index) as *mut _ }
}
// -------------------------------------------------------------------------------------------------
// УНИЧТОЖЕНИЕ ОБЪЕКТА -----------------------------------------------------------------------------
// Обработка удаления объекта
impl Drop for AddIn {
fn drop(&mut self) {}
}

View File

@@ -0,0 +1,78 @@
use addin1c::{Variant, Tm};
pub trait ValueType {
fn get_value(&self, val: &mut Variant) -> bool;
fn set_value(&mut self, val: &Variant);
}
// Реализация для i32
impl ValueType for i32 {
fn get_value(&self, val: &mut Variant) -> bool {
val.set_i32(*self);
true
}
fn set_value(&mut self, val: &Variant) {
*self = val.get_i32().unwrap_or(0);
}
}
// Реализация для f64
impl ValueType for f64 {
fn get_value(&self, val: &mut Variant) -> bool {
val.set_f64(*self);
true
}
fn set_value(&mut self, val: &Variant) {
*self = val.get_f64().unwrap_or(0.0);
}
}
// Реализация для bool
impl ValueType for bool {
fn get_value(&self, val: &mut Variant) -> bool {
val.set_bool(*self);
true
}
fn set_value(&mut self, val: &Variant) {
*self = val.get_bool().unwrap_or(false);
}
}
// Реализация для tm
impl ValueType for Tm {
fn get_value(&self, val: &mut Variant) -> bool {
val.set_date(*self);
true
}
fn set_value(&mut self, val: &Variant) {
*self = val.get_date().unwrap_or(Tm::default());
}
}
// Реализация для String
impl ValueType for String {
fn get_value(&self, val: &mut Variant) -> bool {
let s: Vec<u16> = self.encode_utf16().collect();
val.set_str1c(s.as_slice()).is_ok()
}
fn set_value(&mut self, val: &Variant) {
*self = val.get_string().unwrap_or("".to_string());
}
}
// Реализация для Vec<u8>
impl ValueType for Vec<u8> {
fn get_value(&self, val: &mut Variant) -> bool {
val.set_blob(self.as_slice()).is_ok()
}
fn set_value(&mut self, val: &Variant) {
*self = val.get_blob().unwrap_or(&[]).to_vec()
}
}

View File

@@ -0,0 +1,53 @@
pub mod getset;
use addin1c::{name, RawAddin, Variant};
use crate::component::METHODS;
use crate::component::PROPS;
use crate::component::get_params_amount;
use crate::component::cal_func;
use crate::component::AddIn;
// Определение класса
impl RawAddin for AddIn {
fn register_extension_as(&mut self) -> &'static [u16] {
name!("Main")
}
fn get_n_props(&mut self) -> usize {
PROPS.len()
}
fn find_prop(&mut self, name: &[u16]) -> Option<usize> {
PROPS.iter().position(|&x| x == name)
}
fn get_prop_name(&mut self, num: usize, _alias: usize) -> Option<&'static [u16]> { PROPS.get(num).copied() }
fn get_prop_val(&mut self, num: usize, val: &mut Variant) -> bool {let field: &dyn getset::ValueType = &self[num]; field.get_value(val) }
fn set_prop_val(&mut self, num: usize, val: &Variant) -> bool {let field: &mut dyn getset::ValueType = &mut self[num]; field.set_value(val); true }
fn is_prop_readable(&mut self, _num: usize) -> bool { true }
fn is_prop_writable(&mut self, _num: usize) -> bool { true }
fn get_n_methods(&mut self) -> usize { METHODS.len() }
fn find_method(&mut self, name: &[u16]) -> Option<usize> { METHODS.iter().position(|&x| x == name) }
fn get_method_name(&mut self, num: usize, _alias: usize) -> Option<&'static [u16]> { METHODS.get(num).copied() }
fn get_n_params(&mut self, num: usize) -> usize { get_params_amount(num) }
fn get_param_def_value(&mut self, _method_num: usize, _param_num: usize, _value: Variant, ) -> bool { true }
fn has_ret_val(&mut self, _num: usize) -> bool { true }
fn call_as_proc(&mut self, _num: usize, _params: &mut [Variant]) -> bool { false }
fn call_as_func(&mut self, num: usize, params: &mut [Variant], ret_value: &mut Variant, ) -> bool { cal_func(self, num, params).get_value(ret_value) }
}
impl std::ops::Index<usize> for AddIn {
type Output = dyn getset::ValueType;
fn index(&self, index: usize) -> &Self::Output {
unsafe { &*self.get_field_ptr(index) }
}
}
impl std::ops::IndexMut<usize> for AddIn {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
unsafe { &mut *self.get_field_ptr_mut(index) }
}
}

49
src/addins/ftp/src/lib.rs Normal file
View File

@@ -0,0 +1,49 @@
pub mod component;
mod core;
use std::{
ffi::{c_int, c_long, c_void},
sync::atomic::{AtomicI32, Ordering},
};
use component::AddIn;
use addin1c::{create_component, destroy_component, name, AttachType};
pub static mut PLATFORM_CAPABILITIES: AtomicI32 = AtomicI32::new(-1);
#[allow(non_snake_case)]
#[no_mangle]
pub unsafe extern "C" fn GetClassObject(_name: *const u16, component: *mut *mut c_void) -> c_long {
let addin = AddIn::new();
create_component(component, addin)
}
#[allow(non_snake_case)]
#[no_mangle]
pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
destroy_component(component)
}
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn GetClassNames() -> *const u16 {
// small strings for performance
name!("Main").as_ptr()
}
#[allow(non_snake_case)]
#[no_mangle]
#[allow(static_mut_refs)]
pub unsafe extern "C" fn SetPlatformCapabilities(capabilities: c_int) -> c_int {
PLATFORM_CAPABILITIES.store(capabilities, Ordering::Relaxed);
3
}
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn GetAttachType() -> AttachType {
AttachType::Any
}

View File

@@ -0,0 +1,50 @@
// OneScript: ./OInt/core/Modules/OPI_FTP.os
// Lib: FTP
// CLI: ftp
// Keywords: ftp, ftps
// MIT License
// Copyright (c) 2023-2025 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
// BSLLS:Typo-off
// BSLLS:LatinAndCyrillicSymbolInWord-off
// BSLLS:IncorrectLineBreak-off
// BSLLS:NumberOfOptionalParams-off
// BSLLS:UsingServiceTag-off
// BSLLS:LineLength-off
// BSLLS:UsingSynchronousCalls-off
// BSLLS:MagicNumber-off
//@skip-check module-structure-top-region
//@skip-check module-structure-method-in-regions
//@skip-check wrong-string-literal-content
//@skip-check method-too-many-params
#Область ПрограммныйИнтерфейс
#Область ОсновныеМетоды
#КонецОбласти
#КонецОбласти

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="4b20914a-129a-449b-b361-8d62ca43ffd8">
<name>OPI_FTP</name>
<synonym>
<key>ru</key>
<value>FTP (ОПИ)</value>
</synonym>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonTemplate xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="4d395e12-f3b7-4903-9db6-289028ccf30e">
<name>OPI_FTP</name>
<synonym>
<key>ru</key>
<value>FTP (OPI)</value>
</synonym>
<templateType>AddIn</templateType>
</mdclass:CommonTemplate>

Binary file not shown.