From a6acbf61a098deca7cbdbf0399cdc49261a70245 Mon Sep 17 00:00:00 2001 From: FollieHiyuki Date: Thu, 2 Jun 2022 20:43:56 +0700 Subject: [PATCH 1/4] Update dependencies fuse_mt, time and zip --- rage/Cargo.toml | 6 +++--- rage/src/bin/rage-mount/tar.rs | 21 +++++++++++---------- rage/src/bin/rage-mount/zip.rs | 16 ++++++++-------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/rage/Cargo.toml b/rage/Cargo.toml index 103a292d..23910d25 100644 --- a/rage/Cargo.toml +++ b/rage/Cargo.toml @@ -66,11 +66,11 @@ pinentry = "0.5" rust-embed = "6" # rage-mount dependencies -fuse_mt = { version = "0.5.1", optional = true } +fuse_mt = { version = "0.6.0", optional = true } libc = { version = "0.2", optional = true } tar = { version = "0.4", optional = true } -time = { version = "0.1", optional = true } -zip = { version = "0.5.9", optional = true } +time = { version = "0.3.7", optional = true } +zip = { version = "0.6.2", optional = true } [dev-dependencies] clap = "3.1" diff --git a/rage/src/bin/rage-mount/tar.rs b/rage/src/bin/rage-mount/tar.rs index 69f33507..abaa5670 100644 --- a/rage/src/bin/rage-mount/tar.rs +++ b/rage/src/bin/rage-mount/tar.rs @@ -5,8 +5,9 @@ use std::fs::File; use std::io::{self, BufReader, Read, Seek, SeekFrom}; use std::path::{Path, PathBuf}; use std::sync::Mutex; +use std::time::{Duration, SystemTime}; + use tar::{Archive, Entry, EntryType}; -use time::Timespec; fn tar_path(path: &Path) -> &Path { path.strip_prefix("/").unwrap() @@ -28,11 +29,11 @@ fn tar_to_fuse(entry: &Entry) -> io::Result { .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Unsupported filetype"))?; let perm = (entry.header().mode()? & 0o7777) as u16; - let mtime = Timespec::new(entry.header().mtime()? as i64, 0); + let mtime = SystemTime::UNIX_EPOCH + Duration::new(entry.header().mtime()? as u64, 0); let ctime = if let Some(header) = entry.header().as_gnu() { header .ctime() - .map(|ctime| Timespec::new(ctime as i64, 0)) + .map(|ctime| SystemTime::UNIX_EPOCH + Duration::new(ctime as u64, 0)) .unwrap_or(mtime) } else { mtime @@ -40,7 +41,7 @@ fn tar_to_fuse(entry: &Entry) -> io::Result { let atime = if let Some(header) = entry.header().as_gnu() { header .atime() - .map(|atime| Timespec::new(atime as i64, 0)) + .map(|atime| SystemTime::UNIX_EPOCH + Duration::new(atime as u64, 0)) .unwrap_or(mtime) } else { mtime @@ -52,7 +53,7 @@ fn tar_to_fuse(entry: &Entry) -> io::Result { atime, mtime, ctime, - crtime: Timespec { sec: 0, nsec: 0 }, + crtime: SystemTime::UNIX_EPOCH, kind, perm, nlink: 1, @@ -66,10 +67,10 @@ fn tar_to_fuse(entry: &Entry) -> io::Result { const ROOT_ATTR: FileAttr = FileAttr { size: 0, blocks: 0, - atime: Timespec { sec: 0, nsec: 0 }, - mtime: Timespec { sec: 0, nsec: 0 }, - ctime: Timespec { sec: 0, nsec: 0 }, - crtime: Timespec { sec: 0, nsec: 0 }, + atime: SystemTime::UNIX_EPOCH, + mtime: SystemTime::UNIX_EPOCH, + ctime: SystemTime::UNIX_EPOCH, + crtime: SystemTime::UNIX_EPOCH, kind: FileType::Directory, perm: 0o0755, nlink: 1, @@ -143,7 +144,7 @@ impl AgeTarFs { } } -const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; +const TTL: Duration = Duration::from_secs(1); impl FilesystemMT for AgeTarFs { fn getattr(&self, _req: RequestInfo, path: &Path, fh: Option) -> ResultEntry { diff --git a/rage/src/bin/rage-mount/zip.rs b/rage/src/bin/rage-mount/zip.rs index 3d8074b3..6b303a41 100644 --- a/rage/src/bin/rage-mount/zip.rs +++ b/rage/src/bin/rage-mount/zip.rs @@ -5,7 +5,7 @@ use std::fs::File; use std::io::{self, BufReader, Read}; use std::path::{Path, PathBuf}; use std::sync::Mutex; -use time::Timespec; +use std::time::{Duration, SystemTime}; use zip::{read::ZipFile, ZipArchive}; fn zip_path(path: &Path) -> &Path { @@ -23,7 +23,7 @@ fn zipfile_to_filetype(zf: &ZipFile) -> FileType { fn zipfile_to_fuse(zf: &ZipFile) -> FileAttr { let kind = zipfile_to_filetype(zf); let perm = (zf.unix_mode().unwrap_or(0) & 0o7777) as u16; - let mtime = zf.last_modified().to_time().to_timespec(); + let mtime: SystemTime = zf.last_modified().to_time().unwrap().into(); FileAttr { size: zf.size() as u64, @@ -31,7 +31,7 @@ fn zipfile_to_fuse(zf: &ZipFile) -> FileAttr { atime: mtime, mtime, ctime: mtime, - crtime: Timespec { sec: 0, nsec: 0 }, + crtime: SystemTime::UNIX_EPOCH, kind, perm, nlink: 1, @@ -45,10 +45,10 @@ fn zipfile_to_fuse(zf: &ZipFile) -> FileAttr { const DIR_ATTR: FileAttr = FileAttr { size: 0, blocks: 0, - atime: Timespec { sec: 0, nsec: 0 }, - mtime: Timespec { sec: 0, nsec: 0 }, - ctime: Timespec { sec: 0, nsec: 0 }, - crtime: Timespec { sec: 0, nsec: 0 }, + atime: SystemTime::UNIX_EPOCH, + mtime: SystemTime::UNIX_EPOCH, + ctime: SystemTime::UNIX_EPOCH, + crtime: SystemTime::UNIX_EPOCH, kind: FileType::Directory, perm: 0o0755, nlink: 1, @@ -116,7 +116,7 @@ impl AgeZipFs { } } -const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; +const TTL: Duration = Duration::from_secs(1); impl FilesystemMT for AgeZipFs { fn getattr(&self, _req: RequestInfo, path: &Path, fh: Option) -> ResultEntry { From 4ecb474e55cf17778b0580f1059f572aaa3d6f2e Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 21 Aug 2022 14:45:28 +0000 Subject: [PATCH 2/4] Update lockfile --- Cargo.lock | 241 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 193 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fe75d64..362708ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "opaque-debug", +] + [[package]] name = "aes" version = "0.8.1" @@ -41,7 +53,7 @@ dependencies = [ name = "age" version = "0.8.1" dependencies = [ - "aes", + "aes 0.8.1", "age-core", "atty", "base64", @@ -193,9 +205,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "base64ct" -version = "1.1.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" +checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" [[package]] name = "bcrypt-pbkdf" @@ -337,6 +349,9 @@ name = "cc" version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -378,7 +393,7 @@ dependencies = [ "libc", "num-integer", "num-traits", - "time", + "time 0.1.44", "winapi", ] @@ -464,6 +479,12 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "cookie-factory" version = "0.3.2" @@ -720,7 +741,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ - "log 0.4.17", + "log", "regex", ] @@ -732,7 +753,7 @@ checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" dependencies = [ "atty", "humantime", - "log 0.4.17", + "log", "regex", "termcolor", ] @@ -834,29 +855,31 @@ dependencies = [ ] [[package]] -name = "fuse" -version = "0.3.1" +name = "fuse_mt" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e57070510966bfef93662a81cb8aa2b1c7db0964354fa9921434f04b9e8660" +checksum = "b6fb32ee97853a470831e058c0340955c9c773c8a1885aab99b37a2d3131fc06" dependencies = [ + "fuser", "libc", - "log 0.3.9", - "pkg-config", - "thread-scoped", - "time", + "log", + "threadpool", ] [[package]] -name = "fuse_mt" -version = "0.5.1" +name = "fuser" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "594691fb765cf23933301a6b5b7962332cb0e29fdb2c15a92fc92039a4817afa" +checksum = "aef8400a4ea1d18a8302e2952f5137a9a21ab257825ccc7d67db4a8018b89022" dependencies = [ - "fuse", "libc", - "log 0.4.17", - "threadpool", - "time", + "log", + "memchr", + "page_size", + "pkg-config", + "smallvec", + "users", + "zerocopy", ] [[package]] @@ -1080,7 +1103,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62affcd43abfb51f3cbd8736f9407908dc5b44fc558a9be07460bbfd104d983" dependencies = [ - "log 0.4.17", + "log", "serde", "serde_derive", "thiserror", @@ -1101,7 +1124,7 @@ dependencies = [ "intl-memoizer", "lazy_static", "locale_config", - "log 0.4.17", + "log", "parking_lot", "rust-embed", "thiserror", @@ -1164,7 +1187,7 @@ dependencies = [ "indexmap", "itoa 1.0.2", "lazy_static", - "log 0.4.17", + "log", "num-format", "quick-xml", "rgb", @@ -1237,6 +1260,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.58" @@ -1290,15 +1322,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -dependencies = [ - "log 0.4.17", -] - [[package]] name = "log" version = "0.4.17" @@ -1463,6 +1486,15 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + [[package]] name = "objc" version = "0.2.7" @@ -1525,6 +1557,16 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +[[package]] +name = "page_size" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eebde548fbbf1ea81a99b128872779c437752fb99f217c45245e1a61dcd9edcd" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1548,6 +1590,17 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "password-hash" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" +dependencies = [ + "base64ct", + "rand_core 0.6.3", + "subtle", +] + [[package]] name = "pbkdf2" version = "0.10.1" @@ -1555,6 +1608,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7" dependencies = [ "digest 0.10.3", + "hmac", + "password-hash", + "sha2 0.10.2", ] [[package]] @@ -1610,7 +1666,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa5b8bc68be6a5e2ba84ee86db53f816cba1905b94fcb7c236e606221cc8fc8" dependencies = [ - "log 0.4.17", + "log", "nom", "percent-encoding", "secrecy", @@ -1699,7 +1755,7 @@ dependencies = [ "findshlibs", "inferno", "libc", - "log 0.4.17", + "log", "nix", "once_cell", "parking_lot", @@ -1764,7 +1820,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" dependencies = [ "env_logger 0.8.4", - "log 0.4.17", + "log", "rand 0.8.5", ] @@ -1805,12 +1861,12 @@ dependencies = [ "i18n-embed-fl", "lazy_static", "libc", - "log 0.4.17", + "log", "man", "pinentry", "rust-embed", "tar", - "time", + "time 0.3.7", "zip", ] @@ -2156,6 +2212,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77f4e7f65455545c2153c1253d25056825e77ee2533f0e41deb65a93a34852f" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.3", +] + [[package]] name = "sha2" version = "0.9.9" @@ -2378,12 +2445,6 @@ dependencies = [ "syn", ] -[[package]] -name = "thread-scoped" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbb6aa301e5d3b0b5ef639c9a9c7e2f1c944f177b460c04dc24c69b1fa2bd99" - [[package]] name = "threadpool" version = "1.8.1" @@ -2404,6 +2465,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d" +dependencies = [ + "itoa 1.0.2", + "libc", + "num_threads", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6" + [[package]] name = "tinystr" version = "0.3.4" @@ -2491,6 +2570,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "users" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" +dependencies = [ + "libc", + "log", +] + [[package]] name = "uuid" version = "0.8.2" @@ -2550,7 +2639,7 @@ checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" dependencies = [ "bumpalo", "lazy_static", - "log 0.4.17", + "log", "proc-macro2", "quote", "syn", @@ -2707,6 +2796,27 @@ dependencies = [ "libc", ] +[[package]] +name = "zerocopy" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332f188cc1bcf1fe1064b8c58d150f497e697f49774aa846f2dc949d9a25f236" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0fbc82b82efe24da867ee52e015e58178684bd9dd64c34e66bdf21da2582a9f" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + [[package]] name = "zeroize" version = "1.4.3" @@ -2730,14 +2840,49 @@ dependencies = [ [[package]] name = "zip" -version = "0.5.13" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d" dependencies = [ + "aes 0.7.5", "byteorder", "bzip2", + "constant_time_eq", "crc32fast", + "crossbeam-utils", "flate2", - "thiserror", - "time", + "hmac", + "pbkdf2", + "sha1", + "time 0.3.7", + "zstd", +] + +[[package]] +name = "zstd" +version = "0.10.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4a6bd64f22b5e3e94b4e238669ff9f10815c27a5180108b849d24174a83847" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "4.1.6+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b61c51bb270702d6167b8ce67340d2754b088d0c091b06e593aa772c3ee9bb" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.6.3+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8" +dependencies = [ + "cc", + "libc", ] From 5a6110fba25c6dfd26cf28f516e7b3541446de1a Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 3 Sep 2022 11:59:12 +0000 Subject: [PATCH 3/4] rage-mount: Switch to `fuser::mount2` with typed options This also pins `fuser 0.11.1` which fixes an error message for libfuse2. --- Cargo.lock | 5 +++-- rage/Cargo.toml | 3 ++- rage/src/bin/rage-mount/main.rs | 13 +++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 362708ee..3b6e4d16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -868,9 +868,9 @@ dependencies = [ [[package]] name = "fuser" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8400a4ea1d18a8302e2952f5137a9a21ab257825ccc7d67db4a8018b89022" +checksum = "104ed58f182bc2975062cd3fab229e82b5762de420e26cf5645f661402694599" dependencies = [ "libc", "log", @@ -1856,6 +1856,7 @@ dependencies = [ "env_logger 0.9.0", "flate2", "fuse_mt", + "fuser", "gumdrop", "i18n-embed", "i18n-embed-fl", diff --git a/rage/Cargo.toml b/rage/Cargo.toml index 23910d25..01132a9f 100644 --- a/rage/Cargo.toml +++ b/rage/Cargo.toml @@ -67,6 +67,7 @@ rust-embed = "6" # rage-mount dependencies fuse_mt = { version = "0.6.0", optional = true } +fuser = { version = "0.11.1", optional = true } libc = { version = "0.2", optional = true } tar = { version = "0.4", optional = true } time = { version = "0.3.7", optional = true } @@ -80,7 +81,7 @@ man = "0.3" [features] default = ["ssh"] -mount = ["fuse_mt", "libc", "tar", "time", "zip"] +mount = ["fuse_mt", "fuser", "libc", "tar", "time", "zip"] ssh = ["age/ssh"] unstable = ["age/unstable"] diff --git a/rage/src/bin/rage-mount/main.rs b/rage/src/bin/rage-mount/main.rs index e25e49a5..fc1f2cc0 100644 --- a/rage/src/bin/rage-mount/main.rs +++ b/rage/src/bin/rage-mount/main.rs @@ -6,6 +6,7 @@ use age::{ stream::StreamReader, }; use fuse_mt::FilesystemMT; +use fuser::MountOption; use gumdrop::Options; use i18n_embed::{ fluent::{fluent_language_loader, FluentLanguageLoader}, @@ -14,7 +15,7 @@ use i18n_embed::{ use lazy_static::lazy_static; use log::info; use rust_embed::RustEmbed; -use std::ffi::OsStr; + use std::fmt; use std::fs::File; use std::io; @@ -164,11 +165,15 @@ fn mount_fs( where F: FnOnce() -> io::Result, { - let fuse_args: Vec<&OsStr> = vec![OsStr::new("-o"), OsStr::new("ro,auto_unmount")]; - let fs = open().map(|fs| fuse_mt::FuseMT::new(fs, 1))?; info!("{}", fl!("info-mounting-as-fuse")); - fuse_mt::mount(fs, &mountpoint, &fuse_args)?; + + fuser::mount2( + fs, + &mountpoint, + &[MountOption::RO, MountOption::AutoUnmount], + )?; + Ok(()) } From 5e212a7895689eff316483d0497fd8b1d586d565 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 3 Sep 2022 13:06:47 +0000 Subject: [PATCH 4/4] rage-mount: Replace `MountOptions::AutoUnmount` with a channel We now cleanly unmount the filesystem ourselves on Ctrl-C, instead of relying on FUSE to do this for us. This removes the need for the ambient `MountOptions::AllowOther` capability that `AutoUnmount` requires, while ensuring that `rage-mount` correctly exits if the mountpoint is unmounted externally (e.g. via `umount`). --- Cargo.lock | 29 +++++++++++++++++++++++++--- rage/Cargo.toml | 3 ++- rage/src/bin/rage-mount/main.rs | 34 ++++++++++++++++++++++++++------- rage/src/bin/rage-mount/tar.rs | 15 +++++++++++++-- rage/src/bin/rage-mount/zip.rs | 15 +++++++++++++-- 5 files changed, 81 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b6e4d16..452004c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -660,6 +660,16 @@ dependencies = [ "cipher 0.4.3", ] +[[package]] +name = "ctrlc" +version = "3.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173" +dependencies = [ + "nix 0.25.0", + "winapi", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1289,9 +1299,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.126" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "libm" @@ -1401,6 +1411,18 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nix" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +dependencies = [ + "autocfg 1.1.0", + "bitflags", + "cfg-if", + "libc", +] + [[package]] name = "nodrop" version = "0.1.14" @@ -1756,7 +1778,7 @@ dependencies = [ "inferno", "libc", "log", - "nix", + "nix 0.23.1", "once_cell", "parking_lot", "smallvec", @@ -1853,6 +1875,7 @@ dependencies = [ "clap 3.2.5", "clap_complete", "console", + "ctrlc", "env_logger 0.9.0", "flate2", "fuse_mt", diff --git a/rage/Cargo.toml b/rage/Cargo.toml index 01132a9f..11ac5a27 100644 --- a/rage/Cargo.toml +++ b/rage/Cargo.toml @@ -66,6 +66,7 @@ pinentry = "0.5" rust-embed = "6" # rage-mount dependencies +ctrlc = { version = "3.2", optional = true } fuse_mt = { version = "0.6.0", optional = true } fuser = { version = "0.11.1", optional = true } libc = { version = "0.2", optional = true } @@ -81,7 +82,7 @@ man = "0.3" [features] default = ["ssh"] -mount = ["fuse_mt", "fuser", "libc", "tar", "time", "zip"] +mount = ["ctrlc", "fuse_mt", "fuser", "libc", "tar", "time", "zip"] ssh = ["age/ssh"] unstable = ["age/unstable"] diff --git a/rage/src/bin/rage-mount/main.rs b/rage/src/bin/rage-mount/main.rs index fc1f2cc0..ad1fb14e 100644 --- a/rage/src/bin/rage-mount/main.rs +++ b/rage/src/bin/rage-mount/main.rs @@ -19,6 +19,7 @@ use rust_embed::RustEmbed; use std::fmt; use std::fs::File; use std::io; +use std::sync::mpsc; mod tar; mod zip; @@ -161,6 +162,7 @@ struct AgeMountOptions { fn mount_fs( open: F, mountpoint: String, + finished: mpsc::Receiver<()>, ) -> Result<(), Error> where F: FnOnce() -> io::Result, @@ -168,11 +170,14 @@ where let fs = open().map(|fs| fuse_mt::FuseMT::new(fs, 1))?; info!("{}", fl!("info-mounting-as-fuse")); - fuser::mount2( - fs, - &mountpoint, - &[MountOption::RO, MountOption::AutoUnmount], - )?; + // Mount the filesystem. + let handle = fuser::spawn_mount2(fs, mountpoint, &[MountOption::RO])?; + + // Wait until we are done. + finished.recv().expect("Could not receive from channel."); + + // Ensure the filesystem is unmounted. + handle.join(); Ok(()) } @@ -182,9 +187,24 @@ fn mount_stream( types: String, mountpoint: String, ) -> Result<(), Error> { + // We want to block until either Ctrl-C, or the filesystem is unmounted externally. + // Set up a channel for notifying the main thread that we should exit. + let (tx, finished) = mpsc::sync_channel(2); + let destroy_tx = tx.clone(); + ctrlc::set_handler(move || tx.send(()).expect("Could not send signal on channel.")) + .expect("Error setting Ctrl-C handler"); + match types.as_str() { - "tar" => mount_fs(|| crate::tar::AgeTarFs::open(stream), mountpoint), - "zip" => mount_fs(|| crate::zip::AgeZipFs::open(stream), mountpoint), + "tar" => mount_fs( + || crate::tar::AgeTarFs::open(stream, destroy_tx), + mountpoint, + finished, + ), + "zip" => mount_fs( + || crate::zip::AgeZipFs::open(stream, destroy_tx), + mountpoint, + finished, + ), _ => Err(Error::UnknownType(types)), } } diff --git a/rage/src/bin/rage-mount/tar.rs b/rage/src/bin/rage-mount/tar.rs index abaa5670..9f4e071f 100644 --- a/rage/src/bin/rage-mount/tar.rs +++ b/rage/src/bin/rage-mount/tar.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::{self, BufReader, Read, Seek, SeekFrom}; use std::path::{Path, PathBuf}; -use std::sync::Mutex; +use std::sync::{mpsc, Mutex}; use std::time::{Duration, SystemTime}; use tar::{Archive, Entry, EntryType}; @@ -106,6 +106,7 @@ type OpenFile = (PathBuf, u64, u64); pub struct AgeTarFs { inner: Mutex>>>, + destroy_tx: mpsc::SyncSender<()>, dir_map: HashMap>, file_map: HashMap, open_dirs: Mutex<(HashMap, u64)>, @@ -113,7 +114,10 @@ pub struct AgeTarFs { } impl AgeTarFs { - pub fn open(stream: StreamReader>>) -> io::Result { + pub fn open( + stream: StreamReader>>, + destroy_tx: mpsc::SyncSender<()>, + ) -> io::Result { // Build a directory listing for the archive let mut dir_map: HashMap> = HashMap::new(); dir_map.insert(PathBuf::new(), vec![]); // the root @@ -136,6 +140,7 @@ impl AgeTarFs { Ok(AgeTarFs { inner: Mutex::new(archive.into_inner()), + destroy_tx, dir_map, file_map, open_dirs: Mutex::new((HashMap::new(), 0)), @@ -147,6 +152,12 @@ impl AgeTarFs { const TTL: Duration = Duration::from_secs(1); impl FilesystemMT for AgeTarFs { + fn destroy(&self) { + self.destroy_tx + .send(()) + .expect("Could not send signal on channel."); + } + fn getattr(&self, _req: RequestInfo, path: &Path, fh: Option) -> ResultEntry { let open_dirs = self.open_dirs.lock().unwrap(); let open_files = self.open_files.lock().unwrap(); diff --git a/rage/src/bin/rage-mount/zip.rs b/rage/src/bin/rage-mount/zip.rs index 6b303a41..30b7e246 100644 --- a/rage/src/bin/rage-mount/zip.rs +++ b/rage/src/bin/rage-mount/zip.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::{self, BufReader, Read}; use std::path::{Path, PathBuf}; -use std::sync::Mutex; +use std::sync::{mpsc, Mutex}; use std::time::{Duration, SystemTime}; use zip::{read::ZipFile, ZipArchive}; @@ -85,13 +85,17 @@ fn add_dir_to_map( pub struct AgeZipFs { inner: Mutex>>>>, + destroy_tx: mpsc::SyncSender<()>, dir_map: HashMap>, open_dirs: Mutex<(HashMap, u64)>, open_files: Mutex<(HashMap, u64)>, } impl AgeZipFs { - pub fn open(stream: StreamReader>>) -> io::Result { + pub fn open( + stream: StreamReader>>, + destroy_tx: mpsc::SyncSender<()>, + ) -> io::Result { let mut archive = ZipArchive::new(stream).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; @@ -109,6 +113,7 @@ impl AgeZipFs { Ok(AgeZipFs { inner: Mutex::new(archive), + destroy_tx, dir_map, open_dirs: Mutex::new((HashMap::new(), 0)), open_files: Mutex::new((HashMap::new(), 0)), @@ -119,6 +124,12 @@ impl AgeZipFs { const TTL: Duration = Duration::from_secs(1); impl FilesystemMT for AgeZipFs { + fn destroy(&self) { + self.destroy_tx + .send(()) + .expect("Could not send signal on channel."); + } + fn getattr(&self, _req: RequestInfo, path: &Path, fh: Option) -> ResultEntry { let mut inner = self.inner.lock().unwrap(); let open_dirs = self.open_dirs.lock().unwrap();