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