xref: /netbsd-src/sbin/gpt/main.c (revision e5906ade5eb91c13c173c6fd1f0ae477ca0d90a4)
1*e5906adeSjmcneill /*	$NetBSD: main.c,v 1.14 2020/05/24 18:42:20 jmcneill Exp $	*/
2e4ed2565Schristos 
3e4ed2565Schristos /*-
4e4ed2565Schristos  * Copyright (c) 2002 Marcel Moolenaar
5e4ed2565Schristos  * All rights reserved.
6e4ed2565Schristos  *
7e4ed2565Schristos  * Redistribution and use in source and binary forms, with or without
8e4ed2565Schristos  * modification, are permitted provided that the following conditions
9e4ed2565Schristos  * are met:
10e4ed2565Schristos  *
11e4ed2565Schristos  * 1. Redistributions of source code must retain the above copyright
12e4ed2565Schristos  *    notice, this list of conditions and the following disclaimer.
13e4ed2565Schristos  * 2. Redistributions in binary form must reproduce the above copyright
14e4ed2565Schristos  *    notice, this list of conditions and the following disclaimer in the
15e4ed2565Schristos  *    documentation and/or other materials provided with the distribution.
16e4ed2565Schristos  *
17e4ed2565Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18e4ed2565Schristos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19e4ed2565Schristos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20e4ed2565Schristos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21e4ed2565Schristos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22e4ed2565Schristos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23e4ed2565Schristos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24e4ed2565Schristos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25e4ed2565Schristos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26e4ed2565Schristos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27e4ed2565Schristos  *
28e4ed2565Schristos  * CRC32 code derived from work by Gary S. Brown.
29e4ed2565Schristos  */
30e4ed2565Schristos 
31e4ed2565Schristos #if HAVE_NBTOOL_CONFIG_H
32e4ed2565Schristos #include "nbtool_config.h"
33e4ed2565Schristos #endif
34e4ed2565Schristos 
35e4ed2565Schristos #include <sys/cdefs.h>
36e4ed2565Schristos #ifdef __RCSID
37*e5906adeSjmcneill __RCSID("$NetBSD: main.c,v 1.14 2020/05/24 18:42:20 jmcneill Exp $");
38e4ed2565Schristos #endif
39e4ed2565Schristos 
40e4ed2565Schristos #include <stdio.h>
41e4ed2565Schristos #include <stdlib.h>
42e4ed2565Schristos #include <unistd.h>
43e4ed2565Schristos #include <err.h>
44ef9cffabSchristos #include <errno.h>
45ef9cffabSchristos #include <sys/stat.h>
46ef9cffabSchristos #ifndef NBTOOL_CONFIG_H
47ef9cffabSchristos #include <util.h>
48ef9cffabSchristos #endif
49e4ed2565Schristos 
50e4ed2565Schristos #include "map.h"
51e4ed2565Schristos #include "gpt.h"
52e4ed2565Schristos 
538ca93e46Schristos static const struct gpt_cmd c_null;
548ca93e46Schristos 
558ca93e46Schristos extern const struct gpt_cmd
568ca93e46Schristos 	c_add,
57e4ed2565Schristos #ifndef HAVE_NBTOOL_CONFIG_H
588ca93e46Schristos 	c_backup,
59e4ed2565Schristos #endif
608ca93e46Schristos 	c_biosboot,
618ca93e46Schristos 	c_create,
628ca93e46Schristos 	c_destroy,
638ca93e46Schristos 	c_header,
648ca93e46Schristos 	c_label,
658ca93e46Schristos 	c_migrate,
668ca93e46Schristos 	c_recover,
678ca93e46Schristos 	c_remove,
688ca93e46Schristos 	c_resize,
698ca93e46Schristos 	c_resizedisk,
70e4ed2565Schristos #ifndef HAVE_NBTOOL_CONFIG_H
718ca93e46Schristos 	c_restore,
72e4ed2565Schristos #endif
738ca93e46Schristos 	c_set,
748ca93e46Schristos 	c_show,
758ca93e46Schristos 	c_type,
767d442200Sjnemeth 	c_unset,
777d442200Sjnemeth 	c_uuid;
788ca93e46Schristos 
798ca93e46Schristos static const struct gpt_cmd *cmdsw[] = {
808ca93e46Schristos 	&c_add,
818ca93e46Schristos #ifndef HAVE_NBTOOL_CONFIG_H
828ca93e46Schristos 	&c_backup,
838ca93e46Schristos #endif
848ca93e46Schristos 	&c_biosboot,
858ca93e46Schristos 	&c_create,
868ca93e46Schristos 	&c_destroy,
878ca93e46Schristos 	&c_header,
888ca93e46Schristos 	&c_label,
898ca93e46Schristos 	&c_migrate,
908ca93e46Schristos 	&c_recover,
918ca93e46Schristos 	&c_remove,
928ca93e46Schristos 	&c_resize,
938ca93e46Schristos 	&c_resizedisk,
948ca93e46Schristos #ifndef HAVE_NBTOOL_CONFIG_H
958ca93e46Schristos 	&c_restore,
968ca93e46Schristos #endif
978ca93e46Schristos 	&c_set,
988ca93e46Schristos 	&c_show,
998ca93e46Schristos 	&c_type,
1008ca93e46Schristos 	&c_unset,
1017d442200Sjnemeth 	&c_uuid,
1028ca93e46Schristos 	&c_null,
103e4ed2565Schristos };
104e4ed2565Schristos 
105e4ed2565Schristos __dead static void
usage(void)106e4ed2565Schristos usage(void)
107e4ed2565Schristos {
108e4ed2565Schristos 	const char *p = getprogname();
109e4ed2565Schristos 	const char *f =
1100a08194fSsevan 	    "[-nrqv] [-m mediasize] [-s sectorsize] [-T timestamp]";
1118ca93e46Schristos 	size_t i;
112e4ed2565Schristos 
1130b43d398Schristos 	if (strcmp(p, "gpt") == 0)
114e4ed2565Schristos 		fprintf(stderr,
115da0a3b4cSchristos 		    "Usage: %s %s command device\n", p, f);
1160b43d398Schristos 	else
1170b43d398Schristos 		fprintf(stderr,
118da0a3b4cSchristos 		    "Usage: %s %s device command\n", p, f);
1198ca93e46Schristos 	fprintf(stderr, "Commands:\n");
1208ca93e46Schristos 	for (i = 0; i < __arraycount(cmdsw); i++)
1218ca93e46Schristos 		gpt_usage("\t", cmdsw[i]);
1228ca93e46Schristos 	exit(EXIT_FAILURE);
123e4ed2565Schristos }
124e4ed2565Schristos 
125e4ed2565Schristos static void
prefix(const char * cmd)126e4ed2565Schristos prefix(const char *cmd)
127e4ed2565Schristos {
128e4ed2565Schristos 	char *pfx;
129e4ed2565Schristos 
130e4ed2565Schristos 	if (asprintf(&pfx, "%s %s", getprogname(), cmd) < 0)
131e4ed2565Schristos 		pfx = NULL;
132e4ed2565Schristos 	else
133e4ed2565Schristos 		setprogname(pfx);
134e4ed2565Schristos }
135e4ed2565Schristos 
136ef9cffabSchristos static time_t
get_tstamp(const char * b)137ef9cffabSchristos get_tstamp(const char *b)
138ef9cffabSchristos {
139ef9cffabSchristos 	struct stat st;
140ef9cffabSchristos 	char *eb;
141ef9cffabSchristos 	long long l;
142ef9cffabSchristos #ifndef HAVE_NBTOOL_CONFIG_H
143ef9cffabSchristos 	time_t when;
144ef9cffabSchristos #endif
145ef9cffabSchristos 
146ef9cffabSchristos 	if (stat(b, &st) != -1)
147ef9cffabSchristos 		return (time_t)st.st_mtime;
148ef9cffabSchristos 
149ef9cffabSchristos #ifndef HAVE_NBTOOL_CONFIG_H
150ef9cffabSchristos 	errno = 0;
151ef9cffabSchristos 	if ((when = parsedate(b, NULL, NULL)) != -1 || errno == 0)
152ef9cffabSchristos 		return when;
153ef9cffabSchristos #endif
154ef9cffabSchristos 	errno = 0;
155ef9cffabSchristos 	l = strtoll(b, &eb, 0);
156ef9cffabSchristos 	if (b == eb || *eb || errno)
157ef9cffabSchristos 		errx(EXIT_FAILURE, "Can't parse timestamp `%s'", b);
158ef9cffabSchristos 	return (time_t)l;
159ef9cffabSchristos }
160ef9cffabSchristos 
161e4ed2565Schristos int
main(int argc,char * argv[])162e4ed2565Schristos main(int argc, char *argv[])
163e4ed2565Schristos {
1640b43d398Schristos 	char *cmd, *p, *dev = NULL;
165e4ed2565Schristos 	int ch, i;
1660b43d398Schristos 	u_int secsz = 0;
1670b43d398Schristos 	off_t mediasz = 0;
1680b43d398Schristos 	int flags = 0;
1690b43d398Schristos 	int verbose = 0;
170ef9cffabSchristos 	time_t timestamp = 0;
1710b43d398Schristos 	gpt_t gpt;
1720b43d398Schristos 
1730b43d398Schristos 	setprogname(argv[0]);
1740b43d398Schristos 
1750b43d398Schristos 	if (strcmp(getprogname(), "gpt") == 0) {
1760b43d398Schristos 		if (argc < 3)
1770b43d398Schristos 			usage();
1780b43d398Schristos 		dev = argv[--argc];
1790b43d398Schristos 	}
180e4ed2565Schristos 
181eadf25e0Saymeric #ifdef __GLIBC__
182eadf25e0Saymeric #define GETOPT_BE_POSIX		"+"
183eadf25e0Saymeric #else
184eadf25e0Saymeric #define GETOPT_BE_POSIX		""
185eadf25e0Saymeric #endif
186eadf25e0Saymeric 
187e4ed2565Schristos 	/* Get the generic options */
188*e5906adeSjmcneill 	while ((ch = getopt(argc, argv, GETOPT_BE_POSIX "Hm:nqrs:T:v")) != -1) {
189e4ed2565Schristos 		switch(ch) {
190*e5906adeSjmcneill 		case 'H':
191*e5906adeSjmcneill 			flags |= GPT_HYBRID;
192*e5906adeSjmcneill 			break;
193e4ed2565Schristos 		case 'm':
194e4ed2565Schristos 			if (mediasz > 0)
195e4ed2565Schristos 				usage();
1965c1ccc6eSchristos 			mediasz = strtol(optarg, &p, 10);
197e4ed2565Schristos 			if (*p != 0 || mediasz < 1)
198e4ed2565Schristos 				usage();
199e4ed2565Schristos 			break;
200e4ed2565Schristos 		case 'n':
2010b43d398Schristos 			flags |= GPT_NOSYNC;
202e4ed2565Schristos 			break;
203e4ed2565Schristos 		case 'r':
2040b43d398Schristos 			flags |= GPT_READONLY;
205e4ed2565Schristos 			break;
206e4ed2565Schristos 		case 'q':
2070b43d398Schristos 			flags |= GPT_QUIET;
208e4ed2565Schristos 			break;
209e4ed2565Schristos 		case 's':
210f9db7548Schristos 			if (gpt_uint_get(NULL, &secsz) == -1)
211e4ed2565Schristos 				usage();
212e4ed2565Schristos 			break;
213ef9cffabSchristos 		case 'T':
214f8bc8f05Schristos 			flags |= GPT_TIMESTAMP;
215ef9cffabSchristos 			timestamp = get_tstamp(optarg);
216ef9cffabSchristos 			break;
217e4ed2565Schristos 		case 'v':
218e4ed2565Schristos 			verbose++;
219e4ed2565Schristos 			break;
220e4ed2565Schristos 		default:
221e4ed2565Schristos 			usage();
222e4ed2565Schristos 		}
223e4ed2565Schristos 	}
2240b43d398Schristos 
2250b43d398Schristos 	if (argc == optind)
2260b43d398Schristos 		usage();
2270b43d398Schristos 
2280b43d398Schristos 	if (dev == NULL)
2290b43d398Schristos 		dev = argv[optind++];
230e4ed2565Schristos 
231e4ed2565Schristos 	if (argc == optind)
232e4ed2565Schristos 		usage();
233e4ed2565Schristos 
234e4ed2565Schristos 	cmd = argv[optind++];
2358ca93e46Schristos 	for (i = 0; cmdsw[i]->name != NULL && strcmp(cmd, cmdsw[i]->name); i++)
2360b43d398Schristos 		continue;
237e4ed2565Schristos 
2388ca93e46Schristos 	if (cmdsw[i]->fptr == NULL)
2390b43d398Schristos 		errx(EXIT_FAILURE, "Unknown command: %s", cmd);
240e4ed2565Schristos 
241e4ed2565Schristos 	prefix(cmd);
2420b43d398Schristos 
243f9db7548Schristos 	if (*dev != '-') {
244f9db7548Schristos 		gpt = gpt_open(dev, flags | cmdsw[i]->flags,
245ef9cffabSchristos 		    verbose, mediasz, secsz, timestamp);
2460b43d398Schristos 		if (gpt == NULL)
2470b43d398Schristos 			return EXIT_FAILURE;
248f9db7548Schristos 	} else {
249a23ee504Smlelstv 		if ((cmdsw[i]->flags & GPT_OPTDEV) == 0)
250a23ee504Smlelstv 			errx(EXIT_FAILURE,
251a23ee504Smlelstv 			     "Command %s needs a device parameter", cmd);
252f9db7548Schristos 		argc++;
253f9db7548Schristos 		gpt = NULL;
254f9db7548Schristos 	}
2550b43d398Schristos 
2568ca93e46Schristos 	if ((*cmdsw[i]->fptr)(gpt, argc, argv) == -1)
2570b43d398Schristos 		return EXIT_FAILURE;
2580b43d398Schristos 
259f9db7548Schristos 	if (gpt)
2600b43d398Schristos 		gpt_close(gpt);
2610b43d398Schristos 	return EXIT_SUCCESS;
262e4ed2565Schristos }
263