@@ -272,42 +272,41 @@ impl Chmoder {
272272 /// Calculate the new mode based on the current mode and the chmod specification.
273273 /// Returns (`new_mode`, `naively_expected_new_mode`) for symbolic modes, or (`new_mode`, `new_mode`) for numeric/reference modes.
274274 fn calculate_new_mode ( & self , current_mode : u32 , is_dir : bool ) -> UResult < ( u32 , u32 ) > {
275- match self . fmode {
276- Some ( mode) => Ok ( ( mode, mode) ) ,
277- None => {
278- let cmode_unwrapped = self . cmode . clone ( ) . unwrap ( ) ;
279- let mut new_mode = current_mode;
280- let mut naively_expected_new_mode = current_mode;
281-
282- for mode in cmode_unwrapped. split ( ',' ) {
283- let result = if mode. chars ( ) . any ( |c| c. is_ascii_digit ( ) ) {
284- mode:: parse_numeric ( new_mode, mode, is_dir) . map ( |v| ( v, v) )
285- } else {
286- mode:: parse_symbolic ( new_mode, mode, mode:: get_umask ( ) , is_dir) . map ( |m| {
287- // calculate the new mode as if umask was 0
288- let naive_mode =
289- mode:: parse_symbolic ( naively_expected_new_mode, mode, 0 , is_dir)
290- . unwrap ( ) ; // we know that mode must be valid, so this cannot fail
291- ( m, naive_mode)
292- } )
293- } ;
294-
295- match result {
296- Ok ( ( mode, naive_mode) ) => {
297- new_mode = mode;
298- naively_expected_new_mode = naive_mode;
299- }
300- Err ( f) => {
301- return if self . quiet {
302- Err ( ExitCode :: new ( 1 ) )
303- } else {
304- Err ( USimpleError :: new ( 1 , f) )
305- } ;
306- }
275+ if let Some ( mode) = self . fmode {
276+ Ok ( ( mode, mode) )
277+ } else {
278+ let cmode_unwrapped = self . cmode . clone ( ) . unwrap ( ) ;
279+ let mut new_mode = current_mode;
280+ let mut naively_expected_new_mode = current_mode;
281+
282+ for mode in cmode_unwrapped. split ( ',' ) {
283+ let result = if mode. chars ( ) . any ( |c| c. is_ascii_digit ( ) ) {
284+ mode:: parse_numeric ( new_mode, mode, is_dir) . map ( |v| ( v, v) )
285+ } else {
286+ mode:: parse_symbolic ( new_mode, mode, mode:: get_umask ( ) , is_dir) . map ( |m| {
287+ // calculate the new mode as if umask was 0
288+ let naive_mode =
289+ mode:: parse_symbolic ( naively_expected_new_mode, mode, 0 , is_dir)
290+ . unwrap ( ) ; // we know that mode must be valid, so this cannot fail
291+ ( m, naive_mode)
292+ } )
293+ } ;
294+
295+ match result {
296+ Ok ( ( mode, naive_mode) ) => {
297+ new_mode = mode;
298+ naively_expected_new_mode = naive_mode;
299+ }
300+ Err ( f) => {
301+ return if self . quiet {
302+ Err ( ExitCode :: new ( 1 ) )
303+ } else {
304+ Err ( USimpleError :: new ( 1 , f) )
305+ } ;
307306 }
308307 }
309- Ok ( ( new_mode, naively_expected_new_mode) )
310308 }
309+ Ok ( ( new_mode, naively_expected_new_mode) )
311310 }
312311 }
313312
@@ -655,32 +654,31 @@ impl Chmoder {
655654 self . calculate_new_mode ( fperm, file. is_dir ( ) ) ?;
656655
657656 // Determine how to apply the permissions
658- match self . fmode {
659- Some ( mode) => self . change_file ( fperm, mode, file) ?,
660- None => {
661- // Special handling for symlinks when not dereferencing
662- if file. is_symlink ( ) && !dereference {
663- // TODO: On most Unix systems, symlink permissions are ignored by the kernel,
664- // so changing them has no effect. We skip this operation for compatibility.
665- // Note that "chmod without dereferencing" effectively does nothing on symlinks.
666- if self . verbose {
667- println ! (
668- "neither symbolic link {} nor referent has been changed" ,
669- file. quote( )
670- ) ;
671- }
672- } else {
673- self . change_file ( fperm, new_mode, file) ?;
674- }
675- // if a permission would have been removed if umask was 0, but it wasn't because umask was not 0, print an error and fail
676- if ( new_mode & !naively_expected_new_mode) != 0 {
677- return Err ( ChmodError :: NewPermissions (
678- file. into ( ) ,
679- display_permissions_unix ( new_mode as mode_t , false ) ,
680- display_permissions_unix ( naively_expected_new_mode as mode_t , false ) ,
681- )
682- . into ( ) ) ;
657+ if let Some ( mode) = self . fmode {
658+ self . change_file ( fperm, mode, file) ?;
659+ } else {
660+ // Special handling for symlinks when not dereferencing
661+ if file. is_symlink ( ) && !dereference {
662+ // TODO: On most Unix systems, symlink permissions are ignored by the kernel,
663+ // so changing them has no effect. We skip this operation for compatibility.
664+ // Note that "chmod without dereferencing" effectively does nothing on symlinks.
665+ if self . verbose {
666+ println ! (
667+ "neither symbolic link {} nor referent has been changed" ,
668+ file. quote( )
669+ ) ;
683670 }
671+ } else {
672+ self . change_file ( fperm, new_mode, file) ?;
673+ }
674+ // if a permission would have been removed if umask was 0, but it wasn't because umask was not 0, print an error and fail
675+ if ( new_mode & !naively_expected_new_mode) != 0 {
676+ return Err ( ChmodError :: NewPermissions (
677+ file. into ( ) ,
678+ display_permissions_unix ( new_mode as mode_t , false ) ,
679+ display_permissions_unix ( naively_expected_new_mode as mode_t , false ) ,
680+ )
681+ . into ( ) ) ;
684682 }
685683 }
686684
0 commit comments