@@ -12,11 +12,11 @@ use std::collections::BinaryHeap;
1212use std:: ffi:: OsStr ;
1313use std:: fs;
1414use std:: io;
15+ use std:: os:: unix:: { self , fs:: PermissionsExt } ;
1516use std:: path:: { Path , PathBuf } ;
1617
1718/// An iterator that recursively walks through a directory structure and yields a tuple `(path,
1819/// dirs, files)` for each directory it visits.
19- ///
2020/// This struct is created by [`walk_dir`]. See its documentation for more.
2121pub struct DirWalk {
2222 /// Queued paths that will be visited next.
@@ -117,3 +117,48 @@ pub fn move_file<S: AsRef<Path>, D: AsRef<Path>>(source: S, destination: D) -> c
117117
118118 Ok ( ( ) )
119119}
120+
121+ /// Set file/directory owner and permissions.
122+ #[ cfg( unix) ]
123+ pub fn set_file_permissions < S : AsRef < Path > > (
124+ source : S ,
125+ uid : Option < u32 > ,
126+ gid : Option < u32 > ,
127+ mode : Option < u32 > ,
128+ ) -> crate :: Result < ( ) > {
129+ let path = source. as_ref ( ) ;
130+
131+ unix:: fs:: chown ( path, uid, gid) ?;
132+ match ( uid, gid) {
133+ ( Some ( owner) , Some ( group) ) => {
134+ log:: info!(
135+ "Changed owner/group for {} to {owner}:{group}." ,
136+ path. display( )
137+ ) ;
138+ }
139+ ( Some ( owner) , None ) => {
140+ log:: info!( "Changed owner for {} to {owner}." , path. display( ) ) ;
141+ }
142+ ( None , Some ( group) ) => {
143+ log:: info!( "Changed group for {} to {group}." , path. display( ) ) ;
144+ }
145+ _ => ( ) ,
146+ }
147+
148+ if let Some ( new_mode) = mode {
149+ let metadata = fs:: metadata ( path) ?;
150+ let permissions = metadata. permissions ( ) ;
151+ let old_mode = permissions. mode ( ) ;
152+
153+ if permissions. mode ( ) != new_mode {
154+ let permissions = fs:: Permissions :: from_mode ( new_mode) ;
155+ fs:: set_permissions ( path, permissions) ?; // ← Works on paths (files & directories)
156+ log:: info!(
157+ "Permission for {} changed from {old_mode:o} to {new_mode:o}." ,
158+ path. display( )
159+ ) ;
160+ }
161+ }
162+
163+ Ok ( ( ) )
164+ }
0 commit comments