xref: /haiku/src/bin/mkfs/main.cpp (revision b08627f310bb2e80bca50176e7a758182384735a)
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