99
1010#[ cfg( unix) ]
1111extern crate libc;
12- extern crate walker ;
12+ extern crate walkdir ;
1313
1414#[ macro_use]
1515extern crate uucore;
@@ -20,7 +20,7 @@ use std::path::Path;
2020use uucore:: fs:: display_permissions_unix;
2121#[ cfg( not( windows) ) ]
2222use uucore:: mode;
23- use walker :: Walker ;
23+ use walkdir :: WalkDir ;
2424
2525const NAME : & str = "chmod" ;
2626static SUMMARY : & str = "Change the mode of each FILE to MODE.
@@ -150,62 +150,46 @@ impl Chmoder {
150150 for filename in & files {
151151 let filename = & filename[ ..] ;
152152 let file = Path :: new ( filename) ;
153- if file. exists ( ) {
154- if file. is_dir ( ) {
155- if !self . preserve_root || filename != "/" {
156- if self . recursive {
157- let walk_dir = match Walker :: new ( & file) {
158- Ok ( m) => m,
159- Err ( f) => {
160- crash ! ( 1 , "{}" , f. to_string( ) ) ;
161- }
162- } ;
163- // XXX: here (and elsewhere) we see that this impl will have issues
164- // with non-UTF-8 filenames. Using OsString won't fix this because
165- // on Windows OsStrings cannot be built out of non-UTF-8 chars. One
166- // possible fix is to use CStrings rather than Strings in the args
167- // to chmod() and chmod_file().
168- r = self
169- . chmod (
170- walk_dir
171- . filter_map ( |x| match x {
172- Ok ( o) => match o. path ( ) . into_os_string ( ) . to_str ( ) {
173- Some ( s) => Some ( s. to_owned ( ) ) ,
174- None => None ,
175- } ,
176- Err ( _) => None ,
177- } )
178- . collect ( ) ,
179- )
180- . and ( r) ;
181- r = self . chmod_file ( & file, filename) . and ( r) ;
182- }
153+ if !file. exists ( ) {
154+ show_error ! ( "no such file or directory '{}'" , filename) ;
155+ return Err ( 1 ) ;
156+ }
157+ if !self . recursive {
158+ r = self . chmod_file ( & file) . and ( r) ;
159+ } else {
160+ for entry in WalkDir :: new ( & filename) . into_iter ( ) . filter_map ( |e| e. ok ( ) ) {
161+ let file = entry. path ( ) ;
162+ if file. is_file ( ) {
163+ r = self . chmod_file ( & file) . and ( r) ;
183164 } else {
184- show_error ! ( "could not change permissions of directory '{}'" , filename) ;
185- r = Err ( 1 ) ;
165+ if file. is_dir ( ) {
166+ if !self . preserve_root || filename != "/" {
167+ r = self . chmod_file ( & file) . and ( r) ;
168+ } else {
169+ show_error ! ( "could not change permissions of directory '{}'" , filename) ;
170+ r = Err ( 1 ) ;
171+ }
172+ } else {
173+ r = self . chmod_file ( & file) . and ( r) ;
174+ }
186175 }
187- } else {
188- r = self . chmod_file ( & file, filename) . and ( r) ;
189- }
190- } else {
191- show_error ! ( "no such file or directory '{}'" , filename) ;
192- r = Err ( 1 ) ;
193176 }
194177 }
178+ }
195179
196180 r
197181 }
198182
199183 #[ cfg( windows) ]
200- fn chmod_file ( & self , file : & Path , name : & str ) -> Result < ( ) , i32 > {
184+ fn chmod_file ( & self , file : & Path ) -> Result < ( ) , i32 > {
201185 // chmod is useless on Windows
202186 // it doesn't set any permissions at all
203187 // instead it just sets the readonly attribute on the file
204188 Err ( 0 )
205189 }
206190 #[ cfg( any( unix, target_os = "redox" ) ) ]
207- fn chmod_file ( & self , file : & Path , name : & str ) -> Result < ( ) , i32 > {
208- let mut fperm = match fs:: metadata ( name ) {
191+ fn chmod_file ( & self , file : & Path ) -> Result < ( ) , i32 > {
192+ let mut fperm = match fs:: metadata ( file ) {
209193 Ok ( meta) => meta. mode ( ) & 0o7777 ,
210194 Err ( err) => {
211195 if !self . quiet {
@@ -215,7 +199,7 @@ impl Chmoder {
215199 }
216200 } ;
217201 match self . fmode {
218- Some ( mode) => self . change_file ( fperm, mode, file, name ) ?,
202+ Some ( mode) => self . change_file ( fperm, mode, file) ?,
219203 None => {
220204 let cmode_unwrapped = self . cmode . clone ( ) . unwrap ( ) ;
221205 for mode in cmode_unwrapped. split ( ',' ) {
@@ -228,7 +212,7 @@ impl Chmoder {
228212 } ;
229213 match result {
230214 Ok ( mode) => {
231- self . change_file ( fperm, mode, file, name ) ?;
215+ self . change_file ( fperm, mode, file) ?;
232216 fperm = mode;
233217 }
234218 Err ( f) => {
@@ -246,7 +230,7 @@ impl Chmoder {
246230 }
247231
248232 #[ cfg( unix) ]
249- fn change_file ( & self , fperm : u32 , mode : u32 , file : & Path , path : & str ) -> Result < ( ) , i32 > {
233+ fn change_file ( & self , fperm : u32 , mode : u32 , file : & Path ) -> Result < ( ) , i32 > {
250234 if fperm == mode {
251235 if self . verbose && !self . changes {
252236 show_info ! (
@@ -258,7 +242,7 @@ impl Chmoder {
258242 }
259243 Ok ( ( ) )
260244 } else if let Err ( err) =
261- fs:: set_permissions ( Path :: new ( path ) , fs:: Permissions :: from_mode ( mode) )
245+ fs:: set_permissions ( file , fs:: Permissions :: from_mode ( mode) )
262246 {
263247 if !self . quiet {
264248 show_error ! ( "{}" , err) ;
0 commit comments