main.c revision 1.9
1/* $NetBSD: main.c,v 1.9 2017/02/16 03:32:17 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.9 2017/02/16 03:32:17 christos Exp $"); 38#endif 39 40#include <stdio.h> 41#include <stdlib.h> 42#include <unistd.h> 43#include <err.h> 44#include <errno.h> 45#include <sys/stat.h> 46#ifndef NBTOOL_CONFIG_H 47#include <util.h> 48#endif 49 50#include "map.h" 51#include "gpt.h" 52 53static const struct gpt_cmd c_null; 54 55extern const struct gpt_cmd 56 c_add, 57#ifndef HAVE_NBTOOL_CONFIG_H 58 c_backup, 59#endif 60 c_biosboot, 61 c_create, 62 c_destroy, 63 c_header, 64 c_label, 65 c_migrate, 66 c_recover, 67 c_remove, 68 c_resize, 69 c_resizedisk, 70#ifndef HAVE_NBTOOL_CONFIG_H 71 c_restore, 72#endif 73 c_set, 74 c_show, 75 c_type, 76 c_unset; 77 78static const struct gpt_cmd *cmdsw[] = { 79 &c_add, 80#ifndef HAVE_NBTOOL_CONFIG_H 81 &c_backup, 82#endif 83 &c_biosboot, 84 &c_create, 85 &c_destroy, 86 &c_header, 87 &c_label, 88 &c_migrate, 89 &c_recover, 90 &c_remove, 91 &c_resize, 92 &c_resizedisk, 93#ifndef HAVE_NBTOOL_CONFIG_H 94 &c_restore, 95#endif 96 &c_set, 97 &c_show, 98 &c_type, 99 &c_unset, 100 &c_null, 101}; 102 103__dead static void 104usage(void) 105{ 106 const char *p = getprogname(); 107 const char *f = 108 "[-nrqv] [-m mediasize] [-s sectorsize]"; 109 size_t i; 110 111 if (strcmp(p, "gpt") == 0) 112 fprintf(stderr, 113 "Usage: %s %s command device\n", p, f); 114 else 115 fprintf(stderr, 116 "Usage: %s %s device command\n", p, f); 117 fprintf(stderr, "Commands:\n"); 118 for (i = 0; i < __arraycount(cmdsw); i++) 119 gpt_usage("\t", cmdsw[i]); 120 exit(EXIT_FAILURE); 121} 122 123static void 124prefix(const char *cmd) 125{ 126 char *pfx; 127 128 if (asprintf(&pfx, "%s %s", getprogname(), cmd) < 0) 129 pfx = NULL; 130 else 131 setprogname(pfx); 132} 133 134static time_t 135get_tstamp(const char *b) 136{ 137 struct stat st; 138 char *eb; 139 long long l; 140#ifndef HAVE_NBTOOL_CONFIG_H 141 time_t when; 142#endif 143 144 if (stat(b, &st) != -1) 145 return (time_t)st.st_mtime; 146 147#ifndef HAVE_NBTOOL_CONFIG_H 148 errno = 0; 149 if ((when = parsedate(b, NULL, NULL)) != -1 || errno == 0) 150 return when; 151#endif 152 errno = 0; 153 l = strtoll(b, &eb, 0); 154 if (b == eb || *eb || errno) 155 errx(EXIT_FAILURE, "Can't parse timestamp `%s'", b); 156 return (time_t)l; 157} 158 159int 160main(int argc, char *argv[]) 161{ 162 char *cmd, *p, *dev = NULL; 163 int ch, i; 164 u_int secsz = 0; 165 off_t mediasz = 0; 166 int flags = 0; 167 int verbose = 0; 168 time_t timestamp = 0; 169 gpt_t gpt; 170 171 setprogname(argv[0]); 172 173 if (strcmp(getprogname(), "gpt") == 0) { 174 if (argc < 3) 175 usage(); 176 dev = argv[--argc]; 177 } 178 179#ifdef __GLIBC__ 180#define GETOPT_BE_POSIX "+" 181#else 182#define GETOPT_BE_POSIX "" 183#endif 184 185 /* Get the generic options */ 186 while ((ch = getopt(argc, argv, GETOPT_BE_POSIX "m:nqrs:T:v")) != -1) { 187 switch(ch) { 188 case 'm': 189 if (mediasz > 0) 190 usage(); 191 mediasz = strtol(optarg, &p, 10); 192 if (*p != 0 || mediasz < 1) 193 usage(); 194 break; 195 case 'n': 196 flags |= GPT_NOSYNC; 197 break; 198 case 'r': 199 flags |= GPT_READONLY; 200 break; 201 case 'q': 202 flags |= GPT_QUIET; 203 break; 204 case 's': 205 if (gpt_uint_get(NULL, &secsz) == -1) 206 usage(); 207 break; 208 case 'T': 209 timestamp = get_tstamp(optarg); 210 break; 211 case 'v': 212 verbose++; 213 break; 214 default: 215 usage(); 216 } 217 } 218 219 if (argc == optind) 220 usage(); 221 222 if (dev == NULL) 223 dev = argv[optind++]; 224 225 if (argc == optind) 226 usage(); 227 228 cmd = argv[optind++]; 229 for (i = 0; cmdsw[i]->name != NULL && strcmp(cmd, cmdsw[i]->name); i++) 230 continue; 231 232 if (cmdsw[i]->fptr == NULL) 233 errx(EXIT_FAILURE, "Unknown command: %s", cmd); 234 235 prefix(cmd); 236 237 if (*dev != '-') { 238 gpt = gpt_open(dev, flags | cmdsw[i]->flags, 239 verbose, mediasz, secsz, timestamp); 240 if (gpt == NULL) 241 return EXIT_FAILURE; 242 } else { 243 argc++; 244 gpt = NULL; 245 } 246 247 if ((*cmdsw[i]->fptr)(gpt, argc, argv) == -1) 248 return EXIT_FAILURE; 249 250 if (gpt) 251 gpt_close(gpt); 252 return EXIT_SUCCESS; 253} 254