mirror of
https://review.haiku-os.org/haiku
synced 2025-02-13 00:59:43 +01:00
- The checkfs help text is worded such that it would appear to require both a device name and volume name when it actually requires either one or the other.
146 lines
3.2 KiB
C++
146 lines
3.2 KiB
C++
/*
|
|
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
|
|
#include <getopt.h>
|
|
#include <stdio.h>
|
|
|
|
#include <DiskDevice.h>
|
|
#include <DiskDeviceRoster.h>
|
|
#include <DiskSystem.h>
|
|
|
|
|
|
extern "C" const char* __progname;
|
|
static const char* kProgramName = __progname;
|
|
|
|
|
|
void
|
|
usage(FILE* output)
|
|
{
|
|
fprintf(output,
|
|
"Usage: %s <options> <device|volume name>\n"
|
|
"\n"
|
|
"Options:\n"
|
|
" -h, --help - print this help text\n"
|
|
" -c, --check-only - do not make any changes to the file system\n",
|
|
kProgramName);
|
|
}
|
|
|
|
|
|
int
|
|
main(int argc, char** argv)
|
|
{
|
|
const struct option kLongOptions[] = {
|
|
{ "help", 0, NULL, 'h' },
|
|
{ "check-only", 0, NULL, 'c' },
|
|
{ NULL, 0, NULL, 0 }
|
|
};
|
|
const char* kShortOptions = "hc";
|
|
|
|
// parse argument list
|
|
bool checkOnly = false;
|
|
|
|
while (true) {
|
|
int nextOption = getopt_long(argc, argv, kShortOptions, kLongOptions,
|
|
NULL);
|
|
if (nextOption == -1)
|
|
break;
|
|
|
|
switch (nextOption) {
|
|
case 'h': // --help
|
|
usage(stdout);
|
|
return 0;
|
|
case 'c': // --check-only
|
|
checkOnly = true;
|
|
break;
|
|
default: // everything else
|
|
usage(stderr);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// the device name should be the only non-option element
|
|
if (optind != argc - 1) {
|
|
usage(stderr);
|
|
return 1;
|
|
}
|
|
|
|
const char* path = argv[optind];
|
|
//UnregisterFileDevice unregisterFileDevice;
|
|
|
|
BDiskDeviceRoster roster;
|
|
BPartition* partition;
|
|
BDiskDevice device;
|
|
|
|
status_t status = roster.GetPartitionForPath(path, &device,
|
|
&partition);
|
|
if (status != B_OK) {
|
|
if (strncmp(path, "/dev", 4)) {
|
|
// try mounted volume
|
|
status = roster.FindPartitionByMountPoint(path, &device, &partition)
|
|
? B_OK : B_BAD_VALUE;
|
|
}
|
|
|
|
// TODO: try to register file device
|
|
|
|
if (status != B_OK) {
|
|
fprintf(stderr, "%s: Failed to get disk device for path \"%s\": "
|
|
"%s\n", kProgramName, path, strerror(status));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// Prepare the device for modifications
|
|
|
|
status = device.PrepareModifications();
|
|
if (status != B_OK) {
|
|
fprintf(stderr, "%s: Could not prepare the device for modifications: "
|
|
"%s\n", kProgramName, strerror(status));
|
|
return false;
|
|
}
|
|
|
|
// Check if the partition supports repairing
|
|
|
|
bool canRepairWhileMounted;
|
|
bool canRepair = partition->CanRepair(checkOnly, &canRepairWhileMounted);
|
|
if (!canRepair && !canRepairWhileMounted) {
|
|
fprintf(stderr, "%s: The disk system does not support repairing.\n",
|
|
kProgramName);
|
|
return 1;
|
|
}
|
|
|
|
if (partition->IsMounted() && !canRepairWhileMounted) {
|
|
fprintf(stderr, "%s: The disk system does not support repairing a "
|
|
"mounted volume.\n", kProgramName);
|
|
return 1;
|
|
}
|
|
if (!partition->IsMounted() && !canRepair) {
|
|
fprintf(stderr, "%s: The disk system does not support repairing a "
|
|
"volume that is not mounted.\n", kProgramName);
|
|
return 1;
|
|
}
|
|
|
|
BDiskSystem diskSystem;
|
|
status = partition->GetDiskSystem(&diskSystem);
|
|
if (status != B_OK) {
|
|
fprintf(stderr, "%s: Failed to get disk system for partition: %s\n",
|
|
kProgramName, strerror(status));
|
|
return 1;
|
|
}
|
|
|
|
// Repair the volume
|
|
|
|
status = partition->Repair(checkOnly);
|
|
if (status != B_OK) {
|
|
fprintf(stderr, "%s: Repairing failed: %s\n", kProgramName,
|
|
strerror(status));
|
|
return 1;
|
|
}
|
|
|
|
status = device.CommitModifications();
|
|
|
|
return 0;
|
|
}
|