xref: /haiku/src/bin/mkfs/main.cpp (revision f75a7bf508f3156d63a14f8fd77c5e0ca4d08c42)
1 /*
2  * Copyright 2008 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 		kProgramName);
38 }
39 
40 
41 /*!	Print program help and exit */
42 static void
43 print_help_exit(bool out)
44 {
45 	print_help(out);
46 	exit(out ? 0 : 1);
47 }
48 
49 
50 static void
51 list_types()
52 {
53 	const char* kFormat = "%-10s  %-25s  %s\n";
54 	BDiskDeviceRoster roster;
55 	BDiskSystem diskSystem;
56 
57 	printf("Installed file systems that support initializing:\n\n");
58 	printf(kFormat, "Name", "Pretty Name", "Module");
59 	printf(kFormat, "--", "--", "--");
60 
61 	while (roster.GetNextDiskSystem(&diskSystem) == B_OK) {
62 		if (!diskSystem.SupportsInitializing()
63 			|| !diskSystem.IsFileSystem())
64 			continue;
65 
66 		printf(kFormat, diskSystem.ShortName(), diskSystem.PrettyName(),
67 			diskSystem.Name());
68 	}
69 }
70 
71 
72 int
73 main(int argc, char* const* argv)
74 {
75 	const struct option kLongOptions[] = {
76 		{ "help", 0, NULL, 'h' },
77 		{ "options", 0, NULL, 'o' },
78 		{ "type", 1, NULL, 't' },
79 		{ "list-types", 0, NULL, 'l' },
80 		{ "verbose", 0, NULL, 'v' },
81 		{ "dont-ask", 0, NULL, 'q' },
82 		{ NULL, 0, NULL, 0 }
83 	};
84 	const char* kShortOptions = "t:o:lhvq";
85 
86 	// parse argument list
87 	const char* fsType = "bfs";
88 	const char* fsOptions = NULL;
89 	bool verbose = false;
90 	bool quick = false;
91 
92 	while (true) {
93 		int nextOption = getopt_long(argc, argv, kShortOptions, kLongOptions,
94 			NULL);
95 		if (nextOption == -1)
96 			break;
97 
98 		switch (nextOption) {
99 			case 't':	// -t or --type
100 				fsType = optarg;
101 				break;
102 			case 'h':	// -h or --help
103 				print_help_exit(true);
104 				break;
105 			case 'v':	// -v or --verbose
106 				verbose = true;
107 				break;
108 			case 'o':	// -o or --options
109 				fsOptions = optarg;
110 				break;
111 			case 'q':	// -q or --quick
112 				quick = true;
113 				break;
114 			case 'l':	// list types
115 				list_types();
116 				return 0;
117 			case '?':	// invalid option
118 				break;
119 			case -1:	// done with options
120 				break;
121 			default:	// everything else
122 				print_help(false);
123 				abort();
124 		}
125 	}
126 
127 	// the device name should be the first non-option element
128 	// right before the volume name
129 	if (optind > argc - 1)
130 		print_help_exit(false);
131 
132 	const char* device = argv[optind];
133 	const char* volumeName = NULL;
134 	if (optind == argc - 2)
135 		volumeName = argv[argc - 1];
136 	else {
137 		if (!strncmp(device, "/dev", 4))
138 			volumeName = "Unnamed";
139 		else
140 			volumeName = "Unnamed Image";
141 	}
142 
143 	FsCreator creator(device, fsType, volumeName, fsOptions, quick, verbose);
144 	return creator.Run() ? 0 : 1;
145 }
146