1 /* 2 * Copyright 2008-2017 Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Marco Minutoli, mminutoli@gmail.com 7 * Axel Dörfler, axeld@pinc-software.de 8 */ 9 10 #include <getopt.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 14 #include <DiskSystem.h> 15 16 #include "FsCreator.h" 17 18 19 extern "C" const char* __progname; 20 static const char* kProgramName = __progname; 21 22 23 /*! Print program help on the right stream */ 24 static void 25 print_help(bool out) 26 { 27 fprintf(out ? stdout : stderr, 28 "Usage: %s <options> <device> <volume name>\n" 29 "\n" 30 "Options:\n" 31 " -t, --type <fs> - set type of file system to create\n\n" 32 " -l, --list-types - list file systems that support initializing\n" 33 " -h, --help - print this help text\n" 34 " -o, --options <opt> - set fs specific options\n" 35 " -q, --dont-ask - do not ask before initializing\n" 36 " -v, --verbose - set verbose output\n" 37 "\n" 38 "Example:\n" 39 " mkfs -t bfs -o 'block_size 4096; noindex' ./test.image Data\n" 40 "\tThis will initialize \"test.image\" with BFS with a block\n" 41 "\tsize of 4096 bytes, without index, and named \"Data\".\n", 42 kProgramName); 43 } 44 45 46 /*! Print program help and exit */ 47 static void 48 print_help_exit(bool out) 49 { 50 print_help(out); 51 exit(out ? 0 : 1); 52 } 53 54 55 static void 56 list_types() 57 { 58 const char* kFormat = "%-10s %-25s %s\n"; 59 BDiskDeviceRoster roster; 60 BDiskSystem diskSystem; 61 62 printf("Installed file systems that support initializing:\n\n"); 63 printf(kFormat, "Name", "Pretty Name", "Module"); 64 printf(kFormat, "--", "--", "--"); 65 66 while (roster.GetNextDiskSystem(&diskSystem) == B_OK) { 67 if (!diskSystem.SupportsInitializing() 68 || !diskSystem.IsFileSystem()) 69 continue; 70 71 printf(kFormat, diskSystem.ShortName(), diskSystem.PrettyName(), 72 diskSystem.Name()); 73 } 74 } 75 76 77 int 78 main(int argc, char* const* argv) 79 { 80 const struct option kLongOptions[] = { 81 { "help", 0, NULL, 'h' }, 82 { "options", 0, NULL, 'o' }, 83 { "type", 1, NULL, 't' }, 84 { "list-types", 0, NULL, 'l' }, 85 { "verbose", 0, NULL, 'v' }, 86 { "dont-ask", 0, NULL, 'q' }, 87 { NULL, 0, NULL, 0 } 88 }; 89 const char* kShortOptions = "t:o:lhvq"; 90 91 // parse argument list 92 const char* fsType = "bfs"; 93 const char* fsOptions = NULL; 94 bool verbose = false; 95 bool quick = false; 96 97 while (true) { 98 int nextOption = getopt_long(argc, argv, kShortOptions, kLongOptions, 99 NULL); 100 if (nextOption == -1) 101 break; 102 103 switch (nextOption) { 104 case 't': // -t or --type 105 fsType = optarg; 106 break; 107 case 'h': // -h or --help 108 print_help_exit(true); 109 break; 110 case 'v': // -v or --verbose 111 verbose = true; 112 break; 113 case 'o': // -o or --options 114 fsOptions = optarg; 115 break; 116 case 'q': // -q or --quick 117 quick = true; 118 break; 119 case 'l': // list types 120 list_types(); 121 return 0; 122 case '?': // invalid option 123 break; 124 case -1: // done with options 125 break; 126 default: // everything else 127 print_help(false); 128 abort(); 129 } 130 } 131 132 // the device name should be the first non-option element 133 // right before the volume name 134 if (optind > argc - 1) 135 print_help_exit(false); 136 137 const char* device = argv[optind]; 138 const char* volumeName = NULL; 139 if (optind == argc - 2) 140 volumeName = argv[argc - 1]; 141 else { 142 if (!strncmp(device, "/dev", 4)) 143 volumeName = "Unnamed"; 144 else 145 volumeName = "Unnamed Image"; 146 } 147 148 FsCreator creator(device, fsType, volumeName, fsOptions, quick, verbose); 149 return creator.Run() ? 0 : 1; 150 } 151