1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 12:28:12 +00:00
serenity/Userland/mount.cpp
Sergey Bugaev 4566c2d811 Kernel+LibC: Add support for mount flags
At the moment, the actual flags are ignored, but we correctly propagate them all
the way from the original mount() syscall to each custody that resides on the
mounted FS.
2020-01-11 18:57:53 +01:00

114 lines
3.5 KiB
C++

#include <AK/JsonArray.h>
#include <AK/JsonObject.h>
#include <AK/JsonValue.h>
#include <LibCore/CArgsParser.h>
#include <LibCore/CFile.h>
#include <stdio.h>
#include <unistd.h>
bool mount_all()
{
// Mount all filesystems listed in /etc/fstab.
dbg() << "Mounting all filesystems...";
auto fstab = CFile::construct("/etc/fstab");
if (!fstab->open(CIODevice::OpenMode::ReadOnly)) {
fprintf(stderr, "Failed to open /etc/fstab: %s\n", fstab->error_string());
return false;
}
bool all_ok = true;
while (fstab->can_read_line()) {
ByteBuffer buffer = fstab->read_line(1024);
StringView line_view = (const char*)buffer.data();
// Trim the trailing newline, if any.
if (line_view.length() > 0 && line_view[line_view.length() - 1] == '\n')
line_view = line_view.substring_view(0, line_view.length() - 1);
String line = line_view;
Vector<String> parts = line.split('\t');
if (parts.size() < 3) {
fprintf(stderr, "Invalid fstab entry: %s\n", line.characters());
all_ok = false;
continue;
}
const char* devname = parts[0].characters();
const char* mountpoint = parts[1].characters();
const char* fstype = parts[2].characters();
if (strcmp(mountpoint, "/") == 0) {
dbg() << "Skipping mounting root";
continue;
}
dbg() << "Mounting " << devname << "(" << fstype << ")"
<< " on " << mountpoint;
int rc = mount(devname, mountpoint, fstype, 0);
if (rc != 0) {
fprintf(stderr, "Failed to mount %s (%s) on %s: %s\n", devname, fstype, mountpoint, strerror(errno));
all_ok = false;
continue;
}
}
return all_ok;
}
bool print_mounts()
{
// Output info about currently mounted filesystems.
auto df = CFile::construct("/proc/df");
if (!df->open(CIODevice::ReadOnly)) {
fprintf(stderr, "Failed to open /proc/df: %s\n", df->error_string());
return false;
}
auto content = df->read_all();
auto json = JsonValue::from_string(content).as_array();
json.for_each([](auto& value) {
auto fs_object = value.as_object();
auto class_name = fs_object.get("class_name").to_string();
auto mount_point = fs_object.get("mount_point").to_string();
auto device = fs_object.get("device").as_string_or(class_name);
printf("%s on %s type %s\n", device.characters(), mount_point.characters(), class_name.characters());
});
return true;
}
int main(int argc, char** argv)
{
CArgsParser args_parser("mount");
args_parser.add_arg("devname", "device path");
args_parser.add_arg("mountpoint", "mount point");
args_parser.add_arg("t", "fstype", "file system type");
args_parser.add_arg("a", "mount all systems listed in /etc/fstab");
CArgsParserResult args = args_parser.parse(argc, argv);
if (args.is_present("a")) {
return mount_all() ? 0 : 1;
}
switch (args.get_single_values().size()) {
case 0:
return print_mounts() ? 0 : 1;
case 2: {
String devname = args.get_single_values()[0];
String mountpoint = args.get_single_values()[1];
String fstype = args.is_present("t") ? args.get("t") : "ext2";
if (mount(devname.characters(), mountpoint.characters(), fstype.characters(), 0) < 0) {
perror("mount");
return 1;
}
return 0;
}
default:
args_parser.print_usage();
return 1;
}
}