main.c revision 1.8
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
48static const struct gpt_cmd c_null;
49
50extern 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
73static 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
99usage(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
118static void
119prefix(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
129int
130main(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