Nothing to see here, move along
1#![no_std]
2#![no_main]
3
4use lancer_user::fs::{self, MOUNT_INFO_ENTRY_SIZE, MountInfoEntry};
5use lancer_user::net;
6use lancer_user::println;
7use lancer_user::syscall;
8
9fn fs_type_name(t: u8) -> &'static str {
10 match t {
11 0 => "lancerfs",
12 1 => "ramfs",
13 2 => "generic",
14 _ => "unknown",
15 }
16}
17
18fn fmt_u64(val: u64, buf: &mut [u8; 20]) -> &str {
19 match val {
20 0 => "0",
21 _ => {
22 let mut tmp = [0u8; 20];
23 fn fill(v: u64, tmp: &mut [u8; 20], pos: usize) -> usize {
24 match v {
25 0 => pos,
26 _ => {
27 tmp[pos] = b'0' + (v % 10) as u8;
28 fill(v / 10, tmp, pos + 1)
29 }
30 }
31 }
32 let digits = fill(val, &mut tmp, 0);
33 (0..digits).for_each(|j| {
34 buf[j] = tmp[digits - 1 - j];
35 });
36 match core::str::from_utf8(&buf[..digits]) {
37 Ok(s) => s,
38 Err(_) => "?",
39 }
40 }
41 }
42}
43
44#[unsafe(no_mangle)]
45pub extern "C" fn lancer_main() -> ! {
46 let _ = net::init();
47
48 let mut client = unsafe { fs::init() };
49
50 println!("Mount Type Total Used Free Use%");
51
52 let mut buf = [0u8; MOUNT_INFO_ENTRY_SIZE * 16];
53 let count = match client.mount_info(&mut buf) {
54 Ok(c) => c,
55 Err(e) => {
56 println!("df: {}", e.name());
57 syscall::exit();
58 }
59 };
60
61 (0..count).for_each(|i| {
62 let off = i * MOUNT_INFO_ENTRY_SIZE;
63 if let Some(entry) = MountInfoEntry::from_bytes(&buf[off..]) {
64 let prefix = entry.prefix_slice();
65 let mount_str = match prefix.is_empty() {
66 true => "/",
67 false => core::str::from_utf8(prefix).unwrap_or("?"),
68 };
69 let needs_slash = !prefix.is_empty() && prefix[0] != b'/';
70
71 let total = entry.total_blocks;
72 let free = entry.free_blocks;
73 let used = total.saturating_sub(free);
74 let pct = match total {
75 0 => 0u64,
76 t => (used * 100) / t,
77 };
78
79 let mut tb = [0u8; 20];
80 let mut ub = [0u8; 20];
81 let mut fb = [0u8; 20];
82 let mut pb = [0u8; 20];
83
84 let ts = fmt_u64(total, &mut tb);
85 let us = fmt_u64(used, &mut ub);
86 let fs = fmt_u64(free, &mut fb);
87 let ps = fmt_u64(pct, &mut pb);
88
89 let ft = fs_type_name(entry.fs_type);
90
91 match needs_slash {
92 true => println!(
93 "/{:<9} {:<9} {:<8} {:<8} {:<8} {}%",
94 mount_str, ft, ts, us, fs, ps
95 ),
96 false => println!(
97 "{:<10} {:<9} {:<8} {:<8} {:<8} {}%",
98 mount_str, ft, ts, us, fs, ps
99 ),
100 };
101 }
102 });
103
104 syscall::exit()
105}