@@ -15,45 +15,41 @@ use base64::prelude::*;
1515use clap:: Parser ;
1616use gettextrs:: { bind_textdomain_codeset, textdomain} ;
1717use plib:: PROJECT_NAME ;
18- use std:: fs:: { self , OpenOptions } ;
18+ use std:: fs:: OpenOptions ;
1919use std:: io:: { self , Error , ErrorKind , Read , Write } ;
20+ use std:: path:: PathBuf ;
2021
2122/// uudecode - decode a binary file
2223#[ derive( Parser , Debug ) ]
2324#[ command( author, version, about, long_about) ]
2425struct Args {
2526 /// A pathname of a file that shall be used instead of any pathname contained in the input data.
2627 #[ arg( short, long) ]
27- outfile : Option < String > ,
28+ outfile : Option < PathBuf > ,
2829
29- /// The pathname of a file containing the output of uuencode .
30- file : Option < String > ,
30+ /// The pathname of a file containing uuencoded data .
31+ file : Option < PathBuf > ,
3132}
3233
33- fn write_file ( filename : & str , bindata : & [ u8 ] ) -> io:: Result < ( ) > {
34+ fn write_file ( pathname : & PathBuf , bindata : & [ u8 ] ) -> io:: Result < ( ) > {
3435 let f_res = OpenOptions :: new ( )
3536 . read ( false )
3637 . write ( true )
3738 . create ( true )
3839 . truncate ( true )
39- . open ( filename ) ;
40+ . open ( pathname ) ;
4041
4142 match f_res {
4243 Err ( e) => {
43- eprintln ! ( "{}: {}" , filename , e) ;
44+ eprintln ! ( "{}: {}" , pathname . display ( ) , e) ;
4445 return Err ( e) ;
4546 }
4647 Ok ( mut file) => file. write_all ( bindata) ,
4748 }
4849}
4950
5051fn decode_file ( args : & Args ) -> io:: Result < ( ) > {
51- let mut file: Box < dyn Read > ;
52- if let Some ( filename) = & args. file {
53- file = Box :: new ( fs:: File :: open ( filename) ?) ;
54- } else {
55- file = Box :: new ( io:: stdin ( ) . lock ( ) ) ;
56- }
52+ let mut file = plib:: io:: input_stream_opt ( & args. file ) ?;
5753
5854 // read entire file into memory.
5955 // ugly but necessary due to uudecode crate implementation.
@@ -68,7 +64,7 @@ fn decode_file(args: &Args) -> io::Result<()> {
6864
6965 // decode succeeded. exit here.
7066 Ok ( bindata) => match & args. outfile {
71- None => return write_file ( "bindata.out" , & bindata[ ..] ) ,
67+ None => return write_file ( & PathBuf :: from ( "bindata.out" ) , & bindata[ ..] ) ,
7268 Some ( outfn) => return write_file ( outfn, & bindata[ ..] ) ,
7369 } ,
7470 }
@@ -77,12 +73,19 @@ fn decode_file(args: &Args) -> io::Result<()> {
7773 match uuencode:: uudecode ( & buffer) {
7874 None => return Err ( Error :: new ( ErrorKind :: Other , "invalid input data" ) ) ,
7975 Some ( ( bindata, filename) ) => match & args. outfile {
80- None => write_file ( & filename, & bindata[ ..] ) ,
76+ None => write_file ( & PathBuf :: from ( filename) , & bindata[ ..] ) ,
8177 Some ( outfn) => write_file ( outfn, & bindata[ ..] ) ,
8278 } ,
8379 }
8480}
8581
82+ fn pathname_display ( path : & Option < PathBuf > ) -> String {
83+ match path {
84+ None => "stdin" . to_string ( ) ,
85+ Some ( p) => p. display ( ) . to_string ( ) ,
86+ }
87+ }
88+
8689fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
8790 // parse command line arguments
8891 let args = Args :: parse ( ) ;
@@ -94,7 +97,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
9497
9598 if let Err ( e) = decode_file ( & args) {
9699 exit_code = 1 ;
97- eprintln ! ( "{:?}: {}" , args. file, e) ;
100+ eprintln ! ( "{:?}: {}" , pathname_display ( & args. file) , e) ;
98101 }
99102
100103 std:: process:: exit ( exit_code)
0 commit comments