mirror of
https://github.com/NLnetLabs/dnst.git
synced 2026-09-25 11:15:01 +02:00
* Keygen skeleton.
* [keygen] Implement the basic features
* [keygen] synchronize files before exiting
* [keygen] Add help documentation
* [keygen] Generate '.ds' files for KSKs
* [keygen] Use 'display_as_bind()'
* [keygen] Add support for symlinks (Unix only)
* [keygen] Improve errors and support '.ds' symlinks
* Implement ldns-specific parsing for 'keygen'
* [keygen] Implement '-v' with version info
* [keygen] Add 'cfg(unix)' in ldns-parsing
* [keygen] Correctly handle duplicate options in ldns parsing
* Revert "[keygen] Implement '-v' with version info"
This reverts commit 643ab86bd4.
See: <https://github.com/NLnetLabs/dnst/pull/9#discussion_r1843460496>
* [keygen] Integrate the use of 'Env'
* [workflows/ci] Add OpenSSL installation steps
* [workflows/ci] Integrate OpenSSL for 'minimal_versions'
* [keygen] Improve the 'dnst' interface
* [keygen] Satisfy clippy
* [keygen] Simplify symlink CLI
* Add basic filesystem operations to 'Env'
* [keygen] Use symlink ops provided by 'Env'
* [keygen] Add basic tests for argument parsing
* [keygen] Add tests
* [keygen] Satisfy 'minimal-versions'
* [keygen] Satisfy clippy
* [keygen] Add Windows-specific missing branch
* [keygen] Document parsing for 'symlink'
* [keygen] Report error on '-r'
* [env] Refactor util fns into a 'util' module
* [keygen::symlink] Mark params as used, for Windows
* [keygen] Fix double error message
See: <https://github.com/NLnetLabs/dnst/pull/9#discussion_r1862213985>
* [keygen] Use 'Args::Report'
* [keygen] Allow invalid HTML in docs for Clap
* Use 'domain'-style imports
* [keygen] Use uppercase for expected clap values
* [keygen] use lowercase value names in Clap
---------
Co-authored-by: arya dradjica <arya@nlnetlabs.nl>
94 lines
2.6 KiB
Rust
94 lines
2.6 KiB
Rust
use std::ffi::OsString;
|
|
use std::path::Path;
|
|
|
|
use clap::Parser;
|
|
use commands::{key2ds::Key2ds, keygen::Keygen, nsec3hash::Nsec3Hash, LdnsCommand};
|
|
use env::Env;
|
|
use error::Error;
|
|
|
|
pub use self::args::Args;
|
|
|
|
pub mod args;
|
|
pub mod commands;
|
|
pub mod env;
|
|
pub mod error;
|
|
pub mod parse;
|
|
pub mod util;
|
|
|
|
pub fn try_ldns_compatibility<I: IntoIterator<Item = OsString>>(
|
|
args: I,
|
|
) -> Result<Option<Args>, Error> {
|
|
let mut args_iter = args.into_iter();
|
|
let binary_path = args_iter.next().ok_or("Missing binary name")?;
|
|
|
|
let binary_name = extract_binary_name(Path::new(&binary_path))?;
|
|
|
|
// We only branch on the binary name for the ldns utilities. The rest we
|
|
// just handle as regular dnst.
|
|
let Some(binary_name) = binary_name.strip_prefix("ldns-") else {
|
|
return Ok(None);
|
|
};
|
|
|
|
let res = match binary_name {
|
|
"key2ds" => Key2ds::parse_ldns_args(args_iter),
|
|
"keygen" => Keygen::parse_ldns_args(args_iter),
|
|
"nsec3-hash" => Nsec3Hash::parse_ldns_args(args_iter),
|
|
_ => return Err(format!("Unrecognized ldns command 'ldns-{binary_name}'").into()),
|
|
};
|
|
|
|
Ok(Some(res?))
|
|
}
|
|
|
|
/// Get the binary name from a [`Path`].
|
|
///
|
|
/// The binary name is the file name without any extensions. It is similar
|
|
/// to the unstable `Path::file_stem`.
|
|
///
|
|
/// ```rust
|
|
/// use dnst::extract_binary_name;
|
|
/// use std::path::Path;
|
|
///
|
|
/// let bin = extract_binary_name(Path::new("foo/ldns-xxx")).unwrap();
|
|
/// assert_eq!(bin, "ldns-xxx");
|
|
///
|
|
/// let bin = extract_binary_name(Path::new("foo/ldns-xxx.real")).unwrap();
|
|
/// assert_eq!(bin, "ldns-xxx");
|
|
///
|
|
/// let bin = extract_binary_name(Path::new("./ldns-xxx.exe")).unwrap();
|
|
/// assert_eq!(bin, "ldns-xxx");
|
|
///
|
|
/// let bin = extract_binary_name(Path::new("ldns-xxx")).unwrap();
|
|
/// assert_eq!(bin, "ldns-xxx");
|
|
/// ```
|
|
pub fn extract_binary_name(path: &Path) -> Result<&str, Error> {
|
|
let filename = path
|
|
.file_name()
|
|
.ok_or("Missing binary file name")?
|
|
.to_str()
|
|
.ok_or("Binary file name is not valid unicode")?;
|
|
|
|
match filename.split_once('.') {
|
|
Some((binary, _)) => Ok(binary),
|
|
None => Ok(filename),
|
|
}
|
|
}
|
|
|
|
fn parse_args(env: impl Env) -> Result<Args, Error> {
|
|
if let Some(args) = try_ldns_compatibility(env.args_os())? {
|
|
return Ok(args);
|
|
}
|
|
let args = Args::try_parse_from(env.args_os())?;
|
|
Ok(args)
|
|
}
|
|
|
|
pub fn run(env: impl Env) -> u8 {
|
|
let res = parse_args(&env).and_then(|args| args.execute(&env));
|
|
match res {
|
|
Ok(()) => 0,
|
|
Err(err) => {
|
|
err.pretty_print(&env);
|
|
err.exit_code()
|
|
}
|
|
}
|
|
}
|