From ab3261cac0e6b017e7bd2fd9df8abc311a327f0f Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Wed, 20 Jan 2021 13:33:28 +0100 Subject: sq: Move utility functions to the root. - Move parse_duration, SECONDS_IN_DAY, and SECONDS_IN_YEAR to the root so that they can be more easily reused. --- sq/src/commands/key.rs | 68 ++------------------------------------------------ sq/src/sq.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 66 deletions(-) (limited to 'sq') diff --git a/sq/src/commands/key.rs b/sq/src/commands/key.rs index 7da8d897..b2d7ed3f 100644 --- a/sq/src/commands/key.rs +++ b/sq/src/commands/key.rs @@ -17,13 +17,10 @@ use crate::openpgp::types::KeyFlags; use crate::openpgp::types::SignatureType; use crate::create_or_stdout; +use crate::SECONDS_IN_YEAR; +use crate::parse_duration; use crate::decrypt_key; -const SECONDS_IN_DAY : u64 = 24 * 60 * 60; -const SECONDS_IN_YEAR : u64 = - // Average number of days in a year. - (365.2422222 * SECONDS_IN_DAY as f64) as u64; - pub fn generate(m: &ArgMatches, force: bool) -> Result<()> { let mut builder = CertBuilder::new(); @@ -193,67 +190,6 @@ pub fn generate(m: &ArgMatches, force: bool) -> Result<()> { Ok(()) } -fn parse_duration(expiry: &str) -> Result { - let mut expiry = expiry.chars().peekable(); - - let _ = expiry.by_ref() - .peeking_take_while(|c| c.is_whitespace()) - .for_each(|_| ()); - let digits = expiry.by_ref() - .peeking_take_while(|c| { - *c == '+' || *c == '-' || c.is_digit(10) - }).collect::(); - let _ = expiry.by_ref() - .peeking_take_while(|c| c.is_whitespace()) - .for_each(|_| ()); - let suffix = expiry.next(); - let _ = expiry.by_ref() - .peeking_take_while(|c| c.is_whitespace()) - .for_each(|_| ()); - let junk = expiry.collect::(); - - if digits == "" { - return Err(anyhow::anyhow!( - "--expiry: missing count \ - (try: '2y' for 2 years)")); - } - - let count = match digits.parse::() { - Ok(count) if count < 0 => - return Err(anyhow::anyhow!( - "--expiry: Expiration can't be in the past")), - Ok(count) => count as u64, - Err(err) => - return Err(err).context("--expiry: count is out of range"), - }; - - let factor = match suffix { - Some('y') | Some('Y') => SECONDS_IN_YEAR, - Some('m') | Some('M') => SECONDS_IN_YEAR / 12, - Some('w') | Some('W') => 7 * SECONDS_IN_DAY, - Some('d') | Some('D') => SECONDS_IN_DAY, - None => - return Err(anyhow::anyhow!( - "--expiry: missing suffix \ - (try: '{}y', '{}m', '{}w' or '{}d' instead)", - digits, digits, digits, digits)), - Some(suffix) => - return Err(anyhow::anyhow!( - "--expiry: invalid suffix '{}' \ - (try: '{}y', '{}m', '{}w' or '{}d' instead)", - suffix, digits, digits, digits, digits)), - }; - - if junk != "" { - return Err(anyhow::anyhow!( - "--expiry: contains trailing junk ('{:?}') \ - (try: '{}{}')", - junk, count, factor)); - } - - Ok(Duration::new(count * factor, 0)) -} - pub fn adopt(m: &ArgMatches, p: &dyn Policy) -> Result<()> { let cert = m.value_of("certificate").unwrap(); let cert = Cert::from_file(cert) diff --git a/sq/src/sq.rs b/sq/src/sq.rs index 8f58d176..b9d8e6ef 100644 --- a/sq/src/sq.rs +++ b/sq/src/sq.rs @@ -4,7 +4,9 @@ use anyhow::Context as _; use std::fs::OpenOptions; use std::io::{self, Write}; use std::path::{Path, PathBuf}; +use std::time::Duration; use chrono::{DateTime, offset::Utc}; +use itertools::Itertools; use buffered_reader::File; use sequoia_openpgp as openpgp; @@ -70,6 +72,72 @@ fn create_or_stdout_pgp<'a>(f: Option<&str>, force: bool, Ok(message) } +const SECONDS_IN_DAY : u64 = 24 * 60 * 60; +const SECONDS_IN_YEAR : u64 = + // Average number of days in a year. + (365.2422222 * SECONDS_IN_DAY as f64) as u64; + +fn parse_duration(expiry: &str) -> Result { + let mut expiry = expiry.chars().peekable(); + + let _ = expiry.by_ref() + .peeking_take_while(|c| c.is_whitespace()) + .for_each(|_| ()); + let digits = expiry.by_ref() + .peeking_take_while(|c| { + *c == '+' || *c == '-' || c.is_digit(10) + }).collect::(); + let _ = expiry.by_ref() + .peeking_take_while(|c| c.is_whitespace()) + .for_each(|_| ()); + let suffix = expiry.next(); + let _ = expiry.by_ref() + .peeking_take_while(|c| c.is_whitespace()) + .for_each(|_| ()); + let junk = expiry.collect::(); + + if digits == "" { + return Err(anyhow::anyhow!( + "--expiry: missing count \ + (try: '2y' for 2 years)")); + } + + let count = match digits.parse::() { + Ok(count) if count < 0 => + return Err(anyhow::anyhow!( + "--expiry: Expiration can't be in the past")), + Ok(count) => count as u64, + Err(err) => + return Err(err).context("--expiry: count is out of range"), + }; + + let factor = match suffix { + Some('y') | Some('Y') => SECONDS_IN_YEAR, + Some('m') | Some('M') => SECONDS_IN_YEAR / 12, + Some('w') | Some('W') => 7 * SECONDS_IN_DAY, + Some('d') | Some('D') => SECONDS_IN_DAY, + None => + return Err(anyhow::anyhow!( + "--expiry: missing suffix \ + (try: '{}y', '{}m', '{}w' or '{}d' instead)", + digits, digits, digits, digits)), + Some(suffix) => + return Err(anyhow::anyhow!( + "--expiry: invalid suffix '{}' \ + (try: '{}y', '{}m', '{}w' or '{}d' instead)", + suffix, digits, digits, digits, digits)), + }; + + if junk != "" { + return Err(anyhow::anyhow!( + "--expiry: contains trailing junk ('{:?}') \ + (try: '{}{}')", + junk, count, factor)); + } + + Ok(Duration::new(count * factor, 0)) +} + /// Loads one TSK from every given file. fn load_keys<'a, I>(files: I) -> openpgp::Result> where I: Iterator -- cgit v1.2.3