[haiku-development] Re: mkfs utility for haiku

Hello,

I'm sorry but in the last 5 days I had no internet connection (damn
ISPs!) so I couldn't send you the mkfs patch using ShortName().

Here it is. I have tested it and it's working.

Looking forward to reading your feedbacks.

Cheers,
Marco
diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage
index 023de2d..2eaab9c 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 d2e1447..15bedcb 100644
--- a/src/bin/Jamfile
+++ b/src/bin/Jamfile
@@ -185,6 +185,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..7962f53
--- /dev/null
+++ b/src/bin/mkfs/FsCreator.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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)
+       :
+       fType(type),
+       fDevicePath(devPath),
+       fVolumeName(volumeName),
+       fFsOptions(fsOpt),
+       fVerbose(verbose)
+{
+       BDiskDeviceRoster roster;
+       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.ShortName() == fType) {
+                               found = true;
+                               break;
+                       }
+               }
+       }
+
+       if (!found) {
+               std::cerr << "Error: "
+                                 << fType.String() << " is an 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(diskSystem.PrettyName(),
+                       &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(diskSystem.PrettyName(),
+               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?\n"
+                         << "\nALL YOUR DATA in " << fDevicePath.String()
+                         << " will be lost forever\n";
+
+       BString reply;
+       do {
+               std::cout << "Continue? [yes|no]: ";
+               reply = _ReadLine();
+               if (reply == "")
+                       reply = "no"; // silence is dissence
+       } 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..b052410
--- /dev/null
+++ b/src/bin/mkfs/FsCreator.h
@@ -0,0 +1,34 @@
+/*
+ * 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 fDevicePath;
+       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..2016e80
--- /dev/null
+++ b/src/bin/mkfs/main.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright 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();
+}

Other related posts: