Hello. This is a new CL file system initialization utility for haiku. It use the new device interface. This is only a first version and I will be happy to improve it with your feedback. Actually It initializes only BFS Volume but as soon as other initialization routines are written I will do the necessary changes. The syntax is quite simple: $ mkfs -t bfs [-v] -o <FsOptions> <DeviceName> <VolumeName> Cheers, Marco
diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 7b0ad68..c4c8889 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -35,7 +35,7 @@ BEOS_BIN = "[" addattr alert arp base64 basename bc beep bootman bzip2 cal cat ideinfo idestatus ifconfig <bin>install installsound iroster isvolume join keymap kill less lessecho lesskey link listarea listattr listdev listimage listport listres listsem ln locate logger login logname ls lsindex m4 make - makebootable md5sum merge mimeset mkdos mkdir mkfifo mkindex modifiers mount + makebootable md5sum merge mimeset mkdos mkdir mkfifo mkfs mkindex modifiers mount mount_nfs mountvolume mv nc netstat nl nohup od open passwd paste patch pathchk pc ping play playfile playsound playwav pr prio printenv printf ps ptx pwd query quit readlink release renice rescan rlog rm rmattr rmindex diff --git a/src/bin/Jamfile b/src/bin/Jamfile index 208ff4e..ccbe218 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -181,6 +181,7 @@ SubInclude HAIKU_TOP src bin make ; SubInclude HAIKU_TOP src bin makebootable ; #SubInclude HAIKU_TOP src bin makeudfimage ; SubInclude HAIKU_TOP src bin mkdos ; +SubInclude HAIKU_TOP src bin mkfs ; SubInclude HAIKU_TOP src bin multiuser ; SubInclude HAIKU_TOP src bin patch ; SubInclude HAIKU_TOP src bin pc ; diff --git a/src/bin/mkfs/FsCreator.cpp b/src/bin/mkfs/FsCreator.cpp new file mode 100644 index 0000000..6115611 --- /dev/null +++ b/src/bin/mkfs/FsCreator.cpp @@ -0,0 +1,130 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marco Minutoli, mminutoli@xxxxxxxxx + */ + +#include "FsCreator.h" + +#include <iostream> + +#include <DiskSystem.h> + + +FsCreator::FsCreator(const char* devPath, BString& type, + BString& volumeName, const char* fsOpt, bool verbose) + :fVolumeName(volumeName),fFsOptions(fsOpt), fVerbose(verbose) +{ + BDiskDeviceRoster roster; + + if (type == "bfs" || type == "Be File System") + fType = "Be File System"; + + status_t ret = roster.GetDeviceForPath(devPath, &fDevice); + if (ret != B_OK) { + std::cerr << "Error: Failed to get disk device for path " + << devPath << ": " << strerror(ret); + } +} + + +bool +FsCreator::Run() +{ + // check that the device is writable + if (fDevice.IsReadOnly()) { + std::cerr << "Error: Can't Inizialize the device." + "It is read only!!\n"; + return false; + } + + // check if the device is mounted + if (fDevice.IsMounted()) { + std::cerr << "Error: The device have to be unmounted before.\n"; + return false; + } + + BDiskSystem diskSystem; + BDiskDeviceRoster dDRoster; + bool found = false; + while (dDRoster.GetNextDiskSystem(&diskSystem) == B_OK) { + if (diskSystem.IsFileSystem() && diskSystem.SupportsInitializing()) { + if (diskSystem.PrettyName() == fType) { + found = true; + break; + } + } + } + + if (!found) { + std::cerr << "Error: Invalid file system type.\n"; + return false; + } + + // prepare the device for modifications + status_t ret = fDevice.PrepareModifications(); + if (ret != B_OK) { + std::cerr << "Error: A problem occurred preparing the device for the" + "modifications\n"; + return false; + } + if (fVerbose) + std::cout << "Preparing for modifications...\n\n"; + + // validate parameters + BString name(fVolumeName); + if (fDevice.ValidateInitialize(fType.String(), + &fVolumeName, fFsOptions) != B_OK) { + std::cerr << "Error: Parameters validation failed. " + "Check what you wrote\n"; + std::cerr << ret; + return false; + } + if (fVerbose) + std::cout << "Parameters Validation...\n\n"; + if (name != fVolumeName) + std::cout << "Volume name was adjusted to " + << fVolumeName.String() << std::endl; + + // Initialize the partition + ret = fDevice.Initialize(fType.String(), fVolumeName.String(), fFsOptions); + if (ret != B_OK) { + std::cerr << "Initialization failed: " << strerror(ret) << std::endl; + return false; + } + + std::cout << "\nAre you sure you want to do this now?" + "\nAll YOUR DATA in this partition will be lost forever\n"; + BString reply=""; + do { + std::cout << "Continue? [yes|no]: "; + reply = _ReadLine(); + } while (reply != "yes" && reply != "no"); + + if (reply == "yes") { + ret = fDevice.CommitModifications(); + if (ret == B_OK) { + if (fVerbose) { + std::cout << "Volume " << fDevice.ContentName() + << " has been initialized successfully!\n"; + } + } else { + std::cout << "Error: Initialization of " << fDevice.ContentName() + << " failed !!\n"; + return false; + } + } + return true; +} + + +inline BString +FsCreator::_ReadLine() { + char line[255]; + + cin.getline(line, sizeof(line), '\n'); + + return line; +} diff --git a/src/bin/mkfs/FsCreator.h b/src/bin/mkfs/FsCreator.h new file mode 100644 index 0000000..f1e281f --- /dev/null +++ b/src/bin/mkfs/FsCreator.h @@ -0,0 +1,33 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marco Minutoli, mminutoli@xxxxxxxxx + */ +#ifndef _FSCREATOR_H_ +#define _FSCREATOR_H_ + +#include <String.h> + +#include <DiskDevice.h> +#include <DiskDeviceRoster.h> + +class FsCreator { +public: + FsCreator(const char* devPath, BString& type, BString& volumeName, + const char* fsOpt, bool verbose); + + bool Run(); +private: + inline BString _ReadLine(); + + BString fType; + BString& fVolumeName; + const char* fFsOptions; + BDiskDevice fDevice; + BPartition* fPartition; + const bool fVerbose; +}; + +#endif // _FSCREATOR_H_ diff --git a/src/bin/mkfs/Jamfile b/src/bin/mkfs/Jamfile new file mode 100644 index 0000000..112c398 --- /dev/null +++ b/src/bin/mkfs/Jamfile @@ -0,0 +1,9 @@ +SubDir HAIKU_TOP src bin mkfs ; + +UsePrivateHeaders shared ; +UsePrivateHeaders storage ; + +BinCommand mkfs : + main.cpp + FsCreator.cpp + : be libstdc++ ; diff --git a/src/bin/mkfs/main.cpp b/src/bin/mkfs/main.cpp new file mode 100644 index 0000000..f0b4c45 --- /dev/null +++ b/src/bin/mkfs/main.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2004-2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marco Minutoli, mminutoli@xxxxxxxxx + */ + +#include <stdio.h> +#include <iostream> +#include <stdlib.h> +#include <String.h> +#include <getopt.h> +#include "FsCreator.h" + +extern "C" const char* __progname; +static const char* kProgramName = __progname; + +static const char* kUsage = +"Usage: %s -t <fs> <options> <device> <volume name>\n" +"\n" +"Options:\n" +" -t, --type <fs> - set type of filesystem to create\n\n" +" -h, --help - print this help text\n" +" -o, --options <opt> - set fs specific options\n" +" -v, --verbose - set verbose output\n" +; + + +/* + * Print program help on the right stream + */ +inline void +print_help(bool out) +{ + fprintf(out ? stdout : stderr, kUsage, kProgramName, kProgramName); +} + + +/* + * Print program help and exit + */ +inline void +print_help_exit(bool out) +{ + print_help(out); + exit(out ? 0 : 1); +} + + +int +main(int argc, char* const* argv) +{ + const struct option longOptions[] = { + { "help", 0, NULL, 'h' }, + { "options", 0, NULL, 'o' }, + { "type", 1, NULL, 't' }, + { "verbose", 0, NULL, 'v' }, + { NULL, 0, NULL, 0 } + }; + const char *shortOptions = "t:o:hv"; + + // parse argument list + int32 nextOption; + BString fsType; + BString fsOptions; + bool verbose = false; + + nextOption = getopt_long(argc, argv, shortOptions, longOptions, NULL); + if (nextOption == 't') + fsType = optarg; + else + print_help_exit(nextOption == 'h' ? true : false); + + do { + nextOption = getopt_long(argc, argv, shortOptions, longOptions, NULL); + + switch (nextOption) { + case 't': // -t or --type again? + print_help_exit(false); + break; + case 'h': // -h or --help + print_help_exit(true); + break; + case 'v': // -v or --verbose + verbose = true; + break; + case 'o': // -o or --options + fsOptions << optarg; + break; + case '?': // invalid option + break; + case -1: // done with options + break; + default: // everything else + print_help(false); + abort(); + } + } while (nextOption != -1); + + // the device name should be the first non-option element + // right before the VolumeName + if (optind != argc - 2) + print_help_exit(false); + const char* devPath = argv[optind]; + BString volName = argv[argc-1]; + + FsCreator* creator = new FsCreator(devPath, fsType, volName, + fsOptions.String(), verbose); + if (creator == NULL) { + std::cerr << "Error: FsCreator can't be allocated\n"; + abort(); + } + + return creator->Run(); +}