Serenity Operating System
at master 119 lines 4.8 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/JsonArray.h> 8#include <AK/JsonObject.h> 9#include <AK/NumberFormat.h> 10#include <LibCore/ArgsParser.h> 11#include <LibCore/File.h> 12#include <LibMain/Main.h> 13#include <inttypes.h> 14#include <stdlib.h> 15 16struct FileSystem { 17 DeprecatedString fs; 18 size_t total_block_count { 0 }; 19 size_t free_block_count { 0 }; 20 size_t total_inode_count { 0 }; 21 size_t free_inode_count { 0 }; 22 size_t block_size { 0 }; 23 DeprecatedString mount_point; 24}; 25 26ErrorOr<int> serenity_main(Main::Arguments arguments) 27{ 28 bool flag_human_readable = false; 29 bool flag_human_readable_si = false; 30 bool flag_inode_info = false; 31 32 Core::ArgsParser args_parser; 33 args_parser.set_general_help("Display free disk space of each partition."); 34 args_parser.add_option(flag_human_readable, "Print human-readable sizes", "human-readable", 'h'); 35 args_parser.add_option(flag_human_readable_si, "Print human-readable sizes in SI units", "si", 'H'); 36 args_parser.add_option(flag_inode_info, "Show inode information as well", "inodes", 'i'); 37 args_parser.parse(arguments); 38 39 auto file = TRY(Core::File::open("/sys/kernel/df"sv, Core::File::OpenMode::Read)); 40 41 Vector<StringView> headers; 42 TRY(headers.try_append(flag_human_readable ? "Size"sv : "Blocks"sv)); 43 TRY(headers.try_append("Used"sv)); 44 TRY(headers.try_append("Available"sv)); 45 TRY(headers.try_append("Used%"sv)); 46 if (flag_inode_info) { 47 TRY(headers.try_append("Inodes"sv)); 48 TRY(headers.try_append("IUsed"sv)); 49 TRY(headers.try_append("IAvailable"sv)); 50 TRY(headers.try_append("IUsed%"sv)); 51 } 52 TRY(headers.try_append("Mount point"sv)); 53 54 out("{:12} ", "Filesystem"); 55 56 for (auto& header : headers) 57 out("{:>12} ", header); 58 outln(); 59 60 auto file_contents = TRY(file->read_until_eof()); 61 auto json_result = TRY(JsonValue::from_string(file_contents)); 62 auto const& json = json_result.as_array(); 63 json.for_each([&](auto& value) { 64 auto& fs_object = value.as_object(); 65 auto fs = fs_object.get_deprecated_string("class_name"sv).value_or({}); 66 auto total_block_count = fs_object.get_u64("total_block_count"sv).value_or(0); 67 auto free_block_count = fs_object.get_u64("free_block_count"sv).value_or(0); 68 auto used_block_count = total_block_count - free_block_count; 69 auto total_inode_count = fs_object.get_u64("total_inode_count"sv).value_or(0); 70 auto free_inode_count = fs_object.get_u64("free_inode_count"sv).value_or(0); 71 auto used_inode_count = total_inode_count - free_inode_count; 72 auto block_size = fs_object.get_u64("block_size"sv).value_or(0); 73 auto mount_point = fs_object.get_deprecated_string("mount_point"sv).value_or({}); 74 75 auto used_percentage = 100; 76 if (total_block_count != 0) 77 used_percentage = (used_block_count * 100) / total_block_count; 78 79 auto used_inode_percentage = 100; 80 if (total_inode_count != 0) 81 used_inode_percentage = (used_inode_count * 100) / total_inode_count; 82 83 out("{:12} ", fs); 84 85 bool human_readable = flag_human_readable || flag_human_readable_si; 86 auto human_readable_based_on = flag_human_readable_si ? AK::HumanReadableBasedOn::Base10 : AK::HumanReadableBasedOn::Base2; 87 88 if (human_readable) { 89 out("{:>12} ", human_readable_size(total_block_count * block_size, human_readable_based_on)); 90 out("{:>12} ", human_readable_size(used_block_count * block_size, human_readable_based_on)); 91 out("{:>12} ", human_readable_size(free_block_count * block_size, human_readable_based_on)); 92 out("{:>11}% ", used_percentage); 93 } else { 94 out("{:>12} ", (uint64_t)total_block_count); 95 out("{:>12} ", (uint64_t)used_block_count); 96 out("{:>12} ", (uint64_t)free_block_count); 97 out("{:>11}% ", used_percentage); 98 } 99 100 if (flag_inode_info) { 101 if (human_readable) { 102 out("{:>12} ", human_readable_quantity(total_inode_count, human_readable_based_on)); 103 out("{:>12} ", human_readable_quantity(used_inode_count, human_readable_based_on)); 104 out("{:>12} ", human_readable_quantity(free_inode_count, human_readable_based_on)); 105 out("{:>11}% ", used_inode_percentage); 106 } else { 107 out("{:>12} ", (uint64_t)total_inode_count); 108 out("{:>12} ", (uint64_t)used_inode_count); 109 out("{:>12} ", (uint64_t)free_inode_count); 110 out("{:>11}% ", used_inode_percentage); 111 } 112 } 113 114 out("{}", mount_point); 115 outln(); 116 }); 117 118 return 0; 119}