From 6b9433f75681557646eb3d3340e5074b33190c0c Mon Sep 17 00:00:00 2001 From: Begild Date: Tue, 2 Jul 2024 18:37:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AC=A1=E6=8F=90=E4=BA=A4=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=201.=20=E5=AE=8C=E6=88=90=E5=9F=BA=E6=9C=AC=E7=9A=84r?= =?UTF-8?q?pc=E7=9A=84=E8=B0=83=E7=94=A8=E5=9B=9E=E8=B0=83=202.=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BA=86config=E7=9A=84=E8=A7=A3=E6=9E=90=20?= =?UTF-8?q?3.=20=E6=94=AF=E6=8C=81=E4=BA=86file=20handle=E7=9A=84=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 - Cargo.lock | 1222 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 28 + build.rs | 4 + proto/lws.proto | 163 ++++++ src/fs_impl/mod.rs | 154 ++++++ src/lib.rs | 423 +++++++++++++++ src/main.rs | 3 + src/server.rs | 33 ++ 9 files changed, 2030 insertions(+), 1 deletion(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 build.rs create mode 100644 proto/lws.proto create mode 100644 src/fs_impl/mod.rs create mode 100644 src/lib.rs create mode 100644 src/main.rs create mode 100644 src/server.rs diff --git a/.gitignore b/.gitignore index 3ca43ae..61ae5aa 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,3 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb - diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..22199e4 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1222 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cc" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[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.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "lws_vfs" +version = "0.1.0" +dependencies = [ + "prost", + "serde", + "serde_json", + "tokio", + "tonic", + "tonic-build", + "winapi", + "windows", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap 2.2.6", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" +dependencies = [ + "bytes", + "heck", + "itertools", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "syn" +version = "2.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio" +version = "1.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tonic" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4ef6dd70a610078cb4e338a0f79d06bc759ff1b22d2120c2ff02ae264ba9c2" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054d31561409bbf7e1ee4a4f0a1233ac2bb79cfadf2a398438a04d8dda69225f" +dependencies = [ + "windows-sys 0.28.0", +] + +[[package]] +name = "windows-sys" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6" +dependencies = [ + "windows_aarch64_msvc 0.28.0", + "windows_i686_gnu 0.28.0", + "windows_i686_msvc 0.28.0", + "windows_x86_64_gnu 0.28.0", + "windows_x86_64_msvc 0.28.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..9adbd63 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "lws_vfs" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[[bin]] # Bin to run the HelloWorld gRPC server +name = "lws_vfs-server" +path = "src/server.rs" + +[dependencies] +tonic = "0.11" +prost = "0.12" +tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } +winapi = { version = "0.3", features = [ + "fileapi", + "minwinbase", + "minwindef", + "timezoneapi", + "winnt", +] } +windows = "0.28" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" + +[build-dependencies] +tonic-build = "0.11" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..a38129c --- /dev/null +++ b/build.rs @@ -0,0 +1,4 @@ +fn main() -> Result<(), Box> { + tonic_build::compile_protos("proto/lws.proto")?; + Ok(()) +} \ No newline at end of file diff --git a/proto/lws.proto b/proto/lws.proto new file mode 100644 index 0000000..39a804c --- /dev/null +++ b/proto/lws.proto @@ -0,0 +1,163 @@ +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package lws_vfs; + +service LwsVfs { + // Sends a greeting + rpc SayHello(HelloRequest) returns (HelloReply) {} + + rpc fgetattr(getattr) returns (getattr) {} + rpc fsetxattr(setxattr) returns (setxattr) {} + rpc faccess(access) returns (access) {} + rpc freaddir(readdir) returns (readdir) {} + rpc fread(read) returns (read) {} + rpc fopen(open) returns (open) {} + rpc fwrite(write) returns (write) {} + rpc fgetxattr(getxattr) returns (getxattr) {} + rpc ftruncate(truncate) returns (truncate) {} + rpc futimens(utimens) returns (utimens) {} + rpc fchown(chown) returns (chown) {} + rpc frelease(release) returns (release) {} + rpc fmkdir(mkdir) returns (mkdir) {} +} + +// The request message containing the user's name. +message HelloRequest { string name = 1; } + +// The response message containing the greetings +message HelloReply { string message = 1; } + +message file_info { + int32 flags = 1; + uint32 fh_old = 2; + bool direct_io = 3; + uint64 fh = 10; + uint64 lock_owner = 11; +} + +message fstat { + uint64 fst_mode = 1; + uint64 fst_ino = 2; + uint64 fst_dev = 3; + uint64 fst_rdev = 4; + uint64 fst_nlink = 5; + uint64 fst_uid = 6; + uint64 fst_gid = 7; + uint64 fst_size = 8; + uint64 fst_atime = 9; + uint64 fst_mtime = 10; + uint64 fst_ctime = 11; + uint64 fst_blksize = 12; + uint64 fst_blocks = 13; +} + +// fuse api function message define: +message getattr { + string path = 1; + fstat stat = 2; + int32 ret = 15; +} + +message setxattr { + string path = 1; + string name = 2; + bytes value = 3; + int64 size = 4; + uint32 flags = 5; + int32 ret = 15; +} +message getxattr { + string path = 1; + string name = 2; + bytes value = 3; + int64 size = 4; + int32 ret = 15; +} + +message access { + string path = 1; + uint32 mask = 2; + int32 ret = 15; +} + +message readdir { + string path = 1; + repeated string dirs = 2; + uint32 offset = 3; + file_info fi = 4; + int32 ret = 15; +} + +message open { + string path = 1; + file_info fi = 2; + int32 ret = 15; +} + +message read { + string path = 1; + bytes buff = 2; + int64 size = 3; + int64 offset = 4; + file_info fi = 5; + int32 ret = 15; +} + +message write { + string path = 1; + bytes buff = 2; + int64 size = 3; + int64 offset = 4; + file_info fi = 5; + int32 ret = 15; +} + +message truncate { + string path = 1; + int64 size = 3; + int32 ret = 15; +} + +message timespec { + int32 tv_sec = 1; + int64 tv_nsec = 2; +} +message utimens { + string path = 1; + repeated timespec ts = 2; // const struct timespec ts[2] + int32 ret = 15; +} + +message chown { + string path = 1; + int32 uid = 2; + int32 gid = 3; + int32 ret = 15; +} + +message release { + string path = 1; + file_info fi = 2; + int32 ret = 15; +} + +message mkdir { + string path = 1; + file_info fi = 2; + uint32 mode = 3; + int32 ret = 15; +} diff --git a/src/fs_impl/mod.rs b/src/fs_impl/mod.rs new file mode 100644 index 0000000..b86bac9 --- /dev/null +++ b/src/fs_impl/mod.rs @@ -0,0 +1,154 @@ +use std::fs; + +use std::io::{self, Seek as ioSeek}; +use std::error::Error; + +use crate::lws_vfs::{Fstat, FileInfo}; + +extern crate winapi; +use winapi::um::winnt::{FILE_ATTRIBUTE_READONLY}; +use std::os::windows::fs::MetadataExt; +use std::os::windows::prelude::*; + +fn from_metadata(sta: &mut Fstat, metadata: &fs::Metadata) -> Result<(), Box> { + sta.fst_size = metadata.len(); + // sta.fst_mtime = metadata + // .modified()?.duration_since(SystemTime::UNIX_EPOCH) + // .map(|d| d.as_secs() as u64)?; + sta.fst_mtime = metadata.last_write_time(); + sta.fst_ctime = metadata.creation_time(); + sta.fst_atime = metadata.last_access_time(); + Ok(()) +} +pub fn fgetattr(path: &String, sta: &mut Fstat, _fi: &mut FileInfo) -> Result> { + let metadata = fs::metadata(path)?; + from_metadata(sta, &metadata)?; + let perm = get_file_mode_mask(path); + sta.fst_mode = perm as u64; + Ok(0) +} + +pub fn fopen(path: &String, _fi: &mut FileInfo) -> Result>{ + return Ok(fs::File::open(path)?); +} + +pub fn fread(path: &String, buffer:&mut Vec, _size:&mut usize, offsize: usize, _fi: &mut FileInfo) -> Result> { + let mut file = fs::File::open(path)?; + match file.seek_read(buffer,offsize as u64){ + Ok(_) =>{}, + Err(_) => { + buffer.resize(file.stream_position()? as usize - offsize, 0); + } + } + Ok(0) +} + +pub fn fwrite(path: &String, buffer: &Vec, size: &mut usize, offsize: usize, _fi: &mut FileInfo, +) -> Result> { + let mut file = fs::File::open(path)?; + match file.seek_write(buffer,offsize as u64){ + Ok(_) =>{}, + Err(_) => { + *size = file.stream_position()? as usize - offsize; + } + } + Ok(0) +} +pub fn freaddir(path: &String, buffer: &mut Vec, _size: usize, _offset: usize, _fi: &mut FileInfo, +) -> Result> { + let mut readed = fs::read_dir(path)?; + loop { + match readed.next() { + Some(Ok(entry)) => { + let name = entry.file_name().into_string().unwrap(); + buffer.push(name); + } + Some(Err(e)) => { + return Err(Box::new(e)); + } + None => { + break; + } + } + } + Ok(0) +} +pub fn fmkdir(path: &String, _mode: u32) -> Result> { + fs::create_dir(path)?; + Ok(0) +} +pub fn fchown(_path: &String, _uid: u32, _gid: u32) -> Result> { + Ok(-1) +} +pub fn ftruncate(path: &String, _size: usize) -> Result> { + fs::OpenOptions::new().write(true).truncate(true).open(path)?; + Ok(0) +} + +use std::fs::OpenOptions; +use winapi::um::fileapi::SetFileTime; +use winapi::shared::minwindef::FILETIME; +use winapi::shared::minwindef::DWORD; +use std::ptr::null_mut; +use winapi::ctypes::c_void; +fn system_time_to_file_time(seconds: u64, nanoseconds: u32) -> FILETIME { + let total_nanoseconds = (seconds * 1_000_000_000) + nanoseconds as u64; + let total_100_nanoseconds = total_nanoseconds / 100; + FILETIME { + dwLowDateTime: total_100_nanoseconds as DWORD, + dwHighDateTime: (total_100_nanoseconds >> 32) as DWORD, + } +} +pub fn futimens(path: &String, a:& Vec, m: & Vec) -> Result> { + let file = OpenOptions::new().write(true).open(path)?; + let handle = file.as_raw_handle(); + + let atime = system_time_to_file_time(a[0], a[1] as u32); + let mtime = system_time_to_file_time(m[0], m[1] as u32); + + let result = unsafe { + SetFileTime(handle as *mut c_void, null_mut(), &atime, &mtime) + }; + + if result != 0 { + Ok(0) + } else { + Err(Box::new(io::Error::last_os_error())) + } +} +pub fn frelease(_path: &String, _fi: &mut FileInfo) -> Result> { + Ok(0) +} +pub fn fsetxattr(_path: &String,_name: &str,_value:&Vec,_size: usize,_flags: u32 +) -> Result> { + Ok(-1) +} +pub fn fgetxattr(_path: &String, _name: &str, _size: usize) -> Result> { + Ok(-1) +} + +fn get_file_mode_mask(path:&str) -> u32{ + let mut permissions = 0; + let metadata = match fs::metadata(path){ + Ok(metadata) => metadata, + Err(_) => { + println!("get {} metadata fail", path); + return permissions; + } + }; + let attributes = metadata.file_attributes(); + // let permissions = metadata.permissions(); + if attributes & FILE_ATTRIBUTE_READONLY != 0 { + permissions |= 0o222; + } else { + permissions |= 0o444 | 0o222; + } + if metadata.is_dir() { + permissions |= 0o111; + } + permissions +} +pub fn faccess(path: &String, mask: u32) -> Result> { + let permissions = get_file_mode_mask(path); + Ok(if permissions & mask != 0 {0} else {-1}) +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..534b2d9 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,423 @@ +use lws_vfs::lws_vfs_server::LwsVfs; +use lws_vfs::{HelloReply, HelloRequest, Getattr, Setxattr, Access, Readdir, Read, Open,Write,Getxattr,Truncate,Utimens,Chown, Release, Fstat, FileInfo, Mkdir}; +use tonic::{Request, Response, Status}; +use serde_json::{self, Value}; +use std::fs::File; +use std::io::{BufReader, Read as _}; +use std::error::Error; +use std::collections::HashMap; +use std::sync::{Arc,Mutex}; +mod fs_impl; +pub mod lws_vfs { + tonic::include_proto!("lws_vfs"); +} + +// config +// +// { +// "mount": { +// "c:\\": "/l3c", +// "w:\\": "/l0e", +// "y:\\": "/l0d" +// }, +// "port":5001 +// } +// +#[derive(Debug, Default)] +pub struct Config{ + port:u16, + mount_map:HashMap, +} +impl Config{ + pub fn new(json:&str) -> Result> { + let mut file = File::open(json)?; + let mut buffer = String::new(); + file.read_to_string(&mut buffer)?; + let json:Value = serde_json::from_str(buffer.as_ref())?; + let port:u16 = match json.get("port"){ + Some(port) => port.as_u64().expect("expect port is a number but its not") as u16, + None => { + 5001 + } + }; + let mounts = match json.get("mount"){ + Some(mounts) => mounts.as_object().unwrap(), + None => { + return Err(Box::new(std::io::Error::new(std::io::ErrorKind::Other, "no mount map"))) + } + }; + let mount_map = mounts.iter().map(|(key,value)|{ + (key.as_str().to_string(),value.as_str().unwrap().to_string()) + }).collect(); + Ok(Config{ + port, + mount_map + }) + } + + pub fn get_port(&self) -> u16 { + self.port + } +} + +#[derive(Debug, Default)] +struct FileFdMgnt { + // key is fd, value is FileHandle + files:HashMap, + curr_fd:u64, +} + +impl FileFdMgnt { + pub fn new() -> FileFdMgnt { + FileFdMgnt{ + curr_fd:3, + files:HashMap::new() + } + } + fn gen_fd(&mut self) -> Result> { + let refd = self.curr_fd; + loop{ + self.curr_fd += 1; + match self.files.get(&self.curr_fd){ + Some(_) => {} + None => { + break; + } + } + if refd == self.curr_fd { + return Err(Box::new(std::io::Error::new(std::io::ErrorKind::Other, "no fd"))) + } + } + Ok(self.curr_fd) + } + pub fn push(&mut self, handle:File) -> Result> { + let fd = self.gen_fd()?; + self.files.insert(fd, handle); + Ok(fd) + } + pub fn pop(&mut self, fd:u64){ + if let Some(handle) = self.files.remove(&fd){ + drop(handle); + } + else{ + println!("not found fd:{}", fd); + } + } +} + +/// server 的基础结构 +#[derive(Debug, Default)] +pub struct LwsVfsIns { + pub config: Config, + file_fds: Arc>, +} + +impl LwsVfsIns { + pub fn new(json:&str) -> Result> { + Ok(LwsVfsIns{ + config:Config::new(json)?, + file_fds:Arc::new(Mutex::new(FileFdMgnt::new())), + }) + } + fn lpath(&self, path:&String) -> String { + let mut ret = String::new(); + for (k,v) in &self.config.mount_map{ + if path.starts_with(v){ + ret = path.replace(v, k); + break; + } + } + ret + } +} + +#[tonic::async_trait] +impl LwsVfs for LwsVfsIns { + async fn say_hello(&self, request: Request) -> Result, Status> { + println!("Got a request: {:?}", request); + + let reply = HelloReply { + message: format!("Hello {}!", request.into_inner().name), + }; + + Ok(Response::new(reply)) + } + async fn fgetattr(&self, request: Request) -> Result, Status> { + println!("Got a request: {:?}", request); + + let request = request.into_inner(); + let path = &self.lpath(&request.path); + let mut fstat = Fstat::default(); + let mut fi = FileInfo::default(); + let ret = match fs_impl::fgetattr(path, & mut fstat, &mut fi){ + Ok(ret) => ret, + Err(e) => { + println!("Error getting file metadata: {:?}", e); + -1 + } + }; + let reply = Getattr { + path:path.to_string(), + stat:Some(fstat), + ret, + }; + Ok(Response::new(reply)) + } + async fn fopen(&self, request: Request) -> Result, Status> { + println!("Got a request: {:?}", request); + let request = request.into_inner(); + let path = &self.lpath(&request.path); + let mut fi =request.fi.unwrap(); + let ret = match fs_impl::fopen(path, &mut fi){ + Ok(file) => { + match self.file_fds.lock().unwrap().push(file){ + Ok(fd) => fi.fh = fd, + Err(e) => { + println!("Error pushing file[{}]: {:?}", path, e); + } + }; + 0 + } + Err(e) => { + println!("Error opening file[{}]: {:?}", path, e); + -1 + } + }; + let reply = Open { + path: path.to_string(), + fi:Some(fi), + ret, + }; + Ok(Response::new(reply)) + } + async fn fread(&self, request: Request) -> Result, Status> { + println!("Got a request: {:?}", request); + let request = request.into_inner(); + let mut fi = request.fi.unwrap(); + let path = &self.lpath(&request.path); + let mut size:usize = request.size.try_into().unwrap(); + let offset:usize = request.offset.try_into().unwrap(); + let mut buff: Vec = Vec::with_capacity(size); + unsafe { buff.set_len(size); } + match fs_impl::fread(path, &mut buff, &mut size, offset, &mut fi){ + Ok(ret) => { + let reply = Read { + path: request.path, + size: buff.len() as i64, + buff, + offset: offset as i64, + fi: Some(fi), + ret, + }; + Ok(Response::new(reply)) + }, + Err(e) => { + println!("Error reading file[{}]: {:?}", path, e); + let reply = Read { + path: request.path, + buff: Vec::new(), + size: 0, + offset: 0, + fi: Some(fi), + ret: -1, + }; + Ok(Response::new(reply)) + } + } + } + async fn fwrite(&self, request: Request) -> Result, Status> { + let request = request.into_inner(); + let mut fi = request.fi.unwrap(); + let path = &self.lpath(&request.path); + let buff = request.buff; + let mut size = request.size as usize; + let offset = request.offset as usize; + let ret = match fs_impl::fwrite(path, &buff, &mut size, offset, &mut fi) { + Ok(ret) => { + ret + }, + Err(e) => { + println!("Error fwrite file[{}]: {:?}", path, e); + -1 + } + }; + let reply = Write { + ret, + size:size as i64, + ..Default::default() + }; + Ok(Response::new(reply)) + + } + async fn faccess( &self, request: Request,) -> Result, Status> { + let request = request.into_inner(); + let path = &self.lpath(&request.path); + let mask = request.mask; + let ret = match fs_impl::faccess(path, mask) { + Ok(ret) => { + ret + }, + Err(e) => { + println!("Error access file[{}]: {:?}", path, e); + -1 + } + }; + let reply = Access { + ret, + path:path.to_string(), + mask, + }; + Ok(Response::new(reply)) + } + + async fn fsetxattr(&self, request: Request) -> Result, Status> { + let req = request.into_inner(); + let path = &self.lpath(&req.path); + let name = req.name.as_ref(); + let value = req.value; + let size = req.size as usize; + let flags = req.flags; + let ret = match fs_impl::fsetxattr(path, name, &value, size, flags) { + Ok(ret) => ret, + Err(e) => { + println!("Error: setxattr file[{}]: {:?}", path, e); + -1 + }, + }; + let reply = Setxattr{ + ret: ret, + ..Setxattr::default() + }; + Ok(Response::new(reply)) + } + async fn fgetxattr(&self, request: Request) -> Result, Status> { + let req = request.into_inner(); + let path = &self.lpath(&req.path); + let name = req.name.as_ref(); + let size = req.size as usize; + let ret = match fs_impl::fgetxattr(path, name, size) { + Ok(ret) => ret, + Err(e) => { + println!("Error: getxattr file[{}]: {:?}", path, e); + -1 + } + }; + let reply = Getxattr{ + ret, + ..Getxattr::default() + }; + Ok(Response::new(reply)) + } + + async fn freaddir(&self, request: Request) -> Result, Status> { + let request = request.into_inner(); + let mut fi = request.fi.unwrap(); + let path = &self.lpath(&request.path); + let offset = request.offset as usize; + let mut dirs: Vec = Vec::new(); + let size = 0; + let ret = match fs_impl::freaddir(path, &mut dirs, size, offset, &mut fi) { + Ok(ret) => ret, + Err(e) => { + println!("Error: readdir file[{}]: {:?}", path, e); + -1 + } + }; + let reply = Readdir{ + ret, + dirs, + ..Readdir::default() + }; + Ok(Response::new(reply)) + } + async fn fmkdir(&self, request: Request) -> Result, Status> { + let request = request.into_inner(); + let path = &self.lpath(&request.path); + let mode = request.mode; + let ret = match fs_impl::fmkdir(&path, mode) { + Ok(ret) => ret, + Err(e) => { + println!("Error: mkdir [{}]: {:?}", path, e); + -1 + } + }; + let reply = Mkdir{ + ret, + ..Mkdir::default() + }; + Ok(Response::new(reply)) + } + async fn ftruncate(&self, request: Request) -> Result, Status> { + let request= request.into_inner(); + let path = &self.lpath(&request.path); + let size = request.size as usize; + let ret = match fs_impl::ftruncate(path, size) { + Ok(ret) => ret, + Err(e) => { + println!("Error: truncate file[{}]: {:?}", path, e); + -1 + } + }; + let reply = Truncate{ + ret, + ..Truncate::default() + }; + Ok(Response::new(reply)) + } + + async fn futimens(&self, request: Request) -> Result, Status> { + let request = request.into_inner(); + let path = &self.lpath(&request.path); + let a_time = vec![request.ts[0].tv_sec as u64, request.ts[0].tv_nsec as u64]; + let m_time = vec![request.ts[1].tv_sec as u64, request.ts[1].tv_nsec as u64]; + let ret = match fs_impl::futimens(path, &a_time, &m_time) { + Ok(ret) => ret, + Err(e) => { + println!("Error: futimens file[{}]: {:?}", path, e); + -1 + } + }; + let reply = Utimens{ + ret, + ..Utimens::default() + }; + Ok(Response::new(reply)) + } + + async fn fchown(&self, request: Request) -> Result, Status> { + let request = request.into_inner(); + let path = &self.lpath(&request.path); + let uid = request.uid as u32; + let gid = request.gid as u32; + let ret = match fs_impl::fchown(path, uid, gid) { + Ok(ret) => ret, + Err(e) => { + println!("Error: chown file[{}]: {:?}", path, e); + -1 + } + }; + let reply = Chown{ + ret, + ..Chown::default() + }; + Ok(Response::new(reply)) + } + async fn frelease(&self, request: Request) -> Result, Status> { + let request = request.into_inner(); + let path = &self.lpath(&request.path); + let mut fi = request.fi.unwrap(); + self.file_fds.lock().unwrap().pop(fi.fh); + let ret = match fs_impl::frelease(path, &mut fi) { + Ok(ret) => ret, + Err(e) => { + println!("Error: release file[{}]: {:?}", path, e); + -1 + } + }; + let reply = Release{ + ret, + ..Release::default() + }; + Ok(Response::new(reply)) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..270214e --- /dev/null +++ b/src/server.rs @@ -0,0 +1,33 @@ +use tonic::transport; + +use lws_vfs::LwsVfsIns; +use lws_vfs::lws_vfs::lws_vfs_server::LwsVfsServer; + +// fn main() { +// println!("Hello, world!"); +// let file = "test.txt"; +// let mut sta = Stat { +// st_size: 0, +// st_mode: 0, +// }; +// let mut fi = FuseFileInfo {}; +// getattr(file, &mut sta, &mut fi); +// } + +#[tokio::main] +async fn main() -> Result<(), Box> { + let instance = match LwsVfsIns::new("config.json"){ + Ok(greeter) => greeter, + Err(e) => { + println!("Error creating lws server instance: {:?}", e); + return Err(e); + } + }; + let addr = format!("[::1]:{}", instance.config.get_port()); + println!("Listening on {}", addr); + transport::Server::builder() + .add_service(LwsVfsServer::new(instance)) + .serve(addr.parse()?) + .await?; + Ok(()) +}