xref: /netbsd-src/sbin/gpt/main.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1 /*	$NetBSD: main.c,v 1.8 2017/02/12 16:54:06 aymeric Exp $	*/
2 
3 /*-
4  * Copyright (c) 2002 Marcel Moolenaar
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * CRC32 code derived from work by Gary S. Brown.
29  */
30 
31 #if HAVE_NBTOOL_CONFIG_H
32 #include "nbtool_config.h"
33 #endif
34 
35 #include <sys/cdefs.h>
36 #ifdef __RCSID
37 __RCSID("$NetBSD: main.c,v 1.8 2017/02/12 16:54:06 aymeric Exp $");
38 #endif
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <err.h>
44 
45 #include "map.h"
46 #include "gpt.h"
47 
48 static const struct gpt_cmd c_null;
49 
50 extern const struct gpt_cmd
51 	c_add,
52 #ifndef HAVE_NBTOOL_CONFIG_H
53 	c_backup,
54 #endif
55 	c_biosboot,
56 	c_create,
57 	c_destroy,
58 	c_header,
59 	c_label,
60 	c_migrate,
61 	c_recover,
62 	c_remove,
63 	c_resize,
64 	c_resizedisk,
65 #ifndef HAVE_NBTOOL_CONFIG_H
66 	c_restore,
67 #endif
68 	c_set,
69 	c_show,
70 	c_type,
71 	c_unset;
72 
73 static const struct gpt_cmd *cmdsw[] = {
74 	&c_add,
75 #ifndef HAVE_NBTOOL_CONFIG_H
76 	&c_backup,
77 #endif
78 	&c_biosboot,
79 	&c_create,
80 	&c_destroy,
81 	&c_header,
82 	&c_label,
83 	&c_migrate,
84 	&c_recover,
85 	&c_remove,
86 	&c_resize,
87 	&c_resizedisk,
88 #ifndef HAVE_NBTOOL_CONFIG_H
89 	&c_restore,
90 #endif
91 	&c_set,
92 	&c_show,
93 	&c_type,
94 	&c_unset,
95 	&c_null,
96 };
97 
98 __dead static void
99 usage(void)
100 {
101 	const char *p = getprogname();
102 	const char *f =
103 	    "[-nrqv] [-m mediasize] [-s sectorsize]";
104 	size_t i;
105 
106 	if (strcmp(p, "gpt") == 0)
107 		fprintf(stderr,
108 		    "Usage: %s %s command device\n", p, f);
109 	else
110 		fprintf(stderr,
111 		    "Usage: %s %s device command\n", p, f);
112 	fprintf(stderr, "Commands:\n");
113 	for (i = 0; i < __arraycount(cmdsw); i++)
114 		gpt_usage("\t", cmdsw[i]);
115 	exit(EXIT_FAILURE);
116 }
117 
118 static void
119 prefix(const char *cmd)
120 {
121 	char *pfx;
122 
123 	if (asprintf(&pfx, "%s %s", getprogname(), cmd) < 0)
124 		pfx = NULL;
125 	else
126 		setprogname(pfx);
127 }
128 
129 int
130 main(int argc, char *argv[])
131 {
132 	char *cmd, *p, *dev = NULL;
133 	int ch, i;
134 	u_int secsz = 0;
135 	off_t mediasz = 0;
136 	int flags = 0;
137 	int verbose = 0;
138 	gpt_t gpt;
139 
140 	setprogname(argv[0]);
141 
142 	if (strcmp(getprogname(), "gpt") == 0) {
143 		if (argc < 3)
144 			usage();
145 		dev = argv[--argc];
146 	}
147 
148 #ifdef __GLIBC__
149 #define GETOPT_BE_POSIX		"+"
150 #else
151 #define GETOPT_BE_POSIX		""
152 #endif
153 
154 	/* Get the generic options */
155 	while ((ch = getopt(argc, argv, GETOPT_BE_POSIX "m:nqrs:v")) != -1) {
156 		switch(ch) {
157 		case 'm':
158 			if (mediasz > 0)
159 				usage();
160 			mediasz = strtol(optarg, &p, 10);
161 			if (*p != 0 || mediasz < 1)
162 				usage();
163 			break;
164 		case 'n':
165 			flags |= GPT_NOSYNC;
166 			break;
167 		case 'r':
168 			flags |= GPT_READONLY;
169 			break;
170 		case 'q':
171 			flags |= GPT_QUIET;
172 			break;
173 		case 's':
174 			if (gpt_uint_get(NULL, &secsz) == -1)
175 				usage();
176 			break;
177 		case 'v':
178 			verbose++;
179 			break;
180 		default:
181 			usage();
182 		}
183 	}
184 
185 	if (argc == optind)
186 		usage();
187 
188 	if (dev == NULL)
189 		dev = argv[optind++];
190 
191 	if (argc == optind)
192 		usage();
193 
194 	cmd = argv[optind++];
195 	for (i = 0; cmdsw[i]->name != NULL && strcmp(cmd, cmdsw[i]->name); i++)
196 		continue;
197 
198 	if (cmdsw[i]->fptr == NULL)
199 		errx(EXIT_FAILURE, "Unknown command: %s", cmd);
200 
201 	prefix(cmd);
202 
203 	if (*dev != '-') {
204 		gpt = gpt_open(dev, flags | cmdsw[i]->flags,
205 		    verbose, mediasz, secsz);
206 		if (gpt == NULL)
207 			return EXIT_FAILURE;
208 	} else {
209 		argc++;
210 		gpt = NULL;
211 	}
212 
213 	if ((*cmdsw[i]->fptr)(gpt, argc, argv) == -1)
214 		return EXIT_FAILURE;
215 
216 	if (gpt)
217 		gpt_close(gpt);
218 	return EXIT_SUCCESS;
219 }
220