From 3572b12a1a9c3d769bf1591f5dab4f2c04a291ab Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 20 Jun 2021 01:53:15 +0200 Subject: [PATCH 01/38] Receive message(s) from a queue This subcommand receives one or more messages from a queue. Three different methods are supported, read message by message, read until a given timout or read until a specified date and time. This subcommand also supports the `--non-blocking` flag. --- Cargo.lock | 50 +++++++++++++++++++++++++++++ Cargo.toml | 1 + src/cli.rs | 3 +- src/main.rs | 2 ++ src/recv.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/recv.rs diff --git a/Cargo.lock b/Cargo.lock index a76a2d3..4d2e6b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,6 +29,19 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi", +] + [[package]] name = "clap" version = "3.0.0-beta.2" @@ -112,10 +125,30 @@ name = "mqrs" version = "0.1.0-dev" dependencies = [ "anyhow", + "chrono", "clap", "posixmq", ] +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + [[package]] name = "os_str_bytes" version = "2.4.0" @@ -208,6 +241,17 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi", + "winapi", +] + [[package]] name = "unicode-segmentation" version = "1.7.1" @@ -238,6 +282,12 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 4222fbc..b008296 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ description = "A CLI program for interacting Posix Message Queues" anyhow = "1.0" clap = "3.0.0-beta.2" posixmq = "1.0" +chrono = "0.4" diff --git a/src/cli.rs b/src/cli.rs index 8568937..4148233 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -use crate::{create::Create, info::Info, send::Send, unlink::Unlink}; +use crate::{create::Create, info::Info, recv::Recv, send::Send, unlink::Unlink}; use clap::{crate_authors, crate_version, AppSettings, Clap}; #[derive(Clap, Debug)] @@ -23,4 +23,5 @@ pub enum Command { Info(Info), Unlink(Unlink), Send(Send), + Recv(Recv), } diff --git a/src/main.rs b/src/main.rs index e361ffe..e6bc64a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use clap::Clap; mod cli; mod create; mod info; +mod recv; mod send; mod unlink; @@ -17,6 +18,7 @@ fn main() -> Result<()> { Command::Info(i) => i.run()?, Command::Unlink(u) => u.run(opts.verbose)?, Command::Send(s) => s.run(opts.verbose)?, + Command::Recv(r) => r.run(opts.verbose)?, } Ok(()) diff --git a/src/recv.rs b/src/recv.rs new file mode 100644 index 0000000..231d841 --- /dev/null +++ b/src/recv.rs @@ -0,0 +1,92 @@ +use anyhow::Result; +use chrono::{DateTime, Local}; +use clap::Clap; +use posixmq::PosixMq; +use std::{str, time::Duration}; + +/// Receive and print a message from a message queue +#[derive(Clap, Debug)] +pub struct Recv { + /// Do not block + #[clap(short, long)] + pub non_blocking: bool, + /// Print messages as they are received + #[clap(short, long)] + pub follow: bool, + /// Print a timestamp before each message + #[clap(short, long)] + pub timestamp: bool, + /// Timeout in "[s]" (default) or "ms" + #[clap(short = 'o', long)] + pub timeout: Option, + /// Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") + #[clap(short, long)] + pub deadline: Option, + #[clap(value_name = "QNAME")] + pub queue: String, +} + +fn print_message(verbose: bool, priority: u32, length: usize, timestamp: bool, msg: &str) { + if verbose { + println!("Priority: {}, length: {}", priority, length); + } + + if timestamp { + println!("{}", Local::now()); + } + + println!("{}", msg); +} + +impl Recv { + fn receive(&self, verbose: bool, mq: &PosixMq) -> Result<()> { + let mut buf = vec![0; mq.attributes()?.max_msg_len]; + + if let Some(timeout) = &self.timeout { + let timeout = if timeout.ends_with("ms") { + Duration::from_millis(timeout[0..timeout.len() - 2].parse::()?) + } else if timeout.ends_with("s") { + Duration::from_secs(timeout[0..timeout.len() - 1].parse::()?) + } else { + Duration::from_secs(timeout.parse::()?) + }; + + let (prio, len) = mq.recv_timeout(&mut buf, timeout)?; + + print_message(verbose, prio, len, self.timestamp, str::from_utf8(&buf)?); + } else if let Some(deadline) = &self.deadline { + let (prio, len) = mq.recv_deadline( + &mut buf, + DateTime::parse_from_str(deadline, "%Y-%m-%d %H:%M:%S")?.into(), + )?; + + print_message(verbose, prio, len, self.timestamp, str::from_utf8(&buf)?); + } else { + let (prio, len) = mq.recv(&mut buf)?; + + print_message(verbose, prio, len, self.timestamp, str::from_utf8(&buf)?); + } + + Ok(()) + } + + pub fn run(&self, verbose: bool) -> Result<()> { + let mq = &mut posixmq::OpenOptions::readonly(); + + if self.non_blocking { + mq.nonblocking(); + } + + let mq = mq.open(&self.queue)?; + + if self.follow { + loop { + self.receive(verbose, &mq)?; + } + } else { + self.receive(verbose, &mq)?; + } + + Ok(()) + } +} From 9b52305285d2385c7504299eb671449ff8839953 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 20 Jun 2021 02:00:08 +0200 Subject: [PATCH 02/38] Rename queue help name --- src/create.rs | 2 +- src/info.rs | 2 +- src/recv.rs | 2 +- src/send.rs | 2 +- src/unlink.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/create.rs b/src/create.rs index 26652c3..b57ce6e 100644 --- a/src/create.rs +++ b/src/create.rs @@ -16,7 +16,7 @@ pub struct Create { #[clap(short = 's', long)] msgsize: Option, /// Name of the queue - #[clap(value_name = "QNAME")] + #[clap(value_name = "QUEUE")] queue: String, } diff --git a/src/info.rs b/src/info.rs index e2be5ba..0fd1e76 100644 --- a/src/info.rs +++ b/src/info.rs @@ -6,7 +6,7 @@ use posixmq::PosixMq; #[derive(Clap, Debug)] pub struct Info { /// Name of the queue - #[clap(value_name = "QNAME")] + #[clap(value_name = "QUEUE")] pub queue: String, } diff --git a/src/recv.rs b/src/recv.rs index 231d841..5452d85 100644 --- a/src/recv.rs +++ b/src/recv.rs @@ -22,7 +22,7 @@ pub struct Recv { /// Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") #[clap(short, long)] pub deadline: Option, - #[clap(value_name = "QNAME")] + #[clap(value_name = "QUEUE")] pub queue: String, } diff --git a/src/send.rs b/src/send.rs index 7b8a6e8..f1f846d 100644 --- a/src/send.rs +++ b/src/send.rs @@ -11,7 +11,7 @@ pub struct Send { #[clap(short, long)] pub non_blocking: bool, /// Name of the queue - #[clap(value_name = "QNAME")] + #[clap(value_name = "QUEUE")] pub queue: String, /// Message to be sent to the queue #[clap(value_name = "MESSAGE")] diff --git a/src/unlink.rs b/src/unlink.rs index 71eaac4..ae837e1 100644 --- a/src/unlink.rs +++ b/src/unlink.rs @@ -5,7 +5,7 @@ use clap::Clap; #[derive(Clap, Debug)] pub struct Unlink { /// Name of the queue - #[clap(value_name = "QNAME")] + #[clap(value_name = "QUEUE")] pub queue: String, } From 1100ba1b132d1ded5387a4232b7c5e4bcbaeb791 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 20 Jun 2021 16:49:40 +0200 Subject: [PATCH 03/38] Support timeout and deadline parameters for send Add support for timeout and deadline parameters when messages are sent to a message queue. To keep code duplication small, the `utils.rs` file contains a helper function to parse the `Duration` from the `String` received from the timeout parameter. Add conflict rules for the timeout and deadline parameters. --- src/main.rs | 1 + src/recv.rs | 17 +++++------------ src/send.rs | 38 ++++++++++++++++++++++++++++++++++---- src/utils.rs | 16 ++++++++++++++++ 4 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 src/utils.rs diff --git a/src/main.rs b/src/main.rs index e6bc64a..d85fa83 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ mod info; mod recv; mod send; mod unlink; +mod utils; use cli::{Command, Opts}; diff --git a/src/recv.rs b/src/recv.rs index 5452d85..356829d 100644 --- a/src/recv.rs +++ b/src/recv.rs @@ -1,8 +1,9 @@ +use crate::utils; use anyhow::Result; use chrono::{DateTime, Local}; use clap::Clap; use posixmq::PosixMq; -use std::{str, time::Duration}; +use std::str; /// Receive and print a message from a message queue #[derive(Clap, Debug)] @@ -17,10 +18,10 @@ pub struct Recv { #[clap(short, long)] pub timestamp: bool, /// Timeout in "[s]" (default) or "ms" - #[clap(short = 'o', long)] + #[clap(short = 'o', long, conflicts_with = "deadline")] pub timeout: Option, /// Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") - #[clap(short, long)] + #[clap(short, long, conflicts_with = "timeout")] pub deadline: Option, #[clap(value_name = "QUEUE")] pub queue: String, @@ -43,15 +44,7 @@ impl Recv { let mut buf = vec![0; mq.attributes()?.max_msg_len]; if let Some(timeout) = &self.timeout { - let timeout = if timeout.ends_with("ms") { - Duration::from_millis(timeout[0..timeout.len() - 2].parse::()?) - } else if timeout.ends_with("s") { - Duration::from_secs(timeout[0..timeout.len() - 1].parse::()?) - } else { - Duration::from_secs(timeout.parse::()?) - }; - - let (prio, len) = mq.recv_timeout(&mut buf, timeout)?; + let (prio, len) = mq.recv_timeout(&mut buf, utils::parse_duration(timeout)?)?; print_message(verbose, prio, len, self.timestamp, str::from_utf8(&buf)?); } else if let Some(deadline) = &self.deadline { diff --git a/src/send.rs b/src/send.rs index f1f846d..3c310b8 100644 --- a/src/send.rs +++ b/src/send.rs @@ -1,4 +1,6 @@ +use crate::utils; use anyhow::Result; +use chrono::DateTime; use clap::Clap; /// Send a message to a message queue @@ -10,6 +12,12 @@ pub struct Send { /// Do not block #[clap(short, long)] pub non_blocking: bool, + /// Timeout in "[s]" (default) or "ms" + #[clap(short = 'o', long, conflicts_with = "deadline")] + pub timeout: Option, + /// Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") + #[clap(short, long, conflicts_with = "timeout")] + pub deadline: Option, /// Name of the queue #[clap(value_name = "QUEUE")] pub queue: String, @@ -26,11 +34,33 @@ impl Send { mq.nonblocking(); } - mq.open(&self.queue)? - .send(self.priority, &self.msg.as_bytes())?; + if let Some(timeout) = &self.timeout { + mq.open(&self.queue)?.send_timeout( + self.priority, + &self.msg.as_bytes(), + utils::parse_duration(timeout)?, + )?; - if verbose { - println!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); + if verbose { + println!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); + } + } else if let Some(deadline) = &self.deadline { + mq.open(&self.queue)?.send_deadline( + self.priority, + &self.msg.as_bytes(), + DateTime::parse_from_str(deadline, "%Y-%m-%d %H:%M:%S")?.into(), + )?; + + if verbose { + println!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); + } + } else { + mq.open(&self.queue)? + .send(self.priority, &self.msg.as_bytes())?; + + if verbose { + println!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); + } } Ok(()) diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..f810f1e --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,16 @@ +use anyhow::Result; +use std::{str, time::Duration}; + +pub fn parse_duration(timeout: &str) -> Result { + if timeout.ends_with("ms") { + Ok(Duration::from_millis( + timeout[0..timeout.len() - 2].parse::()?, + )) + } else if timeout.ends_with("s") { + Ok(Duration::from_secs( + timeout[0..timeout.len() - 1].parse::()?, + )) + } else { + Ok(Duration::from_secs(timeout.parse::()?)) + } +} From ddd9ce9a84c5b7b4f76c93406f457664ccda1f46 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 20 Jun 2021 17:12:05 +0200 Subject: [PATCH 04/38] Add readme and improve description --- Cargo.toml | 2 +- README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 README.md diff --git a/Cargo.toml b/Cargo.toml index b008296..8bbbe5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ authors = ["finga "] edition = "2018" license = "GPL-3.0-or-later" readme = "README.md" -description = "A CLI program for interacting Posix Message Queues" +description = "A CLI program for interacting with Posix Message Queues." [dependencies] anyhow = "1.0" diff --git a/README.md b/README.md new file mode 100644 index 0000000..c546b65 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# mqrs +`mqrs` is a small cli application to handle POSIX message queues. + +## Installation +Currently `mqrs` can only be built with the rust toolchain. Support +for `cargo-deb` is imminent. + +### Install Rust +Install the Rust toolchain from [rustup.rs](https://rustup.rs). + +### Build `mqrs` +`mqrs` can be built for development: +``` sh + cargo b +``` + +or for releasing: +``` sh + cargo b --release +``` + +### Install `mqrs` +When a Rust toolchain installed you can also install `mqrs` +directly without cloning it manually: +``` sh + cargo install --git https://git.onders.org/finga/mqrs.git mqrs +``` + +or from within the project: +``` sh + cargo install mqrs +``` + +### Run `mqrs` +`mqrs` can either be run from the project directory with: +``` sh + cargo b +``` + +or you can copy the produced binary somewhere else or link to them +from `target/{debug,release}/mqrs` depending on which +one you built. + +## Using `mqrs` +`mqrs` supports five commands: `create`, `info`, `unlink`, `send` and +`receive`. All commands do not have to be specified fully. If the +command is clearly distinguishable from all the others, it does not +have to be completed further. From c33294f00b79c6b5cddd25d97e1643f49fc044bd Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 20 Jun 2021 17:24:42 +0200 Subject: [PATCH 05/38] Issue templates for gitea --- .gitea/issue_template/bug.md | 21 +++++++++++++++++++++ .gitea/issue_template/enhancement.md | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 .gitea/issue_template/bug.md create mode 100644 .gitea/issue_template/enhancement.md diff --git a/.gitea/issue_template/bug.md b/.gitea/issue_template/bug.md new file mode 100644 index 0000000..7257e02 --- /dev/null +++ b/.gitea/issue_template/bug.md @@ -0,0 +1,21 @@ +--- + +name: "Bug Report" +about: "Something is not working as expected, file a bug report." +title: "" +labels: +- bug +- "help needed" + +--- + +# What do you want to achieve? + +# What is the result + +# Further information + +# System information +- Rust version: +- Operating system: +- Contents of all files in `/proc/sys/fs/mqueue`: diff --git a/.gitea/issue_template/enhancement.md b/.gitea/issue_template/enhancement.md new file mode 100644 index 0000000..551a59d --- /dev/null +++ b/.gitea/issue_template/enhancement.md @@ -0,0 +1,16 @@ +--- + +name: "Enhancement" +about: "Something could be improved or missing a feature?" +title: "" +labels: +- enhancement +- "help needed" + +--- + +# What do you want to achieve? + +# Example of the enhancement + +# Further information From 487d5a9971c5f01c2505e3ba64201b0b53835bb3 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 20 Jun 2021 17:39:22 +0200 Subject: [PATCH 06/38] Support `cargo-deb` and fix readme --- Cargo.toml | 7 +++++++ README.md | 26 +++++++++++++++----------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8bbbe5c..a3a6393 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,10 @@ anyhow = "1.0" clap = "3.0.0-beta.2" posixmq = "1.0" chrono = "0.4" + +[package.metadata.deb] +extended-description = "`mqrs` is a small cli application to handle POSIX message queues." +assets = [ + ["target/release/mqrs", "usr/bin/", "755"], + ["README.md", "usr/share/doc/cargo-deb/README.md", "644"], +] diff --git a/README.md b/README.md index c546b65..2ff0d81 100644 --- a/README.md +++ b/README.md @@ -2,39 +2,43 @@ `mqrs` is a small cli application to handle POSIX message queues. ## Installation -Currently `mqrs` can only be built with the rust toolchain. Support -for `cargo-deb` is imminent. +To build `mqrs` a rust toolchain is necessary. ### Install Rust Install the Rust toolchain from [rustup.rs](https://rustup.rs). ### Build `mqrs` `mqrs` can be built for development: -``` sh - cargo b +```sh +cargo b ``` or for releasing: -``` sh - cargo b --release +```sh +cargo b --release +``` + +### Build the `mqrs` Debian package +```sh +cargo deb ``` ### Install `mqrs` When a Rust toolchain installed you can also install `mqrs` directly without cloning it manually: ``` sh - cargo install --git https://git.onders.org/finga/mqrs.git mqrs +cargo install --git https://git.onders.org/finga/mqrs.git mqrs ``` or from within the project: -``` sh - cargo install mqrs +```sh +cargo install mqrs ``` ### Run `mqrs` `mqrs` can either be run from the project directory with: -``` sh - cargo b +```sh +cargo b ``` or you can copy the produced binary somewhere else or link to them From bcefd6241b9e730f46f56690a0cc25589279fdbc Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 20 Jun 2021 17:50:24 +0200 Subject: [PATCH 07/38] Move clap options and types into main --- src/cli.rs | 27 --------------------------- src/main.rs | 29 ++++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 30 deletions(-) delete mode 100644 src/cli.rs diff --git a/src/cli.rs b/src/cli.rs deleted file mode 100644 index 4148233..0000000 --- a/src/cli.rs +++ /dev/null @@ -1,27 +0,0 @@ -use crate::{create::Create, info::Info, recv::Recv, send::Send, unlink::Unlink}; -use clap::{crate_authors, crate_version, AppSettings, Clap}; - -#[derive(Clap, Debug)] -#[clap( - version = crate_version!(), - author = crate_authors!(", "), - setting = AppSettings::SubcommandRequiredElseHelp, - global_setting = AppSettings::VersionlessSubcommands, - global_setting = AppSettings::InferSubcommands, -)] -pub struct Opts { - /// Produce verbose output - #[clap(short, long, global = true)] - pub verbose: bool, - #[clap(subcommand)] - pub command: Command, -} - -#[derive(Clap, Debug)] -pub enum Command { - Create(Create), - Info(Info), - Unlink(Unlink), - Send(Send), - Recv(Recv), -} diff --git a/src/main.rs b/src/main.rs index d85fa83..8cf86b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ +use crate::{create::Create, info::Info, recv::Recv, send::Send, unlink::Unlink}; use anyhow::Result; -use clap::Clap; +use clap::{crate_authors, crate_version, AppSettings, Clap}; -mod cli; mod create; mod info; mod recv; @@ -9,7 +9,30 @@ mod send; mod unlink; mod utils; -use cli::{Command, Opts}; +#[derive(Clap, Debug)] +#[clap( + version = crate_version!(), + author = crate_authors!(", "), + setting = AppSettings::SubcommandRequiredElseHelp, + global_setting = AppSettings::VersionlessSubcommands, + global_setting = AppSettings::InferSubcommands, +)] +pub struct Opts { + /// Produce verbose output + #[clap(short, long, global = true)] + pub verbose: bool, + #[clap(subcommand)] + pub command: Command, +} + +#[derive(Clap, Debug)] +pub enum Command { + Create(Create), + Info(Info), + Unlink(Unlink), + Send(Send), + Recv(Recv), +} fn main() -> Result<()> { let opts: Opts = Opts::parse(); From 4633b7a4d8aebbb322fee52ce9b07c26f7390626 Mon Sep 17 00:00:00 2001 From: finga Date: Tue, 22 Jun 2021 01:36:00 +0200 Subject: [PATCH 08/38] Rename `mode` clap parameter to `permissions` Rename the clap parameter when creating a new message queue `mode` to `permissions`. --- src/create.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/create.rs b/src/create.rs index b57ce6e..4bb17eb 100644 --- a/src/create.rs +++ b/src/create.rs @@ -7,8 +7,8 @@ use std::fs; #[derive(Clap, Debug)] pub struct Create { /// Permissions (octal) to create the queue with - #[clap(short = 'p', long)] - mode: Option, + #[clap(short, long)] + permissions: Option, /// Maximum number of messages in the queue #[clap(short, long)] capacity: Option, @@ -38,7 +38,7 @@ impl Create { pub fn run(&self, verbose: bool) -> Result<()> { let mq = &mut posixmq::OpenOptions::readonly(); - if let Some(m) = &self.mode { + if let Some(m) = &self.permissions { mq.mode(u32::from_str_radix(&m, 8)?); } From 3e437b59be5da54a5066cbb7e77ab3af8891581c Mon Sep 17 00:00:00 2001 From: finga Date: Tue, 22 Jun 2021 01:36:57 +0200 Subject: [PATCH 09/38] Add informations about commands to readme --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index 2ff0d81..3382452 100644 --- a/README.md +++ b/README.md @@ -50,3 +50,39 @@ one you built. `receive`. All commands do not have to be specified fully. If the command is clearly distinguishable from all the others, it does not have to be completed further. + +### Create a message queue +Use the `create` command to create a new POSIX message queue. Following +optional arguments are supported: +- `-c`, `--capacity`: Maximum number of messages in the queue +- `-p`, `--permissions`: Permissions (octal) to create the queue with +- `-s`, `--msgsize`: Message size in bytes + +### Print information about a message queue +Use the `info` command to print further information about a message +queue. + +### Delete a message queue +Use the `unlink` command to delete a message queue. + +### Send a message to a queue +Use the `send` command to send a message to a message queue. Following +optional arguments are supported: +- `-n`, `--non-blocking`: Do not block +- `-d`, `--deadline `: Deadline until messages are sent + (format: `%Y-%m-%d %H:%M:%S`) +- `-p`, `--priority `: Use priority PRIO, PRIO >= 0 + [default: 0] +- `-o`, `--timeout `: Timeout in `[s]` (default) or + `ms` + +### Receive a message from a queue +Use the `recv` command to receive one or more messages from a message +queue. Following optional arguments are supported: +- `-f`, `--follow`: Print messages as they are received +- `-n`, `--non-blocking`: Do not block +- `-t`, `--timestamp`: Print a timestamp before each message +- `-d`, `--deadline `: Deadline until messages are received + (format: `%Y-%m-%d %H:%M:%S`) +- `-o,` `--timeout `: Timeout in `[s]` (default) or + `ms` From 8be1b23bad2caac2e8be01b331bdb6fc9e3e283a Mon Sep 17 00:00:00 2001 From: finga Date: Tue, 22 Jun 2021 01:39:24 +0200 Subject: [PATCH 10/38] Fix wrong help message --- src/send.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/send.rs b/src/send.rs index 3c310b8..cd368c1 100644 --- a/src/send.rs +++ b/src/send.rs @@ -15,7 +15,7 @@ pub struct Send { /// Timeout in "[s]" (default) or "ms" #[clap(short = 'o', long, conflicts_with = "deadline")] pub timeout: Option, - /// Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") + /// Deadline until messages are sent (format: "%Y-%m-%d %H:%M:%S") #[clap(short, long, conflicts_with = "timeout")] pub deadline: Option, /// Name of the queue From ac115a69664a48c0dd248464a7a4aaf325f2fb8f Mon Sep 17 00:00:00 2001 From: finga Date: Sat, 26 Jun 2021 23:09:40 +0200 Subject: [PATCH 11/38] Fix readme and clap help --- README.md | 2 +- src/create.rs | 2 +- src/recv.rs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3382452..23249a3 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ one you built. ## Using `mqrs` `mqrs` supports five commands: `create`, `info`, `unlink`, `send` and -`receive`. All commands do not have to be specified fully. If the +`recv`. All commands do not have to be specified fully. If the command is clearly distinguishable from all the others, it does not have to be completed further. diff --git a/src/create.rs b/src/create.rs index 4bb17eb..c55b555 100644 --- a/src/create.rs +++ b/src/create.rs @@ -15,7 +15,7 @@ pub struct Create { /// Message size in bytes #[clap(short = 's', long)] msgsize: Option, - /// Name of the queue + /// Name of the new queue #[clap(value_name = "QUEUE")] queue: String, } diff --git a/src/recv.rs b/src/recv.rs index 356829d..8c045d5 100644 --- a/src/recv.rs +++ b/src/recv.rs @@ -23,6 +23,7 @@ pub struct Recv { /// Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") #[clap(short, long, conflicts_with = "timeout")] pub deadline: Option, + /// Name of the queue #[clap(value_name = "QUEUE")] pub queue: String, } From 2a8488f7a8f95d65c5e5c1f183b7fe923bcb8c66 Mon Sep 17 00:00:00 2001 From: finga Date: Sat, 26 Jun 2021 23:10:28 +0200 Subject: [PATCH 12/38] Add manpage The manpage gets also installed with the debian package. --- Cargo.toml | 3 +- mqrs.1 | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 mqrs.1 diff --git a/Cargo.toml b/Cargo.toml index a3a6393..61c7b1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mqrs" -version = "0.1.0-dev" +version = "0.1.0" authors = ["finga "] edition = "2018" license = "GPL-3.0-or-later" @@ -18,4 +18,5 @@ extended-description = "`mqrs` is a small cli application to handle POSIX messag assets = [ ["target/release/mqrs", "usr/bin/", "755"], ["README.md", "usr/share/doc/cargo-deb/README.md", "644"], + ["mqrs.1", "/usr/share/man/man1/mqrs.1", "644"], ] diff --git a/mqrs.1 b/mqrs.1 new file mode 100644 index 0000000..f4af9fc --- /dev/null +++ b/mqrs.1 @@ -0,0 +1,192 @@ +.\" Manpage for mqrs +.TH man 1 "26 June 2021" "0.1.0" "mqrs man page" +.SH NAME +mqrs \- Handle POSIX message queues +.SH SYNOPSIS +.B mqrs [\-h] [\-\-help] [\-v] [\-\-verbose] [\-V] [\-\-version] [SUBCOMMAND] +.SH DESCRIPTION +.B mqrs +is a small cli program to handle POSIX message queues. Supported commands are +.B create\ +, +.B info\ +, +.B unlink\ +, +.B send +and +.B recv +. +All commands do not have to be specified fully. If the command is +clearly distinguishable from all the others, it does not have to be +completed further. +.SH OPTIONS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.TP 8 +.B \-V, \-\-version +Prints version information +.SH SUBCOMMANDS +.SS create [FLAGS] [OPTIONS] \fI\fP +Create a new POSIX message queue. +.TP 8 +.SS ARGS +.RS +.TP 8 +.B \fI\fP +Name of the new queue +.RE +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.TP 8 +.SS OPTIONS +.RS +.B \-c, \-\-capacity \fI\fP +Maximum number of messages in the queue +.TP 8 +.B \-s, \-\-msgsize \fI\fP +Message size in bytes +.TP 8 +.B \-p, \-\-permissions \fI\fP +Permissions (octal) to create the queue with +.RE +.SS help [SUBCOMMAND] +Prints this message or the help of the given subcommand. +.TP 8 +.SS ARGS +.RS +.TP 8 +.B \fI\fP +Show help for \fISUBCOMMAND\fP +.RE +.SS info [FLAGS] \fI\fP +Print further information about an existing message queue. +.TP 8 +.SS ARGS +.RS +.TP 8 +.B \fI\fP +Name of the queue +.RE +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.RE +.SS recv [FLAGS] [OPTIONS] \fI\fP +Receive and print one or more messages message from a message queue. +.TP 8 +.SS ARGS +.RS +.TP 8 +.B \fI\fP +Name of the queue +.RE +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-f, \-\-follow +Print messages as they are received +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-n, \-\-non\-blocking +Do not block +.TP 8 +.B \-t, \-\-timestamp +Print a timestamp before each message +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.RE +.TP 8 +.SS OPTIONS +.RS +.TP 8 +.B \-d, \-\-deadline \fI\fP +Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") +.TP 8 +.B \-o, \-\-timeout \fI\fP +Timeout in "[s]" (default) or "ms" +.RE +.SS send [FLAGS] [OPTIONS] \fI\fP \fI\fP +Send a message to a message queue. +.TP 8 +.SS ARGS +.RS +.TP 8 +.B \fI\fP +Name of the queue +.TP 8 +.B \fI\fP +Message to be sent to the queue +.RE +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-n, \-\-non\-blocking +Do not block +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.RE +.TP 8 +.SS OPTIONS +.RS +.TP 8 +.B \-d, \-\-deadline \fI\fP +Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") +.TP 8 +.B \-p, \-\-priority \fI\fP +Use priority PRIO, PRIO >= 0 [default: 0] +.TP 8 +.B \-o, \-\-timeout \fI\fP +Timeout in "[s]" (default) or "ms" +.RE +.SS unlink [FLAGS] \fI\fP +Deletes an existing POSIX message queue. +.TP 8 +.SS ARGS +.RS +.TP 8 +.B \fI\fP +Name of the queue +.RE +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.RE +.SH SEE ALSO +mq_overview(7) +.SH BUGS +No known bugs. +.SH AUTHOR +finga (mqrs@onders.org) From 851a387c82a4ab565ff072f1120b3bcb8faade26 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 27 Jun 2021 02:37:25 +0200 Subject: [PATCH 13/38] Cargo update and fix package version --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d2e6b2..a1e0a53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -122,7 +122,7 @@ checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" [[package]] name = "mqrs" -version = "0.1.0-dev" +version = "0.1.0" dependencies = [ "anyhow", "chrono", From 83e4ff36e5d0a1be07e8a8fffaf27f7f44d56585 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 27 Jun 2021 02:39:22 +0200 Subject: [PATCH 14/38] Use the `humantime` crate to parse `Duration` --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + README.md | 6 ++---- mqrs.1 | 4 ++-- src/main.rs | 1 - src/recv.rs | 6 +++--- src/send.rs | 6 +++--- src/utils.rs | 16 ---------------- 8 files changed, 18 insertions(+), 29 deletions(-) delete mode 100644 src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index a1e0a53..2e308d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -98,6 +98,12 @@ dependencies = [ "libc", ] +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "indexmap" version = "1.6.2" @@ -127,6 +133,7 @@ dependencies = [ "anyhow", "chrono", "clap", + "humantime", "posixmq", ] diff --git a/Cargo.toml b/Cargo.toml index 61c7b1f..a7b199d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ anyhow = "1.0" clap = "3.0.0-beta.2" posixmq = "1.0" chrono = "0.4" +humantime = "2.1" [package.metadata.deb] extended-description = "`mqrs` is a small cli application to handle POSIX message queues." diff --git a/README.md b/README.md index 23249a3..f0fce16 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,7 @@ optional arguments are supported: (format: `%Y-%m-%d %H:%M:%S`) - `-p`, `--priority `: Use priority PRIO, PRIO >= 0 [default: 0] -- `-o`, `--timeout `: Timeout in `[s]` (default) or - `ms` +- `-o`, `--timeout `: As for example in "5h 23min 42ms" ### Receive a message from a queue Use the `recv` command to receive one or more messages from a message @@ -84,5 +83,4 @@ queue. Following optional arguments are supported: - `-t`, `--timestamp`: Print a timestamp before each message - `-d`, `--deadline `: Deadline until messages are received (format: `%Y-%m-%d %H:%M:%S`) -- `-o,` `--timeout `: Timeout in `[s]` (default) or - `ms` +- `-o,` `--timeout `: As for example in "5h 23min 42ms" diff --git a/mqrs.1 b/mqrs.1 index f4af9fc..e2fb028 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -125,7 +125,7 @@ Produce verbose output Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") .TP 8 .B \-o, \-\-timeout \fI\fP -Timeout in "[s]" (default) or "ms" +Timeout as for example in "5h 23min 42ms" .RE .SS send [FLAGS] [OPTIONS] \fI\fP \fI\fP Send a message to a message queue. @@ -163,7 +163,7 @@ Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") Use priority PRIO, PRIO >= 0 [default: 0] .TP 8 .B \-o, \-\-timeout \fI\fP -Timeout in "[s]" (default) or "ms" +Timeout as for example in "5h 23min 42ms" .RE .SS unlink [FLAGS] \fI\fP Deletes an existing POSIX message queue. diff --git a/src/main.rs b/src/main.rs index 8cf86b7..a8a6481 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,6 @@ mod info; mod recv; mod send; mod unlink; -mod utils; #[derive(Clap, Debug)] #[clap( diff --git a/src/recv.rs b/src/recv.rs index 8c045d5..afb6758 100644 --- a/src/recv.rs +++ b/src/recv.rs @@ -1,7 +1,7 @@ -use crate::utils; use anyhow::Result; use chrono::{DateTime, Local}; use clap::Clap; +use humantime::Duration; use posixmq::PosixMq; use std::str; @@ -17,7 +17,7 @@ pub struct Recv { /// Print a timestamp before each message #[clap(short, long)] pub timestamp: bool, - /// Timeout in "[s]" (default) or "ms" + /// Timeout, example "5h 23min 42ms" #[clap(short = 'o', long, conflicts_with = "deadline")] pub timeout: Option, /// Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") @@ -45,7 +45,7 @@ impl Recv { let mut buf = vec![0; mq.attributes()?.max_msg_len]; if let Some(timeout) = &self.timeout { - let (prio, len) = mq.recv_timeout(&mut buf, utils::parse_duration(timeout)?)?; + let (prio, len) = mq.recv_timeout(&mut buf, *timeout.parse::()?)?; print_message(verbose, prio, len, self.timestamp, str::from_utf8(&buf)?); } else if let Some(deadline) = &self.deadline { diff --git a/src/send.rs b/src/send.rs index cd368c1..e9a8d5e 100644 --- a/src/send.rs +++ b/src/send.rs @@ -1,7 +1,7 @@ -use crate::utils; use anyhow::Result; use chrono::DateTime; use clap::Clap; +use humantime::Duration; /// Send a message to a message queue #[derive(Clap, Debug)] @@ -12,7 +12,7 @@ pub struct Send { /// Do not block #[clap(short, long)] pub non_blocking: bool, - /// Timeout in "[s]" (default) or "ms" + /// Timeout, example "5h 23min 42ms" #[clap(short = 'o', long, conflicts_with = "deadline")] pub timeout: Option, /// Deadline until messages are sent (format: "%Y-%m-%d %H:%M:%S") @@ -38,7 +38,7 @@ impl Send { mq.open(&self.queue)?.send_timeout( self.priority, &self.msg.as_bytes(), - utils::parse_duration(timeout)?, + *timeout.parse::()?, )?; if verbose { diff --git a/src/utils.rs b/src/utils.rs deleted file mode 100644 index f810f1e..0000000 --- a/src/utils.rs +++ /dev/null @@ -1,16 +0,0 @@ -use anyhow::Result; -use std::{str, time::Duration}; - -pub fn parse_duration(timeout: &str) -> Result { - if timeout.ends_with("ms") { - Ok(Duration::from_millis( - timeout[0..timeout.len() - 2].parse::()?, - )) - } else if timeout.ends_with("s") { - Ok(Duration::from_secs( - timeout[0..timeout.len() - 1].parse::()?, - )) - } else { - Ok(Duration::from_secs(timeout.parse::()?)) - } -} From 19130056ee08cf82f02d4818b68c1714ca032beb Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 27 Jun 2021 02:40:10 +0200 Subject: [PATCH 15/38] Expect instead of a lousy unwrap with comment --- src/create.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/create.rs b/src/create.rs index c55b555..eac24ac 100644 --- a/src/create.rs +++ b/src/create.rs @@ -22,14 +22,14 @@ pub struct Create { fn msgsize_default() -> usize { match fs::read_to_string("/proc/sys/fs/mqueue/msgsize_default") { - Ok(m) => m.trim().parse::().unwrap(), // should never fail + Ok(m) => m.trim().parse::().expect("can never fail"), _ => 8192, } } fn msg_default() -> usize { match fs::read_to_string("/proc/sys/fs/mqueue/msg_default") { - Ok(m) => m.trim().parse::().unwrap(), // should never fail + Ok(m) => m.trim().parse::().expect("can never fail"), _ => 10, } } From d88d69bbb1e6049112e22ef45d6a58cb5c70b90c Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 27 Jun 2021 02:41:40 +0200 Subject: [PATCH 16/38] Raise version to 0.1.1 - Improve `Duration` parsing needed for the timeout command line argument --- Cargo.lock | 2 +- Cargo.toml | 2 +- mqrs.1 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e308d4..50ea407 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,7 +128,7 @@ checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" [[package]] name = "mqrs" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "chrono", diff --git a/Cargo.toml b/Cargo.toml index a7b199d..073ba33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mqrs" -version = "0.1.0" +version = "0.1.1" authors = ["finga "] edition = "2018" license = "GPL-3.0-or-later" diff --git a/mqrs.1 b/mqrs.1 index e2fb028..b16690f 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -1,5 +1,5 @@ .\" Manpage for mqrs -.TH man 1 "26 June 2021" "0.1.0" "mqrs man page" +.TH man 1 "27 June 2021" "0.1.1" "mqrs man page" .SH NAME mqrs \- Handle POSIX message queues .SH SYNOPSIS From f0fb50bc2474e1855f197d6d9f0b8d01bfced142 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 27 Jun 2021 02:56:31 +0200 Subject: [PATCH 17/38] Improve help text --- README.md | 4 ++-- mqrs.1 | 2 +- src/send.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f0fce16..ebc9031 100644 --- a/README.md +++ b/README.md @@ -71,8 +71,8 @@ optional arguments are supported: - `-n`, `--non-blocking`: Do not block - `-d`, `--deadline `: Deadline until messages are sent (format: `%Y-%m-%d %H:%M:%S`) -- `-p`, `--priority `: Use priority PRIO, PRIO >= 0 - [default: 0] +- `-p`, `--priority `: Set a different priority than + default, priority >= 0 [default: 0] - `-o`, `--timeout `: As for example in "5h 23min 42ms" ### Receive a message from a queue diff --git a/mqrs.1 b/mqrs.1 index b16690f..795809a 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -160,7 +160,7 @@ Produce verbose output Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") .TP 8 .B \-p, \-\-priority \fI\fP -Use priority PRIO, PRIO >= 0 [default: 0] +Set a different priority than default, priority >= 0 [default: 0] .TP 8 .B \-o, \-\-timeout \fI\fP Timeout as for example in "5h 23min 42ms" diff --git a/src/send.rs b/src/send.rs index e9a8d5e..1e99346 100644 --- a/src/send.rs +++ b/src/send.rs @@ -6,7 +6,7 @@ use humantime::Duration; /// Send a message to a message queue #[derive(Clap, Debug)] pub struct Send { - /// Use priority PRIO, PRIO >= 0 + /// Set a different priority, priority >= 0 #[clap(short, long, default_value = "0")] pub priority: u32, /// Do not block From 606b4de524d93656674b8f94817684b7129c7dc6 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 27 Jun 2021 02:58:56 +0200 Subject: [PATCH 18/38] Use a fn for verbose output when sending --- src/send.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/send.rs b/src/send.rs index 1e99346..835b677 100644 --- a/src/send.rs +++ b/src/send.rs @@ -26,6 +26,12 @@ pub struct Send { pub msg: String, } +fn print_verbose(verbose: bool, msg: &str, queue: &str) { + if verbose { + println!("Sent message: \"{}\" to queue: {}", &msg, &queue); + } +} + impl Send { pub fn run(&self, verbose: bool) -> Result<()> { let mq = &mut posixmq::OpenOptions::writeonly(); @@ -41,9 +47,7 @@ impl Send { *timeout.parse::()?, )?; - if verbose { - println!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); - } + print_verbose(verbose, &self.msg, &self.queue); } else if let Some(deadline) = &self.deadline { mq.open(&self.queue)?.send_deadline( self.priority, @@ -51,16 +55,12 @@ impl Send { DateTime::parse_from_str(deadline, "%Y-%m-%d %H:%M:%S")?.into(), )?; - if verbose { - println!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); - } + print_verbose(verbose, &self.msg, &self.queue); } else { mq.open(&self.queue)? .send(self.priority, &self.msg.as_bytes())?; - if verbose { - println!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); - } + print_verbose(verbose, &self.msg, &self.queue); } Ok(()) From c2ad74ff1527bc39bdc85ef8ef7dd68b5985a1e7 Mon Sep 17 00:00:00 2001 From: finga Date: Wed, 30 Jun 2021 22:46:33 +0200 Subject: [PATCH 19/38] Remove `pub` declarations and move to `posix::*` This is in order to prepare also for SysV message queues. --- src/main.rs | 31 +++++++++++++------------------ src/posix.rs | 11 +++++++++++ src/{ => posix}/create.rs | 0 src/{ => posix}/info.rs | 0 src/{ => posix}/recv.rs | 0 src/{ => posix}/send.rs | 0 src/{ => posix}/unlink.rs | 0 7 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 src/posix.rs rename src/{ => posix}/create.rs (100%) rename src/{ => posix}/info.rs (100%) rename src/{ => posix}/recv.rs (100%) rename src/{ => posix}/send.rs (100%) rename src/{ => posix}/unlink.rs (100%) diff --git a/src/main.rs b/src/main.rs index a8a6481..ba152c7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,16 @@ -use crate::{create::Create, info::Info, recv::Recv, send::Send, unlink::Unlink}; use anyhow::Result; use clap::{crate_authors, crate_version, AppSettings, Clap}; -mod create; -mod info; -mod recv; -mod send; -mod unlink; +mod posix; + +#[derive(Clap, Debug)] +enum Command { + Create(posix::Create), + Info(posix::Info), + Unlink(posix::Unlink), + Send(posix::Send), + Recv(posix::Recv), +} #[derive(Clap, Debug)] #[clap( @@ -16,21 +20,12 @@ mod unlink; global_setting = AppSettings::VersionlessSubcommands, global_setting = AppSettings::InferSubcommands, )] -pub struct Opts { +struct Opts { /// Produce verbose output #[clap(short, long, global = true)] - pub verbose: bool, + verbose: bool, #[clap(subcommand)] - pub command: Command, -} - -#[derive(Clap, Debug)] -pub enum Command { - Create(Create), - Info(Info), - Unlink(Unlink), - Send(Send), - Recv(Recv), + command: Command, } fn main() -> Result<()> { diff --git a/src/posix.rs b/src/posix.rs new file mode 100644 index 0000000..d9e6266 --- /dev/null +++ b/src/posix.rs @@ -0,0 +1,11 @@ +mod create; +mod info; +mod recv; +mod send; +mod unlink; + +pub use create::Create; +pub use info::Info; +pub use recv::Recv; +pub use send::Send; +pub use unlink::Unlink; diff --git a/src/create.rs b/src/posix/create.rs similarity index 100% rename from src/create.rs rename to src/posix/create.rs diff --git a/src/info.rs b/src/posix/info.rs similarity index 100% rename from src/info.rs rename to src/posix/info.rs diff --git a/src/recv.rs b/src/posix/recv.rs similarity index 100% rename from src/recv.rs rename to src/posix/recv.rs diff --git a/src/send.rs b/src/posix/send.rs similarity index 100% rename from src/send.rs rename to src/posix/send.rs diff --git a/src/unlink.rs b/src/posix/unlink.rs similarity index 100% rename from src/unlink.rs rename to src/posix/unlink.rs From 6a41335603237c51b4e9e426e75e8e691c52607f Mon Sep 17 00:00:00 2001 From: finga Date: Wed, 30 Jun 2021 22:50:07 +0200 Subject: [PATCH 20/38] Cargo update --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 50ea407..8034921 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,9 +76,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "heck" @@ -106,9 +106,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "indexmap" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", "hashbrown", From 12b117db7e7528d6289a2933279221efb1f3db6e Mon Sep 17 00:00:00 2001 From: finga Date: Wed, 7 Jul 2021 17:13:08 +0200 Subject: [PATCH 21/38] Refactor logging To supporte more than a single log level `log` and `env_logger` crates are used. For the application to support the different type of argument, the verbose argument definition was adapted. --- Cargo.lock | 64 +++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ mqrs.1 | 3 ++- src/main.rs | 24 ++++++++++++----- src/posix/create.rs | 7 ++--- src/posix/recv.rs | 21 +++++++-------- src/posix/send.rs | 15 ++++------- src/posix/unlink.rs | 7 +++-- 8 files changed, 107 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8034921..afa11c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,16 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "anyhow" version = "1.0.41" @@ -29,6 +40,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[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.19" @@ -74,6 +91,19 @@ dependencies = [ "syn", ] +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -126,6 +156,21 @@ version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + [[package]] name = "mqrs" version = "0.1.1" @@ -133,7 +178,9 @@ dependencies = [ "anyhow", "chrono", "clap", + "env_logger", "humantime", + "log", "posixmq", ] @@ -213,6 +260,23 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "strsim" version = "0.10.0" diff --git a/Cargo.toml b/Cargo.toml index 073ba33..a42c1c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,8 @@ clap = "3.0.0-beta.2" posixmq = "1.0" chrono = "0.4" humantime = "2.1" +log = "0.4" +env_logger = "0.8" [package.metadata.deb] extended-description = "`mqrs` is a small cli application to handle POSIX message queues." diff --git a/mqrs.1 b/mqrs.1 index 795809a..50fa2d0 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -26,7 +26,8 @@ completed further. Prints help information .TP 8 .B \-v, \-\-verbose -Produce verbose output +Produce verbose output, multiple -v options increase the verbosity +(max. 3) .TP 8 .B \-V, \-\-version Prints version information diff --git a/src/main.rs b/src/main.rs index ba152c7..40296fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,9 +21,9 @@ enum Command { global_setting = AppSettings::InferSubcommands, )] struct Opts { - /// Produce verbose output - #[clap(short, long, global = true)] - verbose: bool, + /// Produce verbose output, multiple -v options increase the verbosity (max. 3) + #[clap(short, long, global = true, parse(from_occurrences))] + verbose: u32, #[clap(subcommand)] command: Command, } @@ -31,12 +31,22 @@ struct Opts { fn main() -> Result<()> { let opts: Opts = Opts::parse(); + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or( + match opts.verbose { + 0 => "warn", + 1 => "info", + 2 => "debug", + _ => "trace", + }, + )) + .init(); + match opts.command { - Command::Create(c) => c.run(opts.verbose)?, + Command::Create(c) => c.run()?, Command::Info(i) => i.run()?, - Command::Unlink(u) => u.run(opts.verbose)?, - Command::Send(s) => s.run(opts.verbose)?, - Command::Recv(r) => r.run(opts.verbose)?, + Command::Unlink(u) => u.run()?, + Command::Send(s) => s.run()?, + Command::Recv(r) => r.run()?, } Ok(()) diff --git a/src/posix/create.rs b/src/posix/create.rs index eac24ac..d475d36 100644 --- a/src/posix/create.rs +++ b/src/posix/create.rs @@ -1,5 +1,6 @@ use anyhow::Result; use clap::Clap; +use log::{info, log_enabled, Level::Info}; use posixmq::PosixMq; use std::fs; @@ -35,7 +36,7 @@ fn msg_default() -> usize { } impl Create { - pub fn run(&self, verbose: bool) -> Result<()> { + pub fn run(&self) -> Result<()> { let mq = &mut posixmq::OpenOptions::readonly(); if let Some(m) = &self.permissions { @@ -47,11 +48,11 @@ impl Create { .create_new() .open(&self.queue)?; - if verbose { + if log_enabled!(Info) { let mq = PosixMq::open(&self.queue)?; let attributes = mq.attributes()?; - println!("Created message queue: {} with attributes msgsize: {}, capacity: {}, current_messages: {}", + info!("Created message queue: {} with attributes msgsize: {}, capacity: {}, current_messages: {}", &self.queue, &attributes.max_msg_len, &attributes.capacity, diff --git a/src/posix/recv.rs b/src/posix/recv.rs index afb6758..0b8563a 100644 --- a/src/posix/recv.rs +++ b/src/posix/recv.rs @@ -2,6 +2,7 @@ use anyhow::Result; use chrono::{DateTime, Local}; use clap::Clap; use humantime::Duration; +use log::info; use posixmq::PosixMq; use std::str; @@ -28,10 +29,8 @@ pub struct Recv { pub queue: String, } -fn print_message(verbose: bool, priority: u32, length: usize, timestamp: bool, msg: &str) { - if verbose { - println!("Priority: {}, length: {}", priority, length); - } +fn print_message(priority: u32, length: usize, timestamp: bool, msg: &str) { + info!("Priority: {}, length: {}", priority, length); if timestamp { println!("{}", Local::now()); @@ -41,30 +40,30 @@ fn print_message(verbose: bool, priority: u32, length: usize, timestamp: bool, m } impl Recv { - fn receive(&self, verbose: bool, mq: &PosixMq) -> Result<()> { + fn receive(&self, mq: &PosixMq) -> Result<()> { let mut buf = vec![0; mq.attributes()?.max_msg_len]; if let Some(timeout) = &self.timeout { let (prio, len) = mq.recv_timeout(&mut buf, *timeout.parse::()?)?; - print_message(verbose, prio, len, self.timestamp, str::from_utf8(&buf)?); + print_message(prio, len, self.timestamp, str::from_utf8(&buf)?); } else if let Some(deadline) = &self.deadline { let (prio, len) = mq.recv_deadline( &mut buf, DateTime::parse_from_str(deadline, "%Y-%m-%d %H:%M:%S")?.into(), )?; - print_message(verbose, prio, len, self.timestamp, str::from_utf8(&buf)?); + print_message(prio, len, self.timestamp, str::from_utf8(&buf)?); } else { let (prio, len) = mq.recv(&mut buf)?; - print_message(verbose, prio, len, self.timestamp, str::from_utf8(&buf)?); + print_message(prio, len, self.timestamp, str::from_utf8(&buf)?); } Ok(()) } - pub fn run(&self, verbose: bool) -> Result<()> { + pub fn run(&self) -> Result<()> { let mq = &mut posixmq::OpenOptions::readonly(); if self.non_blocking { @@ -75,10 +74,10 @@ impl Recv { if self.follow { loop { - self.receive(verbose, &mq)?; + self.receive(&mq)?; } } else { - self.receive(verbose, &mq)?; + self.receive(&mq)?; } Ok(()) diff --git a/src/posix/send.rs b/src/posix/send.rs index 835b677..917679b 100644 --- a/src/posix/send.rs +++ b/src/posix/send.rs @@ -2,6 +2,7 @@ use anyhow::Result; use chrono::DateTime; use clap::Clap; use humantime::Duration; +use log::info; /// Send a message to a message queue #[derive(Clap, Debug)] @@ -26,14 +27,8 @@ pub struct Send { pub msg: String, } -fn print_verbose(verbose: bool, msg: &str, queue: &str) { - if verbose { - println!("Sent message: \"{}\" to queue: {}", &msg, &queue); - } -} - impl Send { - pub fn run(&self, verbose: bool) -> Result<()> { + pub fn run(&self) -> Result<()> { let mq = &mut posixmq::OpenOptions::writeonly(); if self.non_blocking { @@ -47,7 +42,7 @@ impl Send { *timeout.parse::()?, )?; - print_verbose(verbose, &self.msg, &self.queue); + info!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); } else if let Some(deadline) = &self.deadline { mq.open(&self.queue)?.send_deadline( self.priority, @@ -55,12 +50,12 @@ impl Send { DateTime::parse_from_str(deadline, "%Y-%m-%d %H:%M:%S")?.into(), )?; - print_verbose(verbose, &self.msg, &self.queue); + info!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); } else { mq.open(&self.queue)? .send(self.priority, &self.msg.as_bytes())?; - print_verbose(verbose, &self.msg, &self.queue); + info!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); } Ok(()) diff --git a/src/posix/unlink.rs b/src/posix/unlink.rs index ae837e1..4b89a27 100644 --- a/src/posix/unlink.rs +++ b/src/posix/unlink.rs @@ -1,5 +1,6 @@ use anyhow::Result; use clap::Clap; +use log::info; /// Delete a message queue #[derive(Clap, Debug)] @@ -10,12 +11,10 @@ pub struct Unlink { } impl Unlink { - pub fn run(&self, verbose: bool) -> Result<()> { + pub fn run(&self) -> Result<()> { posixmq::remove_queue(&self.queue)?; - if verbose { - println!("Removed message queue: {}", &self.queue); - } + info!("Removed message queue: {}", &self.queue); Ok(()) } From 4020f062efbd5943e3b4c61e9d56ad51bfb1623e Mon Sep 17 00:00:00 2001 From: finga Date: Wed, 7 Jul 2021 18:27:41 +0200 Subject: [PATCH 22/38] Add new subcommand `list` Also add it to the readme and manpage. --- README.md | 13 +++++++---- mqrs.1 | 21 +++++++++++++++-- src/main.rs | 2 ++ src/posix.rs | 2 ++ src/posix/list.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 src/posix/list.rs diff --git a/README.md b/README.md index ebc9031..db90769 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,10 @@ from `target/{debug,release}/mqrs` depending on which one you built. ## Using `mqrs` -`mqrs` supports five commands: `create`, `info`, `unlink`, `send` and -`recv`. All commands do not have to be specified fully. If the -command is clearly distinguishable from all the others, it does not -have to be completed further. +`mqrs` supports five commands: `create`, `info`, `list`, `unlink`, +`send` and `recv`. All commands do not have to be specified fully. If +the command is clearly distinguishable from all the others, it does +not have to be completed further. ### Create a message queue Use the `create` command to create a new POSIX message queue. Following @@ -62,6 +62,11 @@ optional arguments are supported: Use the `info` command to print further information about a message queue. +### List all message queues +Use the `list` command to print a list of all message +queues. Following option argument is supported: +- `-a`, `--all`: Print all available information + ### Delete a message queue Use the `unlink` command to delete a message queue. diff --git a/mqrs.1 b/mqrs.1 index 50fa2d0..a7dceca 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -11,6 +11,8 @@ is a small cli program to handle POSIX message queues. Supported commands are , .B info\ , +.B list\ +, .B unlink\ , .B send @@ -18,8 +20,8 @@ and .B recv . All commands do not have to be specified fully. If the command is -clearly distinguishable from all the others, it does not have to be -completed further. +clearly distinguishable from all the others, it is not needed to +complete it further. .SH OPTIONS .TP 8 .B \-h, \-\-help @@ -90,6 +92,21 @@ Prints help information .B \-v, \-\-verbose Produce verbose output .RE +.SS list [FLAGS] +Print a list of all existing POSIX message queues. +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.TP 8 +.B \-a, \-\-all +Print all available information +.RE .SS recv [FLAGS] [OPTIONS] \fI\fP Receive and print one or more messages message from a message queue. .TP 8 diff --git a/src/main.rs b/src/main.rs index 40296fb..bf3fb61 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ mod posix; enum Command { Create(posix::Create), Info(posix::Info), + List(posix::List), Unlink(posix::Unlink), Send(posix::Send), Recv(posix::Recv), @@ -47,6 +48,7 @@ fn main() -> Result<()> { Command::Unlink(u) => u.run()?, Command::Send(s) => s.run()?, Command::Recv(r) => r.run()?, + Command::List(l) => l.run()?, } Ok(()) diff --git a/src/posix.rs b/src/posix.rs index d9e6266..c5855c8 100644 --- a/src/posix.rs +++ b/src/posix.rs @@ -1,11 +1,13 @@ mod create; mod info; +mod list; mod recv; mod send; mod unlink; pub use create::Create; pub use info::Info; +pub use list::List; pub use recv::Recv; pub use send::Send; pub use unlink::Unlink; diff --git a/src/posix/list.rs b/src/posix/list.rs new file mode 100644 index 0000000..54c031a --- /dev/null +++ b/src/posix/list.rs @@ -0,0 +1,58 @@ +use anyhow::{anyhow, Result}; +use chrono::{DateTime, Local}; +use clap::Clap; +use log::warn; +use std::{fs, os::unix::fs::PermissionsExt}; + +/// Print information about an existing message queue +#[derive(Clap, Debug)] +pub struct List { + /// Show all parameters + #[clap(short, long)] + all: bool, +} + +impl List { + pub fn run(&self) -> Result<()> { + match self.all { + false => println!("Name"), + true => println!( + "{0: <10} {1: <10} {2: <12} {3: <26} {4: <26}", + "Name", "Size", "Permissions", "Modified", "Accessed", + ), + } + + for mq in fs::read_dir("/dev/mqueue")? { + match mq { + Ok(mq) => { + print!( + "/{0: <10}", + mq.file_name().into_string().map_err(|e| anyhow!( + "Could not convert queue name to string: {:?}", + e + ))? + ); + + if self.all { + let metadata = mq.metadata()?; + let modified: DateTime = metadata.modified()?.into(); + let accessed: DateTime = metadata.accessed()?.into(); + + print!( + "{0: <10} {1: <12o} {2: <26} {3: <26}", + metadata.len(), + metadata.permissions().mode(), + modified, + accessed, + ); + } + + println!(); + } + Err(e) => warn!("Could not read file: {:?}", e), + } + } + + Ok(()) + } +} From 9aae14feae41de7df997d7e88e0f8370ad2e0cbe Mon Sep 17 00:00:00 2001 From: finga Date: Wed, 7 Jul 2021 19:19:19 +0200 Subject: [PATCH 23/38] Refactor commands to support different backends Therefore also the `sysv` backend is intoduced to prepare for future support. The man page and the readme are updated so far. --- README.md | 30 ++++++++++++++++++++---------- mqrs.1 | 43 ++++++++++++++++++++++++++----------------- src/main.rs | 35 ++++++++++++++++++++++++++--------- 3 files changed, 72 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index db90769..d274168 100644 --- a/README.md +++ b/README.md @@ -46,31 +46,38 @@ from `target/{debug,release}/mqrs` depending on which one you built. ## Using `mqrs` -`mqrs` supports five commands: `create`, `info`, `list`, `unlink`, -`send` and `recv`. All commands do not have to be specified fully. If -the command is clearly distinguishable from all the others, it does -not have to be completed further. +Depending on which backend you want to use there are different subsets +of subcommands. Following backends are supported: +- `posix`: Uses POSIX message queues +- `sysv`: Uses SysV IPC message queues -### Create a message queue +If a command is clearly distinguishable from all the others, +it does not have to be completed further. + +### POSIX message queues +The POSIX backend supports six commands: `create`, `info`, `list`, +`unlink`, `send` and `recv`. + +#### Create a message queue Use the `create` command to create a new POSIX message queue. Following optional arguments are supported: - `-c`, `--capacity`: Maximum number of messages in the queue - `-p`, `--permissions`: Permissions (octal) to create the queue with - `-s`, `--msgsize`: Message size in bytes -### Print information about a message queue +#### Print information about a message queue Use the `info` command to print further information about a message queue. -### List all message queues +#### List all message queues Use the `list` command to print a list of all message queues. Following option argument is supported: - `-a`, `--all`: Print all available information -### Delete a message queue +#### Delete a message queue Use the `unlink` command to delete a message queue. -### Send a message to a queue +#### Send a message to a queue Use the `send` command to send a message to a message queue. Following optional arguments are supported: - `-n`, `--non-blocking`: Do not block @@ -80,7 +87,7 @@ optional arguments are supported: default, priority >= 0 [default: 0] - `-o`, `--timeout `: As for example in "5h 23min 42ms" -### Receive a message from a queue +#### Receive a message from a queue Use the `recv` command to receive one or more messages from a message queue. Following optional arguments are supported: - `-f`, `--follow`: Print messages as they are received @@ -89,3 +96,6 @@ queue. Following optional arguments are supported: - `-d`, `--deadline `: Deadline until messages are received (format: `%Y-%m-%d %H:%M:%S`) - `-o,` `--timeout `: As for example in "5h 23min 42ms" + +### SysV IPC message queues +The SysV IPC backend supports no commands yet. diff --git a/mqrs.1 b/mqrs.1 index a7dceca..9934081 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -1,12 +1,34 @@ .\" Manpage for mqrs -.TH man 1 "27 June 2021" "0.1.1" "mqrs man page" +.TH man 1 "7 July 2021" "0.1.1" "mqrs man page" .SH NAME mqrs \- Handle POSIX message queues .SH SYNOPSIS .B mqrs [\-h] [\-\-help] [\-v] [\-\-verbose] [\-V] [\-\-version] [SUBCOMMAND] .SH DESCRIPTION .B mqrs -is a small cli program to handle POSIX message queues. Supported commands are +is a small cli program to handle message queues. Depending on which +backend you want to use there are different subsets of +subcommands. Following backends are supported: +.B posix\ +and +.B sysv\ +. + +If a command is clearly distinguishable from all the others, it does +not have to be completed further. +.SH OPTIONS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output, multiple -v options increase the verbosity +(max. 3) +.TP 8 +.B \-V, \-\-version +Prints version information +.SH POSIX MESSAGE QUEUE SUBCOMMANDS +The POSIX backend supports six commands: .B create\ , .B info\ @@ -19,21 +41,6 @@ is a small cli program to handle POSIX message queues. Supported commands are and .B recv . -All commands do not have to be specified fully. If the command is -clearly distinguishable from all the others, it is not needed to -complete it further. -.SH OPTIONS -.TP 8 -.B \-h, \-\-help -Prints help information -.TP 8 -.B \-v, \-\-verbose -Produce verbose output, multiple -v options increase the verbosity -(max. 3) -.TP 8 -.B \-V, \-\-version -Prints version information -.SH SUBCOMMANDS .SS create [FLAGS] [OPTIONS] \fI\fP Create a new POSIX message queue. .TP 8 @@ -202,6 +209,8 @@ Prints help information .B \-v, \-\-verbose Produce verbose output .RE +.SH SYSV IPC MESSAGE QUEUE SUBCOMMANDS +The SysV IPC backend supports no commands yet. .SH SEE ALSO mq_overview(7) .SH BUGS diff --git a/src/main.rs b/src/main.rs index bf3fb61..cc1d185 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,15 @@ use clap::{crate_authors, crate_version, AppSettings, Clap}; mod posix; #[derive(Clap, Debug)] -enum Command { +enum Backend { + /// Handle POSIX message queues + Posix(PosixCommand), + /// Handle SysV message queues + Sysv(SysvCommand), +} + +#[derive(Clap, Debug)] +enum PosixCommand { Create(posix::Create), Info(posix::Info), List(posix::List), @@ -13,6 +21,10 @@ enum Command { Recv(posix::Recv), } +#[derive(Clap, Debug)] +enum SysvCommand { +} + #[derive(Clap, Debug)] #[clap( version = crate_version!(), @@ -25,8 +37,9 @@ struct Opts { /// Produce verbose output, multiple -v options increase the verbosity (max. 3) #[clap(short, long, global = true, parse(from_occurrences))] verbose: u32, + /// Backend to be used #[clap(subcommand)] - command: Command, + backend: Backend, } fn main() -> Result<()> { @@ -42,13 +55,17 @@ fn main() -> Result<()> { )) .init(); - match opts.command { - Command::Create(c) => c.run()?, - Command::Info(i) => i.run()?, - Command::Unlink(u) => u.run()?, - Command::Send(s) => s.run()?, - Command::Recv(r) => r.run()?, - Command::List(l) => l.run()?, + match opts.backend { + Backend::Posix(p) => match p { + PosixCommand::Create(c) => c.run()?, + PosixCommand::Info(i) => i.run()?, + PosixCommand::List(l) => l.run()?, + PosixCommand::Unlink(u) => u.run()?, + PosixCommand::Send(s) => s.run()?, + PosixCommand::Recv(r) => r.run()?, + }, + Backend::Sysv(s) => match s { + }, } Ok(()) From 07decf7b367374e90e21e1230284fced4a00f128 Mon Sep 17 00:00:00 2001 From: finga Date: Wed, 7 Jul 2021 19:30:18 +0200 Subject: [PATCH 24/38] Add debian package build information in readme Add prerequisites for building a debian package. --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d274168..5a3008e 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,13 @@ cargo b --release ``` ### Build the `mqrs` Debian package +For that [`cargo-deb`](https://github.com/mmstick/cargo-deb) is +required, which can be installed with: +```sh +cargo install cargo-deb +``` + +A Debian package can be built with: ```sh cargo deb ``` @@ -42,8 +49,7 @@ cargo b ``` or you can copy the produced binary somewhere else or link to them -from `target/{debug,release}/mqrs` depending on which -one you built. +from `target/{debug,release}/mqrs` depending on which one you built. ## Using `mqrs` Depending on which backend you want to use there are different subsets From a468c5d7bbf5016bff730601629a8786b3bf69a4 Mon Sep 17 00:00:00 2001 From: finga Date: Wed, 7 Jul 2021 19:35:32 +0200 Subject: [PATCH 25/38] Move install section into its own file To keep the readme manageable and clear move help about how to build, install and run into its own file. --- INSTALL.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 52 +++------------------------------------------------- 2 files changed, 52 insertions(+), 49 deletions(-) create mode 100644 INSTALL.md diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..7b638ed --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,49 @@ +# Installation +To build `mqrs` having the rust toolchain installed is mandatory. + +## Install Rust +Install the Rust toolchain from [rustup.rs](https://rustup.rs). + +## Build `mqrs` +`mqrs` can be built for development: +```sh +cargo b +``` + +or for releasing: +```sh +cargo b --release +``` + +## Build the `mqrs` Debian package +For that [`cargo-deb`](https://github.com/mmstick/cargo-deb) is +required, which can be installed with: +```sh +cargo install cargo-deb +``` + +A Debian package can be built with: +```sh +cargo deb +``` + +## Install `mqrs` +When a Rust toolchain installed you can also install `mqrs` +directly without cloning it manually: +``` sh +cargo install --git https://git.onders.org/finga/mqrs.git mqrs +``` + +or from within the project: +```sh +cargo install mqrs +``` + +## Run `mqrs` +`mqrs` can either be run from the project directory with: +```sh +cargo b +``` + +or you can copy the produced binary somewhere else or link to them +from `target/{debug,release}/mqrs` depending on which one you built. diff --git a/README.md b/README.md index 5a3008e..588dfe4 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,9 @@ # mqrs `mqrs` is a small cli application to handle POSIX message queues. -## Installation -To build `mqrs` a rust toolchain is necessary. - -### Install Rust -Install the Rust toolchain from [rustup.rs](https://rustup.rs). - -### Build `mqrs` -`mqrs` can be built for development: -```sh -cargo b -``` - -or for releasing: -```sh -cargo b --release -``` - -### Build the `mqrs` Debian package -For that [`cargo-deb`](https://github.com/mmstick/cargo-deb) is -required, which can be installed with: -```sh -cargo install cargo-deb -``` - -A Debian package can be built with: -```sh -cargo deb -``` - -### Install `mqrs` -When a Rust toolchain installed you can also install `mqrs` -directly without cloning it manually: -``` sh -cargo install --git https://git.onders.org/finga/mqrs.git mqrs -``` - -or from within the project: -```sh -cargo install mqrs -``` - -### Run `mqrs` -`mqrs` can either be run from the project directory with: -```sh -cargo b -``` - -or you can copy the produced binary somewhere else or link to them -from `target/{debug,release}/mqrs` depending on which one you built. +## Install `mqrs` +For information about how to build, install and run `mqrs` please see +[`INSTALL.md`](INSTALL.md). ## Using `mqrs` Depending on which backend you want to use there are different subsets From 4d200bb5f3d03d10e55672c2ee3ec398a89a67a4 Mon Sep 17 00:00:00 2001 From: finga Date: Wed, 7 Jul 2021 20:23:04 +0200 Subject: [PATCH 26/38] Implement creation of SysV IPC message queues This adds the `sysvmq` package which handles SysV IPC message queues. For consistency the parameter for `permissions` is renamed to `mode` also for POSIX message queues. --- Cargo.lock | 66 ++++++++++++++++++++++++-- Cargo.toml | 7 +++ README.md | 10 +++- mqrs.1 | 32 ++++++++++++- src/main.rs | 3 ++ src/posix/create.rs | 4 +- src/sysv.rs | 3 ++ src/sysv/create.rs | 31 +++++++++++++ sysvmq/.gitignore | 2 + sysvmq/Cargo.toml | 12 +++++ sysvmq/src/lib.rs | 111 ++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 271 insertions(+), 10 deletions(-) create mode 100644 src/sysv.rs create mode 100644 src/sysv/create.rs create mode 100644 sysvmq/.gitignore create mode 100644 sysvmq/Cargo.toml create mode 100644 sysvmq/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index afa11c4..3c4a517 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,6 +40,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "cc" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" + [[package]] name = "cfg-if" version = "1.0.0" @@ -152,9 +158,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.97" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "log" @@ -171,6 +177,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + [[package]] name = "mqrs" version = "0.1.1" @@ -182,6 +197,20 @@ dependencies = [ "humantime", "log", "posixmq", + "sysvmq", +] + +[[package]] +name = "nix" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3728fec49d363a50a8828a190b379a446cc5cf085c06259bbbeb34447e4ec7" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", ] [[package]] @@ -294,6 +323,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "sysvmq" +version = "0.1.0" +dependencies = [ + "libc", + "nix", + "thiserror", +] + [[package]] name = "termcolor" version = "1.1.2" @@ -312,6 +350,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.1.44" @@ -325,9 +383,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" diff --git a/Cargo.toml b/Cargo.toml index a42c1c3..edbaea8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,9 +3,12 @@ name = "mqrs" version = "0.1.1" authors = ["finga "] edition = "2018" +repository = "https://git.onders.org/finga/mqrs" license = "GPL-3.0-or-later" readme = "README.md" description = "A CLI program for interacting with Posix Message Queues." +keywords = ["message_queue", "mq", "mqueue", "queue"] +categories = ["command-line-utilities"] [dependencies] anyhow = "1.0" @@ -15,6 +18,10 @@ chrono = "0.4" humantime = "2.1" log = "0.4" env_logger = "0.8" +sysvmq = { path = "sysvmq" } + +[workspace] +members = ["sysvmq"] [package.metadata.deb] extended-description = "`mqrs` is a small cli application to handle POSIX message queues." diff --git a/README.md b/README.md index 588dfe4..4f82cfa 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ The POSIX backend supports six commands: `create`, `info`, `list`, Use the `create` command to create a new POSIX message queue. Following optional arguments are supported: - `-c`, `--capacity`: Maximum number of messages in the queue -- `-p`, `--permissions`: Permissions (octal) to create the queue with +- `-m`, `--mode`: Permissions (octal) to create the queue with - `-s`, `--msgsize`: Message size in bytes #### Print information about a message queue @@ -58,4 +58,10 @@ queue. Following optional arguments are supported: - `-o,` `--timeout `: As for example in "5h 23min 42ms" ### SysV IPC message queues -The SysV IPC backend supports no commands yet. +The SysV IPC backend supports one command: `create`. + +#### Create a message queue +Use the `create` command to create a new SysV IPC message +queue. Following optional arguments are supported: +- `-m`, `--mode`: Permissions (octal) to create the queue + with. Default: 0644. diff --git a/mqrs.1 b/mqrs.1 index 9934081..0058957 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -62,13 +62,14 @@ Produce verbose output .TP 8 .SS OPTIONS .RS +.TP 8 .B \-c, \-\-capacity \fI\fP Maximum number of messages in the queue .TP 8 .B \-s, \-\-msgsize \fI\fP Message size in bytes .TP 8 -.B \-p, \-\-permissions \fI\fP +.B \-m, \-\-mode \fI\fP Permissions (octal) to create the queue with .RE .SS help [SUBCOMMAND] @@ -210,7 +211,34 @@ Prints help information Produce verbose output .RE .SH SYSV IPC MESSAGE QUEUE SUBCOMMANDS -The SysV IPC backend supports no commands yet. +The SysV IPC backend supports one command: +.B create\ +. +.SS create [FLAGS] [OPTIONS] \fI\fP +Create a new SysV IPC message queue. +.TP 8 +.SS ARGS +.RS +.TP 8 +.B \fI\fP +Key of the new queue +.RE +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.TP 8 +.SS OPTIONS +.RS +.TP 8 +.B \-m, \-\-mode \fI\fP +Permissions (octal) to create the queue with (default: 0644) +.RE .SH SEE ALSO mq_overview(7) .SH BUGS diff --git a/src/main.rs b/src/main.rs index cc1d185..78109dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use anyhow::Result; use clap::{crate_authors, crate_version, AppSettings, Clap}; mod posix; +mod sysv; #[derive(Clap, Debug)] enum Backend { @@ -23,6 +24,7 @@ enum PosixCommand { #[derive(Clap, Debug)] enum SysvCommand { + Create(sysv::Create), } #[derive(Clap, Debug)] @@ -65,6 +67,7 @@ fn main() -> Result<()> { PosixCommand::Recv(r) => r.run()?, }, Backend::Sysv(s) => match s { + SysvCommand::Create(c) => c.run()?, }, } diff --git a/src/posix/create.rs b/src/posix/create.rs index d475d36..be4606b 100644 --- a/src/posix/create.rs +++ b/src/posix/create.rs @@ -9,7 +9,7 @@ use std::fs; pub struct Create { /// Permissions (octal) to create the queue with #[clap(short, long)] - permissions: Option, + mode: Option, /// Maximum number of messages in the queue #[clap(short, long)] capacity: Option, @@ -39,7 +39,7 @@ impl Create { pub fn run(&self) -> Result<()> { let mq = &mut posixmq::OpenOptions::readonly(); - if let Some(m) = &self.permissions { + if let Some(m) = &self.mode { mq.mode(u32::from_str_radix(&m, 8)?); } diff --git a/src/sysv.rs b/src/sysv.rs new file mode 100644 index 0000000..5ed245c --- /dev/null +++ b/src/sysv.rs @@ -0,0 +1,3 @@ +mod create; + +pub use create::Create; diff --git a/src/sysv/create.rs b/src/sysv/create.rs new file mode 100644 index 0000000..e4b03a6 --- /dev/null +++ b/src/sysv/create.rs @@ -0,0 +1,31 @@ +use anyhow::Result; +use clap::Clap; +use log::info; +use sysvmq::SysvMq; + +/// Create a SysV message queue +#[derive(Clap, Debug)] +pub struct Create { + /// Permissions (octal) to create the queue with (default: 0644) + #[clap(short, long)] + mode: Option, + /// Key of the new queue + #[clap(value_name = "KEY")] + key: i32, +} + +impl Create { + pub fn run(&self) -> Result<()> { + let mut mq = SysvMq::::new(); + + if let Some(m) = &self.mode { + mq.mode(i32::from_str_radix(&m, 8)?); + } + + mq.create(self.key)?; + + info!("SysV message queue created, key: {}, id: {}", mq.key, mq.id); + + Ok(()) + } +} diff --git a/sysvmq/.gitignore b/sysvmq/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/sysvmq/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/sysvmq/Cargo.toml b/sysvmq/Cargo.toml new file mode 100644 index 0000000..a2cee0f --- /dev/null +++ b/sysvmq/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "sysvmq" +version = "0.1.0" +edition = "2018" +authors = ["finga "] +repository = "https://git.onders.org/finga/mqrs" +license = "GPL-3.0-or-later" + +[dependencies] +libc = "0.2.98" +thiserror = "1.0.26" +nix = "0.21.0" diff --git a/sysvmq/src/lib.rs b/sysvmq/src/lib.rs new file mode 100644 index 0000000..7f7e4e3 --- /dev/null +++ b/sysvmq/src/lib.rs @@ -0,0 +1,111 @@ +use libc::{ + msgget, IPC_CREAT, IPC_EXCL, IPC_INFO, IPC_NOWAIT, IPC_PRIVATE, IPC_RMID, IPC_SET, IPC_STAT, + MSG_COPY, MSG_EXCEPT, MSG_INFO, MSG_NOERROR, MSG_STAT, +}; +use nix::errno::{errno, Errno}; +use std::{marker::PhantomData, num::ParseIntError}; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum SysvMqError { + #[error("SysV message queue: {0}")] + ErrnoError(&'static str), + #[error("No message queue found with key {0}")] + KeyNotFound(i32), + #[error("IO Error: {0}")] + IoError(#[from] std::io::Error), + #[error("Parse Error: {0}")] + ParserError(#[from] ParseIntError), +} + +/// IPC bit flags +#[repr(i32)] +pub enum Flags { + /// Create key if key does not exist. + CreateKey = IPC_CREAT, + /// Fail if key exists. + Exclusive = IPC_EXCL, + /// Return error on wait. + NoWait = IPC_NOWAIT, + /// No error if message is too big. + NoError = MSG_NOERROR, + /// Receive any message except of specified type. + Except = MSG_EXCEPT, + /// Copy (not remove) all queue messages. + Copy = MSG_COPY, + /// Private key (Special key value). + Private = IPC_PRIVATE, +} + +/// Commands for `msgctl()` +#[repr(i32)] +pub enum ControlCommands { + /// Remove identifier (Control command for `msgctl`, `semctl`, and `shmctl`). + Remove = IPC_RMID, + /// Set `ipc_perm` options (Control command for `msgctl`, `semctl`, and `shmctl`). + SetPerm = IPC_SET, + /// Get `ipc_perm` options (Control command for `msgctl`, `semctl`, and `shmctl`). + GetPerm = IPC_STAT, + /// See ipcs (Control command for `msgctl`, `semctl`, and `shmctl`). + IpcInfo = IPC_INFO, + /// IPCS control command. + Stat = MSG_STAT, + /// IPCS control command. + MsgInfo = MSG_INFO, +} + +pub struct SysvMq { + pub id: i32, + pub key: i32, + message_mask: i32, + mode: i32, + types: PhantomData, +} + +impl SysvMq { + pub fn create(&mut self, key: i32) -> Result<&Self, SysvMqError> { + self.key = key; + self.id = unsafe { msgget(self.key, Flags::CreateKey as i32 | self.mode) }; + + match self.id { + -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())), + _ => Ok(self), + } + } + + pub fn open(mut self, key: i32) -> Result { + self.key = key; + self.id = unsafe { msgget(self.key, self.mode) }; + + match self.id { + -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())), + _ => Ok(self), + } + } + + pub fn mode(&mut self, mode: i32) -> &Self { + self.mode = mode; + self + } + + pub fn nonblocking(&mut self) -> &Self { + self.message_mask |= Flags::NoWait as i32; + self + } + + pub fn new() -> Self { + SysvMq { + id: -1, + key: 0, + message_mask: 0, + mode: 0o644, + types: PhantomData, + } + } +} + +impl Default for SysvMq { + fn default() -> Self { + Self::new() + } +} From cc19087195e332ff7a30e2d909db6c7062b773d3 Mon Sep 17 00:00:00 2001 From: finga Date: Wed, 7 Jul 2021 20:48:07 +0200 Subject: [PATCH 27/38] Implement deletion of SysV IPC message queues As usual also the readme and the man page are updated. --- README.md | 8 +++++++- mqrs.1 | 35 +++++++++++++++++++++++++++++++++-- src/main.rs | 2 ++ src/sysv.rs | 2 ++ src/sysv/unlink.rs | 35 +++++++++++++++++++++++++++++++++++ sysvmq/src/lib.rs | 27 ++++++++++++++++++++++++--- 6 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 src/sysv/unlink.rs diff --git a/README.md b/README.md index 4f82cfa..e7251f7 100644 --- a/README.md +++ b/README.md @@ -58,10 +58,16 @@ queue. Following optional arguments are supported: - `-o,` `--timeout `: As for example in "5h 23min 42ms" ### SysV IPC message queues -The SysV IPC backend supports one command: `create`. +The SysV IPC backend supports two commands: `create` and `unlink`. #### Create a message queue Use the `create` command to create a new SysV IPC message queue. Following optional arguments are supported: - `-m`, `--mode`: Permissions (octal) to create the queue with. Default: 0644. + +#### Delete a message queue +Use the `unlink` command to delete a message queue. This can either be +done by providing a `key` or an `id` of the queue: +- `-i`, `--id `: Id of the queue +- `-k`, `--key `: Key of the queue diff --git a/mqrs.1 b/mqrs.1 index 0058957..eb7b912 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -192,7 +192,7 @@ Set a different priority than default, priority >= 0 [default: 0] Timeout as for example in "5h 23min 42ms" .RE .SS unlink [FLAGS] \fI\fP -Deletes an existing POSIX message queue. +Delete an existing POSIX message queue. .TP 8 .SS ARGS .RS @@ -211,8 +211,10 @@ Prints help information Produce verbose output .RE .SH SYSV IPC MESSAGE QUEUE SUBCOMMANDS -The SysV IPC backend supports one command: +The SysV IPC backend supports two commands: .B create\ +and +.B unlink\ . .SS create [FLAGS] [OPTIONS] \fI\fP Create a new SysV IPC message queue. @@ -239,6 +241,35 @@ Produce verbose output .B \-m, \-\-mode \fI\fP Permissions (octal) to create the queue with (default: 0644) .RE +.SS unlink [FLAGS] [OPTIONS] +Delete an existing SysV IPC message queue. It is mandatory to pass +exactly one OPTION. +.TP 8 +.SS ARGS +.RS +.TP 8 +.B \fI\fP +Key of the new queue +.RE +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.TP 8 +.SS OPTIONS +.RS +.TP 8 +.B \-i, \-\-id \fI\fP +Id of the queue +.TP 8 +.B \-k, \-\-key \fI\fP +Key of the queue +.RE .SH SEE ALSO mq_overview(7) .SH BUGS diff --git a/src/main.rs b/src/main.rs index 78109dd..5e4db83 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ enum PosixCommand { #[derive(Clap, Debug)] enum SysvCommand { Create(sysv::Create), + Unlink(sysv::Unlink), } #[derive(Clap, Debug)] @@ -68,6 +69,7 @@ fn main() -> Result<()> { }, Backend::Sysv(s) => match s { SysvCommand::Create(c) => c.run()?, + SysvCommand::Unlink(u) => u.run()?, }, } diff --git a/src/sysv.rs b/src/sysv.rs index 5ed245c..91ee1a5 100644 --- a/src/sysv.rs +++ b/src/sysv.rs @@ -1,3 +1,5 @@ mod create; +mod unlink; pub use create::Create; +pub use unlink::Unlink; diff --git a/src/sysv/unlink.rs b/src/sysv/unlink.rs new file mode 100644 index 0000000..277edb6 --- /dev/null +++ b/src/sysv/unlink.rs @@ -0,0 +1,35 @@ +use anyhow::Result; +use clap::Clap; +use log::info; + +/// Delete a message queue +#[derive(Clap, Debug)] +pub struct Unlink { + /// Id of the queue + #[clap( + long, + short, + required_unless_present_any = &["key"], + conflicts_with = "key" + )] + pub id: Option, + /// Key of the queue + #[clap(long, short, required_unless_present_any = &["id"], conflicts_with = "id")] + pub key: Option, +} + +impl Unlink { + pub fn run(&self) -> Result<()> { + if let Some(id) = self.id { + sysvmq::unlink_id(id)?; + + info!("Removed message queue with id: {}", id); + } else if let Some(key) = self.key { + sysvmq::unlink_key(key)?; + + info!("Removed message queue key: {}", key); + } + + Ok(()) + } +} diff --git a/sysvmq/src/lib.rs b/sysvmq/src/lib.rs index 7f7e4e3..bb2c21d 100644 --- a/sysvmq/src/lib.rs +++ b/sysvmq/src/lib.rs @@ -1,9 +1,9 @@ use libc::{ - msgget, IPC_CREAT, IPC_EXCL, IPC_INFO, IPC_NOWAIT, IPC_PRIVATE, IPC_RMID, IPC_SET, IPC_STAT, - MSG_COPY, MSG_EXCEPT, MSG_INFO, MSG_NOERROR, MSG_STAT, + msgctl, msgget, msqid_ds, IPC_CREAT, IPC_EXCL, IPC_INFO, IPC_NOWAIT, IPC_PRIVATE, IPC_RMID, + IPC_SET, IPC_STAT, MSG_COPY, MSG_EXCEPT, MSG_INFO, MSG_NOERROR, MSG_STAT, }; use nix::errno::{errno, Errno}; -use std::{marker::PhantomData, num::ParseIntError}; +use std::{marker::PhantomData, num::ParseIntError, ptr}; use thiserror::Error; #[derive(Debug, Error)] @@ -54,6 +54,27 @@ pub enum ControlCommands { MsgInfo = MSG_INFO, } +pub fn unlink_id(id: i32) -> Result<(), SysvMqError> { + let res = unsafe { + msgctl( + id, + ControlCommands::Remove as i32, + ptr::null::() as *mut msqid_ds, + ) + }; + + match res { + -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())), + _ => Ok(()), + } +} + +pub fn unlink_key(key: i32) -> Result<(), SysvMqError> { + let id = unsafe { msgget(key, 0) }; + + unlink_id(id) +} + pub struct SysvMq { pub id: i32, pub key: i32, From f72608375936814d898360fc7c392e385bc19d40 Mon Sep 17 00:00:00 2001 From: finga Date: Thu, 8 Jul 2021 14:13:59 +0200 Subject: [PATCH 28/38] Remove unneccessary `pub` declarations --- src/posix/info.rs | 2 +- src/posix/recv.rs | 12 ++++++------ src/posix/send.rs | 12 ++++++------ src/sysv/unlink.rs | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/posix/info.rs b/src/posix/info.rs index 0fd1e76..abf9641 100644 --- a/src/posix/info.rs +++ b/src/posix/info.rs @@ -7,7 +7,7 @@ use posixmq::PosixMq; pub struct Info { /// Name of the queue #[clap(value_name = "QUEUE")] - pub queue: String, + queue: String, } impl Info { diff --git a/src/posix/recv.rs b/src/posix/recv.rs index 0b8563a..6d83cef 100644 --- a/src/posix/recv.rs +++ b/src/posix/recv.rs @@ -11,22 +11,22 @@ use std::str; pub struct Recv { /// Do not block #[clap(short, long)] - pub non_blocking: bool, + non_blocking: bool, /// Print messages as they are received #[clap(short, long)] - pub follow: bool, + follow: bool, /// Print a timestamp before each message #[clap(short, long)] - pub timestamp: bool, + timestamp: bool, /// Timeout, example "5h 23min 42ms" #[clap(short = 'o', long, conflicts_with = "deadline")] - pub timeout: Option, + timeout: Option, /// Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") #[clap(short, long, conflicts_with = "timeout")] - pub deadline: Option, + deadline: Option, /// Name of the queue #[clap(value_name = "QUEUE")] - pub queue: String, + queue: String, } fn print_message(priority: u32, length: usize, timestamp: bool, msg: &str) { diff --git a/src/posix/send.rs b/src/posix/send.rs index 917679b..d6feefc 100644 --- a/src/posix/send.rs +++ b/src/posix/send.rs @@ -9,22 +9,22 @@ use log::info; pub struct Send { /// Set a different priority, priority >= 0 #[clap(short, long, default_value = "0")] - pub priority: u32, + priority: u32, /// Do not block #[clap(short, long)] - pub non_blocking: bool, + non_blocking: bool, /// Timeout, example "5h 23min 42ms" #[clap(short = 'o', long, conflicts_with = "deadline")] - pub timeout: Option, + timeout: Option, /// Deadline until messages are sent (format: "%Y-%m-%d %H:%M:%S") #[clap(short, long, conflicts_with = "timeout")] - pub deadline: Option, + deadline: Option, /// Name of the queue #[clap(value_name = "QUEUE")] - pub queue: String, + queue: String, /// Message to be sent to the queue #[clap(value_name = "MESSAGE")] - pub msg: String, + msg: String, } impl Send { diff --git a/src/sysv/unlink.rs b/src/sysv/unlink.rs index 277edb6..ede5b67 100644 --- a/src/sysv/unlink.rs +++ b/src/sysv/unlink.rs @@ -12,10 +12,10 @@ pub struct Unlink { required_unless_present_any = &["key"], conflicts_with = "key" )] - pub id: Option, + id: Option, /// Key of the queue #[clap(long, short, required_unless_present_any = &["id"], conflicts_with = "id")] - pub key: Option, + key: Option, } impl Unlink { From 8d127d840ef29ea718562de16c55c99776be6cde Mon Sep 17 00:00:00 2001 From: finga Date: Thu, 8 Jul 2021 14:14:25 +0200 Subject: [PATCH 29/38] Minor fixes in readme and clap help --- README.md | 7 ++++--- src/posix/list.rs | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e7251f7..12bbbff 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # mqrs -`mqrs` is a small cli application to handle POSIX message queues. +`mqrs` is a small cli application to handle different kinds of message +queues. ## Install `mqrs` For information about how to build, install and run `mqrs` please see @@ -8,8 +9,8 @@ For information about how to build, install and run `mqrs` please see ## Using `mqrs` Depending on which backend you want to use there are different subsets of subcommands. Following backends are supported: -- `posix`: Uses POSIX message queues -- `sysv`: Uses SysV IPC message queues +- `posix`: Use POSIX message queues +- `sysv`: Use SysV IPC message queues If a command is clearly distinguishable from all the others, it does not have to be completed further. diff --git a/src/posix/list.rs b/src/posix/list.rs index 54c031a..f9c02b6 100644 --- a/src/posix/list.rs +++ b/src/posix/list.rs @@ -4,7 +4,7 @@ use clap::Clap; use log::warn; use std::{fs, os::unix::fs::PermissionsExt}; -/// Print information about an existing message queue +/// Print a list of existing message queues #[derive(Clap, Debug)] pub struct List { /// Show all parameters From f4796e7da65ad00053c9b4baacd2fbd40526030c Mon Sep 17 00:00:00 2001 From: finga Date: Thu, 8 Jul 2021 14:20:53 +0200 Subject: [PATCH 30/38] Refactor `sysvmq::unlink_*` and check for error Use `sysvmq::id_from_key(key)` to receive the id of a queue identified with `key`. Here an error check is added as well. Adapt `Sysv::Unlink::run()` to comply with that change. --- src/sysv/unlink.rs | 6 ++++-- sysvmq/src/lib.rs | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sysv/unlink.rs b/src/sysv/unlink.rs index ede5b67..981289b 100644 --- a/src/sysv/unlink.rs +++ b/src/sysv/unlink.rs @@ -25,9 +25,11 @@ impl Unlink { info!("Removed message queue with id: {}", id); } else if let Some(key) = self.key { - sysvmq::unlink_key(key)?; + let id = sysvmq::id_from_key(key)?; - info!("Removed message queue key: {}", key); + sysvmq::unlink_id(id)?; + + info!("Removed message queue key: {} (id: {})", key, id); } Ok(()) diff --git a/sysvmq/src/lib.rs b/sysvmq/src/lib.rs index bb2c21d..b9de136 100644 --- a/sysvmq/src/lib.rs +++ b/sysvmq/src/lib.rs @@ -69,10 +69,13 @@ pub fn unlink_id(id: i32) -> Result<(), SysvMqError> { } } -pub fn unlink_key(key: i32) -> Result<(), SysvMqError> { +pub fn id_from_key(key: i32) -> Result { let id = unsafe { msgget(key, 0) }; - unlink_id(id) + match id { + -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())), + id => Ok(id), + } } pub struct SysvMq { From 4c82d41f8e198a0a9aac83527e2734f384238044 Mon Sep 17 00:00:00 2001 From: finga Date: Thu, 8 Jul 2021 14:46:10 +0200 Subject: [PATCH 31/38] Implement printing a list of SysV IPC mqs What could be improved is when printing the information to use a better human readable format. As usual the readme and the man page are both updated. --- README.md | 4 ++++ mqrs.1 | 12 ++++++++++++ src/main.rs | 2 ++ src/sysv.rs | 2 ++ src/sysv/list.rs | 26 ++++++++++++++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 src/sysv/list.rs diff --git a/README.md b/README.md index 12bbbff..5f68f7c 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,10 @@ queue. Following optional arguments are supported: - `-m`, `--mode`: Permissions (octal) to create the queue with. Default: 0644. +#### List all message queues +Use the `list` command to print a list of all message queues. No +further arguments are supported. + #### Delete a message queue Use the `unlink` command to delete a message queue. This can either be done by providing a `key` or an `id` of the queue: diff --git a/mqrs.1 b/mqrs.1 index eb7b912..af46d24 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -241,6 +241,18 @@ Produce verbose output .B \-m, \-\-mode \fI\fP Permissions (octal) to create the queue with (default: 0644) .RE +.SS list [FLAGS] +Print a list of all existing SysV IPC message queues. +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.RE .SS unlink [FLAGS] [OPTIONS] Delete an existing SysV IPC message queue. It is mandatory to pass exactly one OPTION. diff --git a/src/main.rs b/src/main.rs index 5e4db83..854ae95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ enum PosixCommand { #[derive(Clap, Debug)] enum SysvCommand { Create(sysv::Create), + List(sysv::List), Unlink(sysv::Unlink), } @@ -69,6 +70,7 @@ fn main() -> Result<()> { }, Backend::Sysv(s) => match s { SysvCommand::Create(c) => c.run()?, + SysvCommand::List(l) => l.run()?, SysvCommand::Unlink(u) => u.run()?, }, } diff --git a/src/sysv.rs b/src/sysv.rs index 91ee1a5..05edc1e 100644 --- a/src/sysv.rs +++ b/src/sysv.rs @@ -1,5 +1,7 @@ mod create; +mod list; mod unlink; pub use create::Create; +pub use list::List; pub use unlink::Unlink; diff --git a/src/sysv/list.rs b/src/sysv/list.rs new file mode 100644 index 0000000..f7e6ff7 --- /dev/null +++ b/src/sysv/list.rs @@ -0,0 +1,26 @@ +use anyhow::Result; +use clap::Clap; +use std::{ + fs::File, + io::{BufRead, BufReader}, +}; + +/// Print a list of existing message queues +#[derive(Clap, Debug)] +pub struct List {} + +impl List { + pub fn run(&self) -> Result<()> { + let file = BufReader::new(File::open("/proc/sysvipc/msg")?); + + for line in file.lines() { + for field in line?.split_whitespace().collect::>() { + print!("{0: <10}", field); + } + + println!(); + } + + Ok(()) + } +} From 9666e0788df1be34813787edfeaa284f29080e19 Mon Sep 17 00:00:00 2001 From: finga Date: Thu, 8 Jul 2021 17:44:46 +0200 Subject: [PATCH 32/38] Implement `info` command for SysV IPC mqs The `list` command was refactored a little bit as well and the man page and readme were updated. --- README.md | 6 +++++ mqrs.1 | 58 +++++++++++++++++++++++++++++++++++++--------- src/main.rs | 2 ++ src/sysv.rs | 2 ++ src/sysv/info.rs | 53 ++++++++++++++++++++++++++++++++++++++++++ src/sysv/list.rs | 4 +--- src/sysv/unlink.rs | 4 ++-- 7 files changed, 113 insertions(+), 16 deletions(-) create mode 100644 src/sysv/info.rs diff --git a/README.md b/README.md index 5f68f7c..9e73663 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,12 @@ queue. Following optional arguments are supported: - `-m`, `--mode`: Permissions (octal) to create the queue with. Default: 0644. +#### Print information about a message queue +Use the `info` command to print further information about a message +queue. Exactly of the following arguments is mandatory: +- `-i`, `--id id`: Id of the queue +- `-k`, `--key key`: Key of the queue + #### List all message queues Use the `list` command to print a list of all message queues. No further arguments are supported. diff --git a/mqrs.1 b/mqrs.1 index af46d24..45116a5 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -41,7 +41,7 @@ The POSIX backend supports six commands: and .B recv . -.SS create [FLAGS] [OPTIONS] \fI\fP +.SS posix create [FLAGS] [OPTIONS] \fI\fP Create a new POSIX message queue. .TP 8 .SS ARGS @@ -72,7 +72,7 @@ Message size in bytes .B \-m, \-\-mode \fI\fP Permissions (octal) to create the queue with .RE -.SS help [SUBCOMMAND] +.SS posix help [SUBCOMMAND] Prints this message or the help of the given subcommand. .TP 8 .SS ARGS @@ -81,7 +81,7 @@ Prints this message or the help of the given subcommand. .B \fI\fP Show help for \fISUBCOMMAND\fP .RE -.SS info [FLAGS] \fI\fP +.SS posix info [FLAGS] \fI\fP Print further information about an existing message queue. .TP 8 .SS ARGS @@ -100,7 +100,7 @@ Prints help information .B \-v, \-\-verbose Produce verbose output .RE -.SS list [FLAGS] +.SS posix list [FLAGS] Print a list of all existing POSIX message queues. .TP 8 .SS FLAGS @@ -115,7 +115,7 @@ Produce verbose output .B \-a, \-\-all Print all available information .RE -.SS recv [FLAGS] [OPTIONS] \fI\fP +.SS posix recv [FLAGS] [OPTIONS] \fI\fP Receive and print one or more messages message from a message queue. .TP 8 .SS ARGS @@ -153,7 +153,7 @@ Deadline until messages are received (format: "%Y-%m-%d %H:%M:%S") .B \-o, \-\-timeout \fI\fP Timeout as for example in "5h 23min 42ms" .RE -.SS send [FLAGS] [OPTIONS] \fI\fP \fI\fP +.SS posix send [FLAGS] [OPTIONS] \fI\fP \fI\fP Send a message to a message queue. .TP 8 .SS ARGS @@ -191,7 +191,7 @@ Set a different priority than default, priority >= 0 [default: 0] .B \-o, \-\-timeout \fI\fP Timeout as for example in "5h 23min 42ms" .RE -.SS unlink [FLAGS] \fI\fP +.SS posix unlink [FLAGS] \fI\fP Delete an existing POSIX message queue. .TP 8 .SS ARGS @@ -211,12 +211,16 @@ Prints help information Produce verbose output .RE .SH SYSV IPC MESSAGE QUEUE SUBCOMMANDS -The SysV IPC backend supports two commands: +The SysV IPC backend supports four commands: .B create\ +, +.B info\ +, +.B list and .B unlink\ . -.SS create [FLAGS] [OPTIONS] \fI\fP +.SS sysv create [FLAGS] [OPTIONS] \fI\fP Create a new SysV IPC message queue. .TP 8 .SS ARGS @@ -241,7 +245,39 @@ Produce verbose output .B \-m, \-\-mode \fI\fP Permissions (octal) to create the queue with (default: 0644) .RE -.SS list [FLAGS] +.SS sysv help [SUBCOMMAND] +Prints this message or the help of the given subcommand. +.TP 8 +.SS ARGS +.RS +.TP 8 +.B \fI\fP +Show help for \fISUBCOMMAND\fP +.RE +.SS sysv info [FLAGS] [OPTIONS] +Print further information about an existing message queue. Exactly of +the OPTION arguments is mandatory. +.TP 8 +.SS FLAGS +.RS +.TP 8 +.B \-h, \-\-help +Prints help information +.TP 8 +.B \-v, \-\-verbose +Produce verbose output +.RE +.TP 8 +.SS OPTIONS +.RS +.TP 8 +.B \-i, \-\-id \fI\fP +Id of the queue +.TP 8 +.B \-k, \-\-key \fI\fP +Key of the queue +.RE +.SS sysv list [FLAGS] Print a list of all existing SysV IPC message queues. .TP 8 .SS FLAGS @@ -253,7 +289,7 @@ Prints help information .B \-v, \-\-verbose Produce verbose output .RE -.SS unlink [FLAGS] [OPTIONS] +.SS sysv unlink [FLAGS] [OPTIONS] Delete an existing SysV IPC message queue. It is mandatory to pass exactly one OPTION. .TP 8 diff --git a/src/main.rs b/src/main.rs index 854ae95..b2dc94b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ enum PosixCommand { #[derive(Clap, Debug)] enum SysvCommand { Create(sysv::Create), + Info(sysv::Info), List(sysv::List), Unlink(sysv::Unlink), } @@ -70,6 +71,7 @@ fn main() -> Result<()> { }, Backend::Sysv(s) => match s { SysvCommand::Create(c) => c.run()?, + SysvCommand::Info(i) => i.run()?, SysvCommand::List(l) => l.run()?, SysvCommand::Unlink(u) => u.run()?, }, diff --git a/src/sysv.rs b/src/sysv.rs index 05edc1e..7270e78 100644 --- a/src/sysv.rs +++ b/src/sysv.rs @@ -1,7 +1,9 @@ mod create; +mod info; mod list; mod unlink; pub use create::Create; +pub use info::Info; pub use list::List; pub use unlink::Unlink; diff --git a/src/sysv/info.rs b/src/sysv/info.rs new file mode 100644 index 0000000..42d9fac --- /dev/null +++ b/src/sysv/info.rs @@ -0,0 +1,53 @@ +use anyhow::Result; +use clap::Clap; +use std::{ + fs::File, + io::{BufRead, BufReader}, +}; + +/// Print information about an existing message queue +#[derive(Clap, Debug)] +pub struct Info { + /// Id of the queue + #[clap(short, long, required_unless_present_any = &["key"], conflicts_with = "key")] + id: Option, + /// Key of the queue + #[clap(short, long, required_unless_present_any = &["id"], conflicts_with = "id")] + key: Option, +} + +fn print_line(line: &str) { + for field in line.split_whitespace().collect::>() { + print!("{0: <10}", field); + } + + println!(); +} + +impl Info { + pub fn run(&self) -> Result<()> { + let mut lines = BufReader::new(File::open("/proc/sysvipc/msg")?).lines(); + + print_line(&lines.nth(0).unwrap_or(Ok(String::new()))?); + + for line in lines { + let line = line?; + + if let Some(id) = self.id { + if id == line.split_whitespace().collect::>()[1].parse::()? { + print_line(&line); + + break; + } + } else if let Some(key) = self.key { + if key == line.split_whitespace().collect::>()[0].parse::()? { + print_line(&line); + + break; + } + } + } + + Ok(()) + } +} diff --git a/src/sysv/list.rs b/src/sysv/list.rs index f7e6ff7..9f66951 100644 --- a/src/sysv/list.rs +++ b/src/sysv/list.rs @@ -11,9 +11,7 @@ pub struct List {} impl List { pub fn run(&self) -> Result<()> { - let file = BufReader::new(File::open("/proc/sysvipc/msg")?); - - for line in file.lines() { + for line in BufReader::new(File::open("/proc/sysvipc/msg")?).lines() { for field in line?.split_whitespace().collect::>() { print!("{0: <10}", field); } diff --git a/src/sysv/unlink.rs b/src/sysv/unlink.rs index 981289b..8723d20 100644 --- a/src/sysv/unlink.rs +++ b/src/sysv/unlink.rs @@ -7,14 +7,14 @@ use log::info; pub struct Unlink { /// Id of the queue #[clap( - long, short, + long, required_unless_present_any = &["key"], conflicts_with = "key" )] id: Option, /// Key of the queue - #[clap(long, short, required_unless_present_any = &["id"], conflicts_with = "id")] + #[clap(short, long, required_unless_present_any = &["id"], conflicts_with = "id")] key: Option, } From ecd5ee5a36f9d1b5e0ded62bde3952dff52c157a Mon Sep 17 00:00:00 2001 From: finga Date: Fri, 9 Jul 2021 00:31:51 +0200 Subject: [PATCH 33/38] Add functions to print information about SysV mqs Not needed yet but maybe useful.. --- sysvmq/src/lib.rs | 62 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/sysvmq/src/lib.rs b/sysvmq/src/lib.rs index b9de136..298a48e 100644 --- a/sysvmq/src/lib.rs +++ b/sysvmq/src/lib.rs @@ -1,21 +1,15 @@ use libc::{ - msgctl, msgget, msqid_ds, IPC_CREAT, IPC_EXCL, IPC_INFO, IPC_NOWAIT, IPC_PRIVATE, IPC_RMID, - IPC_SET, IPC_STAT, MSG_COPY, MSG_EXCEPT, MSG_INFO, MSG_NOERROR, MSG_STAT, + msgctl, msgget, msginfo, msqid_ds, IPC_CREAT, IPC_EXCL, IPC_INFO, IPC_NOWAIT, IPC_PRIVATE, + IPC_RMID, IPC_SET, IPC_STAT, MSG_COPY, MSG_EXCEPT, MSG_INFO, MSG_NOERROR, MSG_STAT, }; use nix::errno::{errno, Errno}; -use std::{marker::PhantomData, num::ParseIntError, ptr}; +use std::{marker::PhantomData, mem::MaybeUninit, ptr}; use thiserror::Error; #[derive(Debug, Error)] pub enum SysvMqError { #[error("SysV message queue: {0}")] ErrnoError(&'static str), - #[error("No message queue found with key {0}")] - KeyNotFound(i32), - #[error("IO Error: {0}")] - IoError(#[from] std::io::Error), - #[error("Parse Error: {0}")] - ParserError(#[from] ParseIntError), } /// IPC bit flags @@ -78,6 +72,56 @@ pub fn id_from_key(key: i32) -> Result { } } +pub fn ipc_info(id: i32) -> Result<(), SysvMqError> { + let mut msginfo = MaybeUninit::::uninit(); + + unsafe { + msgctl( + id, + ControlCommands::IpcInfo as i32, + msginfo.as_mut_ptr() as *mut msqid_ds, + ); + } + + let msginfo = unsafe { msginfo.assume_init() }; + + println!("info: {:?}", msginfo); + + Ok(()) +} + +pub fn stat_info(id: i32) -> Result<(), SysvMqError> { + let mut msginfo = MaybeUninit::::uninit(); + + unsafe { + msgctl(id, ControlCommands::Stat as i32, msginfo.as_mut_ptr()); + } + + let msginfo = unsafe { msginfo.assume_init() }; + + println!("info: {:?}", msginfo); + + Ok(()) +} + +pub fn msg_info(id: i32) -> Result<(), SysvMqError> { + let mut msginfo = MaybeUninit::::uninit(); + + unsafe { + msgctl( + id, + ControlCommands::MsgInfo as i32, + msginfo.as_mut_ptr() as *mut msqid_ds, + ); + } + + let msginfo = unsafe { msginfo.assume_init() }; + + println!("info: {:?}", msginfo); + + Ok(()) +} + pub struct SysvMq { pub id: i32, pub key: i32, From 90a3a5eb524b3b98e6e760622d851864b65fbbe9 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 10 Oct 2021 01:17:48 +0200 Subject: [PATCH 34/38] Use mod files To have things more self contained. --- src/{posix.rs => posix/mod.rs} | 0 src/{sysv.rs => sysv/mod.rs} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{posix.rs => posix/mod.rs} (100%) rename src/{sysv.rs => sysv/mod.rs} (100%) diff --git a/src/posix.rs b/src/posix/mod.rs similarity index 100% rename from src/posix.rs rename to src/posix/mod.rs diff --git a/src/sysv.rs b/src/sysv/mod.rs similarity index 100% rename from src/sysv.rs rename to src/sysv/mod.rs From 8150e30ef54dcd20590662cc395f96c82db1c294 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 10 Oct 2021 01:19:00 +0200 Subject: [PATCH 35/38] Update descriptions and manpage Reflect coping with different message queues. --- Cargo.toml | 4 ++-- mqrs.1 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index edbaea8..b69b952 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" repository = "https://git.onders.org/finga/mqrs" license = "GPL-3.0-or-later" readme = "README.md" -description = "A CLI program for interacting with Posix Message Queues." +description = "A CLI program for interacting with different kinds of message queues." keywords = ["message_queue", "mq", "mqueue", "queue"] categories = ["command-line-utilities"] @@ -24,7 +24,7 @@ sysvmq = { path = "sysvmq" } members = ["sysvmq"] [package.metadata.deb] -extended-description = "`mqrs` is a small cli application to handle POSIX message queues." +extended-description = "`mqrs` is a small cli application to handle different kinds of message queues." assets = [ ["target/release/mqrs", "usr/bin/", "755"], ["README.md", "usr/share/doc/cargo-deb/README.md", "644"], diff --git a/mqrs.1 b/mqrs.1 index 45116a5..ce48a87 100644 --- a/mqrs.1 +++ b/mqrs.1 @@ -319,7 +319,7 @@ Id of the queue Key of the queue .RE .SH SEE ALSO -mq_overview(7) +mq_overview(7), sysvipc(7) .SH BUGS No known bugs. .SH AUTHOR From d5ef64171a530bb7e0de96235978da56003eccc9 Mon Sep 17 00:00:00 2001 From: finga Date: Sun, 10 Oct 2021 01:23:17 +0200 Subject: [PATCH 36/38] Cargo update and fix clap changes To support the latest beta version of clap (v3.0.0-beta.4) small changes were necessary. --- Cargo.lock | 61 ++++++++++++++++++++++++++--------------------------- src/main.rs | 4 +++- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c4a517..0485090 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.41" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" +checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" [[package]] name = "atty" @@ -42,9 +42,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "cc" -version = "1.0.68" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd" [[package]] name = "cfg-if" @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.0.0-beta.2" +version = "3.0.0-beta.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" +checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406" dependencies = [ "atty", "bitflags", @@ -80,15 +80,14 @@ dependencies = [ "strsim", "termcolor", "textwrap", - "unicode-width", "vec_map", ] [[package]] name = "clap_derive" -version = "3.0.0-beta.2" +version = "3.0.0-beta.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" +checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac" dependencies = [ "heck", "proc-macro-error", @@ -158,9 +157,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.98" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" [[package]] name = "log" @@ -173,9 +172,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" @@ -202,9 +201,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.21.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3728fec49d363a50a8828a190b379a446cc5cf085c06259bbbeb34447e4ec7" +checksum = "77d9f3521ea8e0641a153b3cddaf008dcbf26acd4ed739a2517295e0760d12c7" dependencies = [ "bitflags", "cc", @@ -234,9 +233,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "2.4.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" +checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d" [[package]] name = "posixmq" @@ -273,18 +272,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] @@ -314,9 +313,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.73" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" +checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" dependencies = [ "proc-macro2", "quote", @@ -343,27 +342,27 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.12.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" dependencies = [ "unicode-width", ] [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -389,9 +388,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" diff --git a/src/main.rs b/src/main.rs index b2dc94b..2e01aa6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,8 +7,10 @@ mod sysv; #[derive(Clap, Debug)] enum Backend { /// Handle POSIX message queues + #[clap(subcommand)] Posix(PosixCommand), /// Handle SysV message queues + #[clap(subcommand)] Sysv(SysvCommand), } @@ -35,7 +37,7 @@ enum SysvCommand { version = crate_version!(), author = crate_authors!(", "), setting = AppSettings::SubcommandRequiredElseHelp, - global_setting = AppSettings::VersionlessSubcommands, + global_setting = AppSettings::PropagateVersion, global_setting = AppSettings::InferSubcommands, )] struct Opts { From 1aab989000168db605cd0f0e23b58475a566bdc2 Mon Sep 17 00:00:00 2001 From: finga Date: Fri, 3 Dec 2021 14:50:23 +0100 Subject: [PATCH 37/38] Update build dependencies and edition Use the 2021 Rust edition. To use current version of clap changes were adapted. --- Cargo.lock | 52 +++++++++++++++++++++++++-------------------- Cargo.toml | 2 +- src/main.rs | 10 ++++----- src/posix/create.rs | 4 ++-- src/posix/info.rs | 4 ++-- src/posix/list.rs | 4 ++-- src/posix/recv.rs | 4 ++-- src/posix/send.rs | 4 ++-- src/posix/unlink.rs | 4 ++-- src/sysv/create.rs | 4 ++-- src/sysv/info.rs | 4 ++-- src/sysv/list.rs | 4 ++-- src/sysv/unlink.rs | 4 ++-- 13 files changed, 55 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0485090..dc36e4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.44" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" +checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" [[package]] name = "atty" @@ -42,9 +42,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "cc" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cfg-if" @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.0.0-beta.4" +version = "3.0.0-beta.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406" +checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63" dependencies = [ "atty", "bitflags", @@ -80,14 +80,14 @@ dependencies = [ "strsim", "termcolor", "textwrap", - "vec_map", + "unicase", ] [[package]] name = "clap_derive" -version = "3.0.0-beta.4" +version = "3.0.0-beta.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac" +checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3" dependencies = [ "heck", "proc-macro-error", @@ -157,9 +157,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.103" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" [[package]] name = "log" @@ -233,9 +233,12 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "3.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d" +checksum = "addaa943333a514159c80c97ff4a93306530d965d27e139188283cd13e06a799" +dependencies = [ + "memchr", +] [[package]] name = "posixmq" @@ -272,9 +275,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" dependencies = [ "unicode-xid", ] @@ -313,9 +316,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.80" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", @@ -380,6 +383,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-segmentation" version = "1.8.0" @@ -398,12 +410,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.3" diff --git a/Cargo.toml b/Cargo.toml index b69b952..f8005b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "mqrs" version = "0.1.1" authors = ["finga "] -edition = "2018" +edition = "2021" repository = "https://git.onders.org/finga/mqrs" license = "GPL-3.0-or-later" readme = "README.md" diff --git a/src/main.rs b/src/main.rs index 2e01aa6..c4b0787 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ use anyhow::Result; -use clap::{crate_authors, crate_version, AppSettings, Clap}; +use clap::{crate_authors, crate_version, AppSettings, Parser}; mod posix; mod sysv; -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] enum Backend { /// Handle POSIX message queues #[clap(subcommand)] @@ -14,7 +14,7 @@ enum Backend { Sysv(SysvCommand), } -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] enum PosixCommand { Create(posix::Create), Info(posix::Info), @@ -24,7 +24,7 @@ enum PosixCommand { Recv(posix::Recv), } -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] enum SysvCommand { Create(sysv::Create), Info(sysv::Info), @@ -32,7 +32,7 @@ enum SysvCommand { Unlink(sysv::Unlink), } -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] #[clap( version = crate_version!(), author = crate_authors!(", "), diff --git a/src/posix/create.rs b/src/posix/create.rs index be4606b..9a09922 100644 --- a/src/posix/create.rs +++ b/src/posix/create.rs @@ -1,11 +1,11 @@ use anyhow::Result; -use clap::Clap; +use clap::Parser; use log::{info, log_enabled, Level::Info}; use posixmq::PosixMq; use std::fs; /// Create a POSIX message queue -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct Create { /// Permissions (octal) to create the queue with #[clap(short, long)] diff --git a/src/posix/info.rs b/src/posix/info.rs index abf9641..7ab01e1 100644 --- a/src/posix/info.rs +++ b/src/posix/info.rs @@ -1,9 +1,9 @@ use anyhow::Result; -use clap::Clap; +use clap::Parser; use posixmq::PosixMq; /// Print information about an existing message queue -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct Info { /// Name of the queue #[clap(value_name = "QUEUE")] diff --git a/src/posix/list.rs b/src/posix/list.rs index f9c02b6..57fa45d 100644 --- a/src/posix/list.rs +++ b/src/posix/list.rs @@ -1,11 +1,11 @@ use anyhow::{anyhow, Result}; use chrono::{DateTime, Local}; -use clap::Clap; +use clap::Parser; use log::warn; use std::{fs, os::unix::fs::PermissionsExt}; /// Print a list of existing message queues -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct List { /// Show all parameters #[clap(short, long)] diff --git a/src/posix/recv.rs b/src/posix/recv.rs index 6d83cef..c3abb66 100644 --- a/src/posix/recv.rs +++ b/src/posix/recv.rs @@ -1,13 +1,13 @@ use anyhow::Result; use chrono::{DateTime, Local}; -use clap::Clap; +use clap::Parser; use humantime::Duration; use log::info; use posixmq::PosixMq; use std::str; /// Receive and print a message from a message queue -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct Recv { /// Do not block #[clap(short, long)] diff --git a/src/posix/send.rs b/src/posix/send.rs index d6feefc..fcfad4f 100644 --- a/src/posix/send.rs +++ b/src/posix/send.rs @@ -1,11 +1,11 @@ use anyhow::Result; use chrono::DateTime; -use clap::Clap; +use clap::Parser; use humantime::Duration; use log::info; /// Send a message to a message queue -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct Send { /// Set a different priority, priority >= 0 #[clap(short, long, default_value = "0")] diff --git a/src/posix/unlink.rs b/src/posix/unlink.rs index 4b89a27..cc21287 100644 --- a/src/posix/unlink.rs +++ b/src/posix/unlink.rs @@ -1,9 +1,9 @@ use anyhow::Result; -use clap::Clap; +use clap::Parser; use log::info; /// Delete a message queue -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct Unlink { /// Name of the queue #[clap(value_name = "QUEUE")] diff --git a/src/sysv/create.rs b/src/sysv/create.rs index e4b03a6..676cdcb 100644 --- a/src/sysv/create.rs +++ b/src/sysv/create.rs @@ -1,10 +1,10 @@ use anyhow::Result; -use clap::Clap; +use clap::Parser; use log::info; use sysvmq::SysvMq; /// Create a SysV message queue -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct Create { /// Permissions (octal) to create the queue with (default: 0644) #[clap(short, long)] diff --git a/src/sysv/info.rs b/src/sysv/info.rs index 42d9fac..9bd0420 100644 --- a/src/sysv/info.rs +++ b/src/sysv/info.rs @@ -1,12 +1,12 @@ use anyhow::Result; -use clap::Clap; +use clap::Parser; use std::{ fs::File, io::{BufRead, BufReader}, }; /// Print information about an existing message queue -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct Info { /// Id of the queue #[clap(short, long, required_unless_present_any = &["key"], conflicts_with = "key")] diff --git a/src/sysv/list.rs b/src/sysv/list.rs index 9f66951..7c12f16 100644 --- a/src/sysv/list.rs +++ b/src/sysv/list.rs @@ -1,12 +1,12 @@ use anyhow::Result; -use clap::Clap; +use clap::Parser; use std::{ fs::File, io::{BufRead, BufReader}, }; /// Print a list of existing message queues -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct List {} impl List { diff --git a/src/sysv/unlink.rs b/src/sysv/unlink.rs index 8723d20..9b4b998 100644 --- a/src/sysv/unlink.rs +++ b/src/sysv/unlink.rs @@ -1,9 +1,9 @@ use anyhow::Result; -use clap::Clap; +use clap::Parser; use log::info; /// Delete a message queue -#[derive(Clap, Debug)] +#[derive(Debug, Parser)] pub struct Unlink { /// Id of the queue #[clap( From 8f93d2d6c8d10d07e91738a62e182bc8dfb5aa75 Mon Sep 17 00:00:00 2001 From: finga Date: Fri, 3 Dec 2021 14:57:38 +0100 Subject: [PATCH 38/38] Fix clippy and remove borrows Fix clippy lints and remove unneded borrows when logging or printing macros. --- src/posix/create.rs | 10 +++++----- src/posix/info.rs | 2 +- src/posix/send.rs | 12 ++++++------ src/posix/unlink.rs | 2 +- src/sysv/create.rs | 2 +- src/sysv/info.rs | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/posix/create.rs b/src/posix/create.rs index 9a09922..cceabde 100644 --- a/src/posix/create.rs +++ b/src/posix/create.rs @@ -40,7 +40,7 @@ impl Create { let mq = &mut posixmq::OpenOptions::readonly(); if let Some(m) = &self.mode { - mq.mode(u32::from_str_radix(&m, 8)?); + mq.mode(u32::from_str_radix(m, 8)?); } mq.max_msg_len(self.msgsize.unwrap_or_else(msgsize_default)) @@ -53,10 +53,10 @@ impl Create { let attributes = mq.attributes()?; info!("Created message queue: {} with attributes msgsize: {}, capacity: {}, current_messages: {}", - &self.queue, - &attributes.max_msg_len, - &attributes.capacity, - &attributes.current_messages); + self.queue, + attributes.max_msg_len, + attributes.capacity, + attributes.current_messages); } Ok(()) diff --git a/src/posix/info.rs b/src/posix/info.rs index 7ab01e1..2a95f6b 100644 --- a/src/posix/info.rs +++ b/src/posix/info.rs @@ -16,7 +16,7 @@ impl Info { println!( "Message queue: {}, msg_max: {}, msgsize_max: {}, current_messages: {}", - &self.queue, &attrs.capacity, &attrs.max_msg_len, &attrs.current_messages + self.queue, attrs.capacity, attrs.max_msg_len, attrs.current_messages ); Ok(()) diff --git a/src/posix/send.rs b/src/posix/send.rs index fcfad4f..6dd70de 100644 --- a/src/posix/send.rs +++ b/src/posix/send.rs @@ -38,24 +38,24 @@ impl Send { if let Some(timeout) = &self.timeout { mq.open(&self.queue)?.send_timeout( self.priority, - &self.msg.as_bytes(), + self.msg.as_bytes(), *timeout.parse::()?, )?; - info!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); + info!("Sent message: \"{}\" to queue: {}", self.msg, self.queue); } else if let Some(deadline) = &self.deadline { mq.open(&self.queue)?.send_deadline( self.priority, - &self.msg.as_bytes(), + self.msg.as_bytes(), DateTime::parse_from_str(deadline, "%Y-%m-%d %H:%M:%S")?.into(), )?; - info!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); + info!("Sent message: \"{}\" to queue: {}", self.msg, self.queue); } else { mq.open(&self.queue)? - .send(self.priority, &self.msg.as_bytes())?; + .send(self.priority, self.msg.as_bytes())?; - info!("Sent message: \"{}\" to queue: {}", &self.msg, &self.queue); + info!("Sent message: \"{}\" to queue: {}", self.msg, self.queue); } Ok(()) diff --git a/src/posix/unlink.rs b/src/posix/unlink.rs index cc21287..75a8bd2 100644 --- a/src/posix/unlink.rs +++ b/src/posix/unlink.rs @@ -14,7 +14,7 @@ impl Unlink { pub fn run(&self) -> Result<()> { posixmq::remove_queue(&self.queue)?; - info!("Removed message queue: {}", &self.queue); + info!("Removed message queue: {}", self.queue); Ok(()) } diff --git a/src/sysv/create.rs b/src/sysv/create.rs index 676cdcb..4adad77 100644 --- a/src/sysv/create.rs +++ b/src/sysv/create.rs @@ -19,7 +19,7 @@ impl Create { let mut mq = SysvMq::::new(); if let Some(m) = &self.mode { - mq.mode(i32::from_str_radix(&m, 8)?); + mq.mode(i32::from_str_radix(m, 8)?); } mq.create(self.key)?; diff --git a/src/sysv/info.rs b/src/sysv/info.rs index 9bd0420..77d4b3e 100644 --- a/src/sysv/info.rs +++ b/src/sysv/info.rs @@ -28,7 +28,7 @@ impl Info { pub fn run(&self) -> Result<()> { let mut lines = BufReader::new(File::open("/proc/sysvipc/msg")?).lines(); - print_line(&lines.nth(0).unwrap_or(Ok(String::new()))?); + print_line(&lines.next().unwrap_or_else(|| Ok(String::new()))?); for line in lines { let line = line?;