xref: /netbsd-src/sbin/gpt/main.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /*	$NetBSD: main.c,v 1.7 2015/12/29 16:45:04 christos 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.7 2015/12/29 16:45:04 christos 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 	/* Get the generic options */
149 	while ((ch = getopt(argc, argv, "m:nqrs:v")) != -1) {
150 		switch(ch) {
151 		case 'm':
152 			if (mediasz > 0)
153 				usage();
154 			mediasz = strtol(optarg, &p, 10);
155 			if (*p != 0 || mediasz < 1)
156 				usage();
157 			break;
158 		case 'n':
159 			flags |= GPT_NOSYNC;
160 			break;
161 		case 'r':
162 			flags |= GPT_READONLY;
163 			break;
164 		case 'q':
165 			flags |= GPT_QUIET;
166 			break;
167 		case 's':
168 			if (gpt_uint_get(NULL, &secsz) == -1)
169 				usage();
170 			break;
171 		case 'v':
172 			verbose++;
173 			break;
174 		default:
175 			usage();
176 		}
177 	}
178 
179 	if (argc == optind)
180 		usage();
181 
182 	if (dev == NULL)
183 		dev = argv[optind++];
184 
185 	if (argc == optind)
186 		usage();
187 
188 	cmd = argv[optind++];
189 	for (i = 0; cmdsw[i]->name != NULL && strcmp(cmd, cmdsw[i]->name); i++)
190 		continue;
191 
192 	if (cmdsw[i]->fptr == NULL)
193 		errx(EXIT_FAILURE, "Unknown command: %s", cmd);
194 
195 	prefix(cmd);
196 
197 	if (*dev != '-') {
198 		gpt = gpt_open(dev, flags | cmdsw[i]->flags,
199 		    verbose, mediasz, secsz);
200 		if (gpt == NULL)
201 			return EXIT_FAILURE;
202 	} else {
203 		argc++;
204 		gpt = NULL;
205 	}
206 
207 	if ((*cmdsw[i]->fptr)(gpt, argc, argv) == -1)
208 		return EXIT_FAILURE;
209 
210 	if (gpt)
211 		gpt_close(gpt);
212 	return EXIT_SUCCESS;
213 }
214