Added a basic "chkbfs" command to the repository, doesn't fix anything yet,

though (boy, I am so lazy...).
Cleaned up the Jamfile a bit.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2065 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2002-11-22 20:15:12 +00:00
parent d470934c95
commit 2b99433ef9
3 changed files with 234 additions and 15 deletions
+2 -2
View File
@@ -4,8 +4,6 @@ StdBinCommands
alert.cpp
beep.cpp
clipboard.cpp
shutdown.cpp
clipboard.cpp
df.cpp
isvolume.cpp
lsindex.cpp
@@ -13,6 +11,7 @@ StdBinCommands
version.cpp
listattr.cpp
setversion.cpp
shutdown.cpp
: be ;
StdBinCommands
@@ -40,6 +39,7 @@ StdBinCommands
;
#SubInclude OBOS_TOP src apps bin gnu ;
SubInclude OBOS_TOP src apps bin chkbfs ;
SubInclude OBOS_TOP src apps bin listdev ;
SubInclude OBOS_TOP src apps bin mkdos ;
SubInclude OBOS_TOP src apps bin pc ;
+7
View File
@@ -0,0 +1,7 @@
SubDir OBOS_TOP src apps bin chkbfs ;
SubDirHdrs $(OBOS_TOP) src add-ons kernel file_systems bfs ;
StdBinCommands
chkbfs.cpp
;
+212
View File
@@ -0,0 +1,212 @@
#include "bfs_control.h"
#include <fs_info.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
const char *gProgramName;
int gDevice = -1;
static int
openDevice(const char *name)
{
dev_t volume = dev_for_path(name);
if (volume < B_OK) {
fprintf(stderr, "%s: could not open \"%s\": %s\n", gProgramName, name, strerror(volume));
return volume;
}
// check if it's a BFS volume
fs_info info;
if (fs_stat_dev(volume, &info) < B_OK) {
fprintf(stderr, "%s: could not stat device: %s\n", gProgramName, name, errno);
return errno;
}
// ToDo: we can (and should) remove the "obfs" name later
if (strcmp(info.fsh_name, "bfs") && strcmp(info.fsh_name, "obfs")) {
fprintf(stderr, "%s: not a BFS volume\n", gProgramName);
return B_BAD_TYPE;
}
int device = open(name, O_RDONLY);
if (device < 0)
fprintf(stderr, "%s: could not open \"%s\": %s\n", gProgramName, name, strerror(device));
else {
uint32 version;
if (ioctl(device, BFS_IOCTL_VERSION, &version) < B_OK) {
fprintf(stderr, "%s: wrong BFS file system handler\n", gProgramName);
close(device);
return B_BAD_TYPE;
}
if (version < 0x0001000) {
fprintf(stderr, "%s: wrong version of the BFS handler\n", gProgramName);
close(device);
return B_BAD_TYPE;
}
}
return device;
}
static int
startChecking(int device, check_control &control)
{
return ioctl(device, BFS_IOCTL_START_CHECKING, &control, sizeof(check_control));
}
static int
stopChecking(int device, check_control &control)
{
int status = ioctl(device, BFS_IOCTL_STOP_CHECKING, &control, sizeof(check_control));
if (status < B_OK)
printf("%s: error stopping!\n", gProgramName);
return status;
}
static int
checkNext(int device, check_control &control)
{
return ioctl(device, BFS_IOCTL_CHECK_NEXT_NODE, &control, sizeof(check_control));
}
static void
printError(const char *string, int32 &cookie)
{
if (cookie++ != 0)
printf(", ");
printf(string);
}
static void
printUsage()
{
printf("usage: %s <path-to-volume>\n", gProgramName);
}
int
main(int argc, char **argv)
{
struct check_control control;
memset(&control, 0, sizeof(control));
gProgramName = strrchr(argv[0], '/');
if (gProgramName == NULL)
gProgramName = argv[0];
else
gProgramName++;
if (argc < 2 || !strcmp(argv[1], "--help"))
{
printUsage();
return -1;
}
while (*++argv)
{
char *arg = *argv;
if (*arg == '-')
{
while (*++arg && isalpha(*arg))
{
// switch (*arg)
// {
// }
}
}
else
break;
}
int device = openDevice(argv[0]);
if (device < 0)
return -1;
puts("Please enhance me, so that I will fix errors!");
// if (argc > 2) {
// printf("will fix any severe errors!\n");
// control.flags |= BFS_REMOVE_WRONG_TYPES | BFS_REMOVE_INVALID;
// }
// start checking
if (startChecking(device, control) < B_OK) {
close(device);
return -1;
}
// reset all counters
off_t nodes = 0, files = 0, directories = 0, indices = 0;
off_t attributeDirectories = 0, attributes = 0;
// check all files and report errors
while (checkNext(device, control) == B_OK) {
if (++nodes % 50 == 0)
printf(" %7Ld nodes processed\x1b[1A\n", nodes);
if (control.errors) {
int32 cookie = 0;
printf("%s (inode = %Ld): ", control.name, control.inode);
if (control.errors & BFS_MISSING_BLOCKS)
printError("some blocks weren't allocated", cookie);
if (control.errors & BFS_BLOCKS_ALREADY_SET)
printError("has blocks already set", cookie);
if (control.errors & BFS_INVALID_BLOCK_RUN)
printError("has invalid block run(s)", cookie);
if (control.errors & BFS_COULD_NOT_OPEN)
printError("could not be opened", cookie);
if (control.errors & BFS_WRONG_TYPE)
printError("has wrong type", cookie);
if (control.errors & BFS_NAMES_DONT_MATCH)
printError("names don't match", cookie);
putchar('\n');
}
// update counters
if ((control.mode & (S_INDEX_DIR | 0777)) == S_INDEX_DIR)
indices++;
else if (control.mode & S_ATTR_DIR)
attributeDirectories++;
else if (control.mode & S_ATTR)
attributes++;
else if (control.mode & S_IFDIR)
directories++;
else
files++;
}
if (control.status != B_ENTRY_NOT_FOUND)
printf("%s: error occured during scan: %s\n", gProgramName, strerror(control.status));
if (stopChecking(device, control) < B_OK) {
close(device);
return -1;
}
// print stats
printf("checked %ld nodes, %Ld blocks not allocated, %Ld blocks already set, %Ld blocks could be freed\n",
nodes, control.stats.missing, control.stats.already_set, control.stats.freed);
printf("\tfiles\t\t%Ld\n\tdirectories\t%Ld\n\tattributes\t%Ld\n\tattr. dirs\t%Ld\n\tindices\t\t%Ld\n",
files, directories, attributes, attributeDirectories, indices);
if (control.flags & BFS_FIX_BITMAP_ERRORS)
printf("errors have been fixed\n");
close(device);
return 0;
}