commit
f150b53d7e
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -976,6 +976,7 @@ dependencies = [
|
||||
"uu_lscpu",
|
||||
"uu_lslocks",
|
||||
"uu_lsmem",
|
||||
"uu_mesg",
|
||||
"uu_mountpoint",
|
||||
"uu_rev",
|
||||
"uu_setsid",
|
||||
@ -1067,6 +1068,15 @@ dependencies = [
|
||||
"uucore",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uu_mesg"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"nix",
|
||||
"uucore",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uu_mountpoint"
|
||||
version = "0.0.1"
|
||||
|
@ -34,6 +34,7 @@ feat_common_core = [
|
||||
"lscpu",
|
||||
"lslocks",
|
||||
"lsmem",
|
||||
"mesg",
|
||||
"mountpoint",
|
||||
"rev",
|
||||
"setsid",
|
||||
@ -79,6 +80,7 @@ last = { optional = true, version = "0.0.1", package = "uu_last", path = "src/uu
|
||||
lscpu = { optional = true, version = "0.0.1", package = "uu_lscpu", path = "src/uu/lscpu" }
|
||||
lslocks = { optional = true, version = "0.0.1", package = "uu_lslocks", path = "src/uu/lslocks" }
|
||||
lsmem = { optional = true, version = "0.0.1", package = "uu_lsmem", path = "src/uu/lsmem" }
|
||||
mesg = { optional = true, version = "0.0.1", package = "uu_mesg", path = "src/uu/mesg" }
|
||||
mountpoint = { optional = true, version = "0.0.1", package = "uu_mountpoint", path = "src/uu/mountpoint" }
|
||||
rev = { optional = true, version = "0.0.1", package = "uu_rev", path = "src/uu/rev" }
|
||||
setsid = { optional = true, version = "0.0.1", package = "uu_setsid", path ="src/uu/setsid" }
|
||||
|
16
src/uu/mesg/Cargo.toml
Normal file
16
src/uu/mesg/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "uu_mesg"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
path = "src/mesg.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "mesg"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = { workspace = true }
|
||||
nix = { workspace = true }
|
||||
uucore = { workspace = true }
|
7
src/uu/mesg/mesg.md
Normal file
7
src/uu/mesg/mesg.md
Normal file
@ -0,0 +1,7 @@
|
||||
# mesg
|
||||
|
||||
```
|
||||
mesg [option] [y|n]
|
||||
```
|
||||
|
||||
enables or disables displaying messages from other users
|
1
src/uu/mesg/src/main.rs
Normal file
1
src/uu/mesg/src/main.rs
Normal file
@ -0,0 +1 @@
|
||||
uucore::bin!(uu_mesg);
|
101
src/uu/mesg/src/mesg.rs
Normal file
101
src/uu/mesg/src/mesg.rs
Normal file
@ -0,0 +1,101 @@
|
||||
// This file is part of the uutils util-linux package.
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use clap::{builder::PossibleValuesParser, crate_version, Arg, ArgAction, ArgMatches, Command};
|
||||
#[cfg(target_family = "unix")]
|
||||
use uucore::error::{set_exit_code, UIoError};
|
||||
use uucore::{error::UResult, format_usage, help_about, help_usage};
|
||||
|
||||
const ABOUT: &str = help_about!("mesg.md");
|
||||
const USAGE: &str = help_usage!("mesg.md");
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
pub fn do_mesg(matches: &ArgMatches) -> UResult<()> {
|
||||
use nix::sys::stat::{fchmod, fstat, Mode};
|
||||
use std::{io, os::fd::AsRawFd};
|
||||
use std::{io::IsTerminal, os::fd::AsFd};
|
||||
|
||||
for fd in &[
|
||||
std::io::stdin().as_fd(),
|
||||
std::io::stdout().as_fd(),
|
||||
std::io::stderr().as_fd(),
|
||||
] {
|
||||
if fd.is_terminal() {
|
||||
let st = fstat(fd.as_raw_fd())?;
|
||||
if let Some(enable) = matches.get_one::<String>("enable") {
|
||||
// 'mesg y' on the GNU version seems to only modify the group write bit,
|
||||
// but 'mesg n' modifies both group and others write bits.
|
||||
let new_mode = if enable == "y" {
|
||||
st.st_mode | 0o020
|
||||
} else {
|
||||
st.st_mode & !0o022
|
||||
};
|
||||
fchmod(fd.as_raw_fd(), Mode::from_bits_retain(new_mode))?;
|
||||
if enable == "n" {
|
||||
set_exit_code(1);
|
||||
}
|
||||
if matches.get_flag("verbose") {
|
||||
println!(
|
||||
"write access to your terminal is {}",
|
||||
if enable == "y" { "allowed" } else { "denied" }
|
||||
);
|
||||
}
|
||||
} else if st.st_mode & 0o022 != 0 {
|
||||
println!("is y");
|
||||
} else {
|
||||
set_exit_code(1);
|
||||
println!("is n");
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Err(UIoError::new(
|
||||
io::ErrorKind::Other,
|
||||
"stdin/stdout/stderr is not a terminal",
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let matches = uu_app().try_get_matches_from(args)?;
|
||||
if let Err(e) = do_mesg(&matches) {
|
||||
set_exit_code(2);
|
||||
uucore::show_error!("{}", e);
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(uucore::util_name())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.override_usage(format_usage(USAGE))
|
||||
.infer_long_args(true)
|
||||
.arg(
|
||||
Arg::new("verbose")
|
||||
.short('v')
|
||||
.long("verbose")
|
||||
.help("Explain what is being done")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("enable")
|
||||
.help("Whether to allow or disallow messages")
|
||||
.value_parser(PossibleValuesParser::new(["y", "n"]))
|
||||
.action(ArgAction::Set),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(not(target_family = "unix"))]
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let _matches: ArgMatches = uu_app().try_get_matches_from(args)?;
|
||||
|
||||
Err(uucore::error::USimpleError::new(
|
||||
1,
|
||||
"`mesg` is available only on Unix platforms.",
|
||||
))
|
||||
}
|
36
tests/by-util/test_mesg.rs
Normal file
36
tests/by-util/test_mesg.rs
Normal file
@ -0,0 +1,36 @@
|
||||
// This file is part of the uutils util-linux package.
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use crate::common::util::TestScenario;
|
||||
|
||||
#[test]
|
||||
fn test_invalid_verb() {
|
||||
new_ucmd!().arg("foo").fails().code_is(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_family = "unix")]
|
||||
fn test_no_terminal() {
|
||||
for args in &[vec![], vec!["y"], vec!["n"]] {
|
||||
new_ucmd!()
|
||||
.args(args)
|
||||
.fails()
|
||||
.code_is(2)
|
||||
.stderr_contains("stdin/stdout/stderr is not a terminal");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_family = "unix"))]
|
||||
mod non_unix {
|
||||
use crate::common::util::TestScenario;
|
||||
|
||||
#[test]
|
||||
fn test_fails_on_unsupported_platforms() {
|
||||
new_ucmd!()
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_is("mesg: `mesg` is available only on Unix platforms.\n");
|
||||
}
|
||||
}
|
@ -17,6 +17,10 @@ mod test_lsmem;
|
||||
#[path = "by-util/test_lslocks.rs"]
|
||||
mod test_lslocks;
|
||||
|
||||
#[cfg(feature = "mesg")]
|
||||
#[path = "by-util/test_mesg.rs"]
|
||||
mod test_mesg;
|
||||
|
||||
#[cfg(feature = "mountpoint")]
|
||||
#[path = "by-util/test_mountpoint.rs"]
|
||||
mod test_mountpoint;
|
||||
|
Loading…
x
Reference in New Issue
Block a user