1 use std::fs::Metadata;
2 #[cfg(unix)]
3 use std::os::unix::fs::MetadataExt;
4 #[cfg(windows)]
5 use std::os::windows::fs::MetadataExt;
6
get_mode(meta: &Metadata) -> String7 pub fn get_mode(meta: &Metadata) -> String {
8 #[cfg(unix)]
9 {
10 format_mode(meta.mode())
11 }
12
13 #[cfg(windows)]
14 {
15 format_mode(meta.file_attributes())
16 }
17 }
18
format_mode(mode: u32) -> String19 pub fn format_mode(mode: u32) -> String {
20 #[cfg(unix)]
21 {
22 get_mode_unix(mode)
23 }
24
25 #[cfg(windows)]
26 {
27 get_mode_windows(mode)
28 }
29 }
30
31 #[cfg(unix)]
get_mode_unix(mode: u32) -> String32 fn get_mode_unix(mode: u32) -> String {
33 let mut s = String::new();
34
35 if mode_is_link(mode) {
36 s.push('l')
37 } else if mode_is_block_device(mode) {
38 s.push('b')
39 } else if mode_is_char_device(mode) {
40 s.push('c')
41 } else if mode_is_socket(mode) {
42 s.push('s')
43 } else if mode_is_pipe(mode) {
44 s.push('p')
45 } else if mode_is_directory(mode) {
46 s.push('d')
47 } else {
48 s.push('-')
49 }
50
51 // user
52
53 if mode_user_read(mode) {
54 s.push('r')
55 } else {
56 s.push('-')
57 }
58
59 if mode_user_write(mode) {
60 s.push('w')
61 } else {
62 s.push('-')
63 }
64
65 if mode_user_exec(mode) {
66 if mode_suid(mode) {
67 s.push('s')
68 } else {
69 s.push('x')
70 }
71 } else {
72 if mode_suid(mode) {
73 s.push('S')
74 } else {
75 s.push('-')
76 }
77 }
78
79 // group
80
81 if mode_group_read(mode) {
82 s.push('r')
83 } else {
84 s.push('-')
85 }
86
87 if mode_group_write(mode) {
88 s.push('w')
89 } else {
90 s.push('-')
91 }
92
93 if mode_group_exec(mode) {
94 if mode_sgid(mode) {
95 s.push('s')
96 } else {
97 s.push('x')
98 }
99 } else {
100 if mode_sgid(mode) {
101 s.push('S')
102 } else {
103 s.push('-')
104 }
105 }
106
107 // other
108
109 if mode_other_read(mode) {
110 s.push('r')
111 } else {
112 s.push('-')
113 }
114
115 if mode_other_write(mode) {
116 s.push('w')
117 } else {
118 s.push('-')
119 }
120
121 if mode_other_exec(mode) {
122 if mode_sticky(mode) {
123 s.push('t')
124 } else {
125 s.push('x')
126 }
127 } else {
128 if mode_sticky(mode) {
129 s.push('T')
130 } else {
131 s.push('-')
132 }
133 }
134
135 s
136 }
137
138 #[allow(unused)]
get_mode_from_boxed_unix_int(meta: &Metadata) -> Option<u32>139 pub fn get_mode_from_boxed_unix_int(meta: &Metadata) -> Option<u32> {
140 #[cfg(unix)]
141 {
142 Some(meta.mode())
143 }
144
145 #[cfg(not(unix))]
146 {
147 None
148 }
149 }
150
user_read(meta: &Metadata) -> bool151 pub fn user_read(meta: &Metadata) -> bool {
152 match get_mode_from_boxed_unix_int(meta) {
153 Some(mode) => mode_user_read(mode),
154 None => false
155 }
156 }
157
mode_user_read(mode: u32) -> bool158 pub fn mode_user_read(mode: u32) -> bool {
159 mode & S_IRUSR == S_IRUSR
160 }
161
user_write(meta: &Metadata) -> bool162 pub fn user_write(meta: &Metadata) -> bool {
163 match get_mode_from_boxed_unix_int(meta) {
164 Some(mode) => mode_user_write(mode),
165 None => false
166 }
167 }
168
mode_user_write(mode: u32) -> bool169 pub fn mode_user_write(mode: u32) -> bool {
170 mode & S_IWUSR == S_IWUSR
171 }
172
user_exec(meta: &Metadata) -> bool173 pub fn user_exec(meta: &Metadata) -> bool {
174 match get_mode_from_boxed_unix_int(meta) {
175 Some(mode) => mode_user_exec(mode),
176 None => false
177 }
178 }
179
mode_user_exec(mode: u32) -> bool180 pub fn mode_user_exec(mode: u32) -> bool {
181 mode & S_IXUSR == S_IXUSR
182 }
183
user_all(meta: &Metadata) -> bool184 pub fn user_all(meta: &Metadata) -> bool {
185 user_read(meta) && user_write(meta) && user_exec(meta)
186 }
187
mode_user_all(mode: u32) -> bool188 pub fn mode_user_all(mode: u32) -> bool {
189 mode_user_read(mode) && mode_user_write(mode) && mode_user_exec(mode)
190 }
191
group_read(meta: &Metadata) -> bool192 pub fn group_read(meta: &Metadata) -> bool {
193 match get_mode_from_boxed_unix_int(meta) {
194 Some(mode) => mode_group_read(mode),
195 None => false
196 }
197 }
198
mode_group_read(mode: u32) -> bool199 pub fn mode_group_read(mode: u32) -> bool {
200 mode & S_IRGRP == S_IRGRP
201 }
202
group_write(meta: &Metadata) -> bool203 pub fn group_write(meta: &Metadata) -> bool {
204 match get_mode_from_boxed_unix_int(meta) {
205 Some(mode) => mode_group_write(mode),
206 None => false
207 }
208 }
209
mode_group_write(mode: u32) -> bool210 pub fn mode_group_write(mode: u32) -> bool {
211 mode & S_IWGRP == S_IWGRP
212 }
213
group_exec(meta: &Metadata) -> bool214 pub fn group_exec(meta: &Metadata) -> bool {
215 match get_mode_from_boxed_unix_int(meta) {
216 Some(mode) => mode_group_exec(mode),
217 None => false
218 }
219 }
220
mode_group_exec(mode: u32) -> bool221 pub fn mode_group_exec(mode: u32) -> bool {
222 mode & S_IXGRP == S_IXGRP
223 }
224
group_all(meta: &Metadata) -> bool225 pub fn group_all(meta: &Metadata) -> bool {
226 group_read(meta) && group_write(meta) && group_exec(meta)
227 }
228
mode_group_all(mode: u32) -> bool229 pub fn mode_group_all(mode: u32) -> bool {
230 mode_group_read(mode) && mode_group_write(mode) && mode_group_exec(mode)
231 }
232
other_read(meta: &Metadata) -> bool233 pub fn other_read(meta: &Metadata) -> bool {
234 match get_mode_from_boxed_unix_int(meta) {
235 Some(mode) => mode_other_read(mode),
236 None => false
237 }
238 }
239
mode_other_read(mode: u32) -> bool240 pub fn mode_other_read(mode: u32) -> bool {
241 mode & S_IROTH == S_IROTH
242 }
243
other_write(meta: &Metadata) -> bool244 pub fn other_write(meta: &Metadata) -> bool {
245 match get_mode_from_boxed_unix_int(meta) {
246 Some(mode) => mode_other_write(mode),
247 None => false
248 }
249 }
250
mode_other_write(mode: u32) -> bool251 pub fn mode_other_write(mode: u32) -> bool {
252 mode & S_IWOTH == S_IWOTH
253 }
254
other_exec(meta: &Metadata) -> bool255 pub fn other_exec(meta: &Metadata) -> bool {
256 match get_mode_from_boxed_unix_int(meta) {
257 Some(mode) => mode_other_exec(mode),
258 None => false
259 }
260 }
261
mode_other_exec(mode: u32) -> bool262 pub fn mode_other_exec(mode: u32) -> bool {
263 mode & S_IXOTH == S_IXOTH
264 }
265
other_all(meta: &Metadata) -> bool266 pub fn other_all(meta: &Metadata) -> bool {
267 other_read(meta) && other_write(meta) && other_exec(meta)
268 }
269
mode_other_all(mode: u32) -> bool270 pub fn mode_other_all(mode: u32) -> bool {
271 mode_other_read(mode) && mode_other_write(mode) && mode_other_exec(mode)
272 }
273
suid_bit_set(meta: &Metadata) -> bool274 pub fn suid_bit_set(meta: &Metadata) -> bool {
275 match get_mode_from_boxed_unix_int(meta) {
276 Some(mode) => mode_suid(mode),
277 None => false
278 }
279 }
280
mode_suid(mode: u32) -> bool281 pub fn mode_suid(mode: u32) -> bool {
282 mode & S_ISUID == S_ISUID
283 }
284
sgid_bit_set(meta: &Metadata) -> bool285 pub fn sgid_bit_set(meta: &Metadata) -> bool {
286 match get_mode_from_boxed_unix_int(meta) {
287 Some(mode) => mode_sgid(mode),
288 None => false
289 }
290 }
291
mode_sgid(mode: u32) -> bool292 pub fn mode_sgid(mode: u32) -> bool {
293 mode & S_ISGID == S_ISGID
294 }
295
296 #[cfg(unix)]
mode_sticky(mode: u32) -> bool297 pub fn mode_sticky(mode: u32) -> bool {
298 mode & S_ISVTX == S_ISVTX
299 }
300
is_pipe(meta: &Metadata) -> bool301 pub fn is_pipe(meta: &Metadata) -> bool {
302 match get_mode_from_boxed_unix_int(meta) {
303 Some(mode) => mode_is_pipe(mode),
304 None => false
305 }
306 }
307
mode_is_pipe(mode: u32) -> bool308 pub fn mode_is_pipe(mode: u32) -> bool {
309 mode & S_IFIFO == S_IFIFO
310 }
311
is_char_device(meta: &Metadata) -> bool312 pub fn is_char_device(meta: &Metadata) -> bool {
313 match get_mode_from_boxed_unix_int(meta) {
314 Some(mode) => mode_is_char_device(mode),
315 None => false
316 }
317 }
318
mode_is_char_device(mode: u32) -> bool319 pub fn mode_is_char_device(mode: u32) -> bool {
320 mode & S_IFCHR == S_IFCHR
321 }
322
is_block_device(meta: &Metadata) -> bool323 pub fn is_block_device(meta: &Metadata) -> bool {
324 match get_mode_from_boxed_unix_int(meta) {
325 Some(mode) => mode_is_block_device(mode),
326 None => false
327 }
328 }
329
mode_is_block_device(mode: u32) -> bool330 pub fn mode_is_block_device(mode: u32) -> bool {
331 mode & S_IFBLK == S_IFBLK
332 }
333
334 #[cfg(unix)]
mode_is_directory(mode: u32) -> bool335 pub fn mode_is_directory(mode: u32) -> bool {
336 mode & S_IFDIR == S_IFDIR
337 }
338
339 #[cfg(unix)]
mode_is_link(mode: u32) -> bool340 pub fn mode_is_link(mode: u32) -> bool {
341 mode & S_IFLNK == S_IFLNK
342 }
343
is_socket(meta: &Metadata) -> bool344 pub fn is_socket(meta: &Metadata) -> bool {
345 match get_mode_from_boxed_unix_int(meta) {
346 Some(mode) => mode_is_socket(mode),
347 None => false
348 }
349 }
350
mode_is_socket(mode: u32) -> bool351 pub fn mode_is_socket(mode: u32) -> bool {
352 mode & S_IFSOCK == S_IFSOCK
353 }
354
355 const S_IRUSR: u32 = 0o400;
356 const S_IWUSR: u32 = 0o200;
357 const S_IXUSR: u32 = 0o100;
358
359 const S_IRGRP: u32 = 0o40;
360 const S_IWGRP: u32 = 0o20;
361 const S_IXGRP: u32 = 0o10;
362
363 const S_IROTH: u32 = 0o4;
364 const S_IWOTH: u32 = 0o2;
365 const S_IXOTH: u32 = 0o1;
366
367 const S_ISUID: u32 = 0o4000;
368 const S_ISGID: u32 = 0o2000;
369 #[cfg(unix)]
370 const S_ISVTX: u32 = 0o1000;
371
372 const S_IFBLK: u32 = 0o60000;
373 #[cfg(unix)]
374 const S_IFDIR: u32 = 0o40000;
375 const S_IFCHR: u32 = 0o20000;
376 const S_IFIFO: u32 = 0o10000;
377 #[cfg(unix)]
378 const S_IFLNK: u32 = 0o120000;
379 const S_IFSOCK: u32 = 0o140000;
380
381 #[cfg(windows)]
get_mode_windows(mode: u32) -> String382 fn get_mode_windows(mode: u32) -> String {
383 const FILE_ATTRIBUTE_ARCHIVE: u32 = 0x20;
384 const FILE_ATTRIBUTE_COMPRESSED: u32 = 0x800;
385 const FILE_ATTRIBUTE_DEVICE: u32 = 0x40;
386 const FILE_ATTRIBUTE_DIRECTORY: u32 = 0x10;
387 const FILE_ATTRIBUTE_ENCRYPTED: u32 = 0x4000;
388 const FILE_ATTRIBUTE_HIDDEN: u32 = 0x2;
389 const FILE_ATTRIBUTE_INTEGRITY_STREAM: u32 = 0x8000;
390 const FILE_ATTRIBUTE_NORMAL: u32 = 0x80;
391 const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED: u32 = 0x2000;
392 const FILE_ATTRIBUTE_NO_SCRUB_DATA: u32 = 0x20000;
393 const FILE_ATTRIBUTE_OFFLINE: u32 = 0x1000;
394 const FILE_ATTRIBUTE_READONLY: u32 = 0x1;
395 const FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS: u32 = 0x400000;
396 const FILE_ATTRIBUTE_RECALL_ON_OPEN: u32 = 0x40000;
397 const FILE_ATTRIBUTE_REPARSE_POINT: u32 = 0x400;
398 const FILE_ATTRIBUTE_SPARSE_FILE: u32 = 0x200;
399 const FILE_ATTRIBUTE_SYSTEM: u32 = 0x4;
400 const FILE_ATTRIBUTE_TEMPORARY: u32 = 0x100;
401 const FILE_ATTRIBUTE_VIRTUAL: u32 = 0x10000;
402
403 let mut v = vec![];
404
405 if mode & FILE_ATTRIBUTE_ARCHIVE == FILE_ATTRIBUTE_ARCHIVE {
406 v.push("Archive");
407 }
408
409 if mode & FILE_ATTRIBUTE_COMPRESSED == FILE_ATTRIBUTE_COMPRESSED {
410 v.push("Compressed");
411 }
412
413 if mode & FILE_ATTRIBUTE_DEVICE == FILE_ATTRIBUTE_DEVICE {
414 v.push("Device");
415 }
416
417 if mode & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY {
418 v.push("Directory");
419 }
420
421 if mode & FILE_ATTRIBUTE_ENCRYPTED == FILE_ATTRIBUTE_ENCRYPTED {
422 v.push("Encrypted");
423 }
424
425 if mode & FILE_ATTRIBUTE_HIDDEN == FILE_ATTRIBUTE_HIDDEN {
426 v.push("Hidden");
427 }
428
429 if mode & FILE_ATTRIBUTE_INTEGRITY_STREAM == FILE_ATTRIBUTE_INTEGRITY_STREAM {
430 v.push("Integrity Stream");
431 }
432
433 if mode & FILE_ATTRIBUTE_NORMAL == FILE_ATTRIBUTE_NORMAL {
434 v.push("Normal");
435 }
436
437 if mode & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED == FILE_ATTRIBUTE_NOT_CONTENT_INDEXED {
438 v.push("Not indexed");
439 }
440
441 if mode & FILE_ATTRIBUTE_NO_SCRUB_DATA == FILE_ATTRIBUTE_NO_SCRUB_DATA {
442 v.push("No scrub data");
443 }
444
445 if mode & FILE_ATTRIBUTE_OFFLINE == FILE_ATTRIBUTE_OFFLINE {
446 v.push("Offline");
447 }
448
449 if mode & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY {
450 v.push("Readonly");
451 }
452
453 if mode & FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS == FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS {
454 v.push("Recall on data access");
455 }
456
457 if mode & FILE_ATTRIBUTE_RECALL_ON_OPEN == FILE_ATTRIBUTE_RECALL_ON_OPEN {
458 v.push("Recall on open");
459 }
460
461 if mode & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT {
462 v.push("Reparse point");
463 }
464
465 if mode & FILE_ATTRIBUTE_SPARSE_FILE == FILE_ATTRIBUTE_SPARSE_FILE {
466 v.push("Sparse");
467 }
468
469 if mode & FILE_ATTRIBUTE_SYSTEM == FILE_ATTRIBUTE_SYSTEM {
470 v.push("System");
471 }
472
473 if mode & FILE_ATTRIBUTE_TEMPORARY == FILE_ATTRIBUTE_TEMPORARY {
474 v.push("Temporary");
475 }
476
477 if mode & FILE_ATTRIBUTE_VIRTUAL == FILE_ATTRIBUTE_VIRTUAL {
478 v.push("Virtual");
479 }
480
481 v.join(", ")
482 }
483
484 #[allow(unused)]
get_uid(meta: &Metadata) -> Option<u32>485 pub fn get_uid(meta: &Metadata) -> Option<u32> {
486 #[cfg(unix)]
487 {
488 Some(meta.uid())
489 }
490
491 #[cfg(not(unix))]
492 {
493 None
494 }
495 }
496
497 #[allow(unused)]
get_gid(meta: &Metadata) -> Option<u32>498 pub fn get_gid(meta: &Metadata) -> Option<u32> {
499 #[cfg(unix)]
500 {
501 Some(meta.gid())
502 }
503
504 #[cfg(not(unix))]
505 {
506 None
507 }
508 }