11use clap:: { ArgGroup , Parser } ;
2- use std:: io:: { self , Read , Write } ;
2+ use std:: io:: { self , BufRead , IsTerminal , Write } ;
33use argon2:: password_hash:: SaltString ;
44
55// Usage: argon2 [-h] salt [-i|-d|-id] [-t iterations] [-m log2(memory in KiB) | -k memory in KiB] [-p parallelism] [-l hash length] [-e|-r] [-v (10|13)]
@@ -54,11 +54,23 @@ struct Args {
5454
5555 /// Argon2 version (defaults to the most recent version, currently 13)
5656 #[ arg( short = 'v' , default_value_t = 13 ) ]
57- v : u32 ,
57+ v : u32 , // Unimplemented: version selection not supported, always uses v13
58+ }
59+
60+ fn get_input ( ) -> io:: Result < String > {
61+ let stdin = io:: stdin ( ) ;
62+
63+ if stdin. is_terminal ( ) {
64+ print ! ( "Enter password: " ) ;
65+ io:: stdout ( ) . flush ( ) ?;
5866
59- /// Print argon2 usage
60- #[ arg( short = 'h' , action = clap:: ArgAction :: Help ) ]
61- help : Option < bool > ,
67+ let mut input = String :: new ( ) ;
68+ stdin. read_line ( & mut input) ?;
69+ Ok ( input. trim ( ) . to_string ( ) )
70+ } else {
71+ let lines: Vec < String > = stdin. lock ( ) . lines ( ) . collect :: < Result < _ , _ > > ( ) ?;
72+ Ok ( lines. join ( "\n " ) )
73+ }
6274}
6375
6476fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
@@ -74,8 +86,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
7486
7587 let args = Args :: parse_from ( new_args) ;
7688
77- let mut password = String :: new ( ) ;
78- io:: stdin ( ) . read_to_string ( & mut password) ?;
89+ let password = get_input ( ) . unwrap_or_else ( |e| {
90+ eprintln ! ( "Error reading input: {}" , e) ;
91+ std:: process:: exit ( 1 ) ;
92+ } ) ;
7993
8094 // Select algorithm variant
8195 let algorithm = if args. d {
0 commit comments