Annotation of src/sbin/gpt/backup.c, Revision 1.1.6.2
1.1 jnemeth 1: /*-
2: * Copyright (c) 2002 Marcel Moolenaar
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: *
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: *
15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
1.1.6.1 snj 27: #if HAVE_NBTOOL_CONFIG_H
28: #include "nbtool_config.h"
29: #endif
30:
1.1 jnemeth 31: #include <sys/cdefs.h>
32: #ifdef __FBSDID
33: __FBSDID("$FreeBSD: src/sbin/gpt/show.c,v 1.14 2006/06/22 22:22:32 marcel Exp $");
34: #endif
35: #ifdef __RCSID
1.1.6.2 ! martin 36: __RCSID("$NetBSD: backup.c,v 1.18 2017/09/07 10:23:33 christos Exp $");
1.1 jnemeth 37: #endif
38:
39: #include <sys/bootblock.h>
40: #include <sys/types.h>
41:
42: #include <err.h>
43: #include <stddef.h>
44: #include <stdio.h>
45: #include <stdlib.h>
46: #include <string.h>
47: #include <unistd.h>
48: #include <prop/proplib.h>
49:
50: #include "map.h"
51: #include "gpt.h"
1.1.6.2 ! martin 52: #include "gpt_private.h"
1.1 jnemeth 53:
1.1.6.2 ! martin 54: static const char *backuphelp[] = {
! 55: "[-o outfile]",
! 56: };
1.1 jnemeth 57:
1.1.6.2 ! martin 58: static int cmd_backup(gpt_t, int, char *[]);
1.1 jnemeth 59:
1.1.6.2 ! martin 60: struct gpt_cmd c_backup = {
! 61: "backup",
! 62: cmd_backup,
! 63: backuphelp, __arraycount(backuphelp),
! 64: GPT_READONLY,
! 65: };
! 66:
! 67: #define usage() gpt_usage(NULL, &c_backup)
! 68:
! 69: #define PROP_ERR(x) if (!(x)) goto cleanup
! 70:
! 71: #define prop_uint(a) prop_number_create_unsigned_integer(a)
! 72:
! 73: static int
! 74: store_mbr(gpt_t gpt, unsigned int i, const struct mbr *mbr,
! 75: prop_array_t *mbr_array)
1.1 jnemeth 76: {
1.1.6.2 ! martin 77: prop_dictionary_t mbr_dict;
! 78: prop_number_t propnum;
! 79: const struct mbr_part *par = &mbr->mbr_part[i];
! 80: bool rc;
1.1 jnemeth 81:
1.1.6.2 ! martin 82: if (mbr->mbr_part[i].part_typ == MBR_PTYPE_UNUSED)
! 83: return 0;
! 84:
! 85: mbr_dict = prop_dictionary_create();
! 86: PROP_ERR(mbr_dict);
! 87: propnum = prop_number_create_integer(i);
! 88: PROP_ERR(propnum);
! 89: rc = prop_dictionary_set(mbr_dict, "index", propnum);
! 90: PROP_ERR(rc);
! 91: propnum = prop_uint(par->part_flag);
! 92: PROP_ERR(propnum);
! 93: rc = prop_dictionary_set(mbr_dict, "flag", propnum);
! 94: PROP_ERR(rc);
! 95: propnum = prop_uint(par->part_shd);
! 96: PROP_ERR(propnum);
! 97: rc = prop_dictionary_set(mbr_dict, "start_head", propnum);
! 98: PROP_ERR(rc);
! 99: propnum = prop_uint(par->part_ssect);
! 100: PROP_ERR(propnum);
! 101: rc = prop_dictionary_set(mbr_dict, "start_sector", propnum);
! 102: PROP_ERR(rc);
! 103: propnum = prop_uint(par->part_scyl);
! 104: PROP_ERR(propnum);
! 105: rc = prop_dictionary_set(mbr_dict, "start_cylinder", propnum);
! 106: PROP_ERR(rc);
! 107: propnum = prop_uint(par->part_typ);
! 108: PROP_ERR(propnum);
! 109: rc = prop_dictionary_set(mbr_dict, "type", propnum);
! 110: PROP_ERR(rc);
! 111: propnum = prop_uint(par->part_ehd);
! 112: PROP_ERR(propnum);
! 113: rc = prop_dictionary_set(mbr_dict, "end_head", propnum);
! 114: PROP_ERR(rc);
! 115: propnum = prop_uint(par->part_esect);
! 116: PROP_ERR(propnum);
! 117: rc = prop_dictionary_set(mbr_dict, "end_sector", propnum);
! 118: PROP_ERR(rc);
! 119: propnum = prop_uint(par->part_ecyl);
! 120: PROP_ERR(propnum);
! 121: rc = prop_dictionary_set(mbr_dict, "end_cylinder", propnum);
! 122: PROP_ERR(rc);
! 123: propnum = prop_uint(le16toh(par->part_start_lo));
! 124: PROP_ERR(propnum);
! 125: rc = prop_dictionary_set(mbr_dict, "lba_start_low", propnum);
! 126: PROP_ERR(rc);
! 127: propnum = prop_uint(le16toh(par->part_start_hi));
! 128: PROP_ERR(propnum);
! 129: rc = prop_dictionary_set(mbr_dict, "lba_start_high", propnum);
! 130: PROP_ERR(rc);
! 131: propnum = prop_uint(le16toh(par->part_size_lo));
! 132: PROP_ERR(propnum);
! 133: rc = prop_dictionary_set(mbr_dict, "lba_size_low", propnum);
! 134: PROP_ERR(rc);
! 135: propnum = prop_uint(le16toh(par->part_size_hi));
! 136: PROP_ERR(propnum);
! 137: rc = prop_dictionary_set(mbr_dict, "lba_size_high", propnum);
! 138: if (*mbr_array == NULL) {
! 139: *mbr_array = prop_array_create();
! 140: PROP_ERR(*mbr_array);
! 141: }
! 142: rc = prop_array_add(*mbr_array, mbr_dict);
! 143: PROP_ERR(rc);
! 144: return 0;
! 145: cleanup:
! 146: if (mbr_dict)
! 147: prop_object_release(mbr_dict);
! 148: gpt_warnx(gpt, "proplib failure");
! 149: return -1;
1.1 jnemeth 150: }
151:
1.1.6.2 ! martin 152: static int
! 153: store_gpt(gpt_t gpt, const struct gpt_hdr *hdr, prop_dictionary_t *type_dict)
! 154: {
! 155: prop_number_t propnum;
! 156: prop_string_t propstr;
! 157: char buf[128];
! 158: bool rc;
! 159:
! 160: *type_dict = prop_dictionary_create();
! 161: PROP_ERR(type_dict);
! 162: propnum = prop_uint(le32toh(hdr->hdr_revision));
! 163: PROP_ERR(propnum);
! 164: rc = prop_dictionary_set(*type_dict, "revision", propnum);
! 165: PROP_ERR(rc);
! 166: gpt_uuid_snprintf(buf, sizeof(buf), "%d", hdr->hdr_guid);
! 167: propstr = prop_string_create_cstring(buf);
! 168: PROP_ERR(propstr);
! 169: rc = prop_dictionary_set(*type_dict, "guid", propstr);
! 170: PROP_ERR(rc);
! 171: propnum = prop_number_create_integer(le32toh(hdr->hdr_entries));
! 172: PROP_ERR(propnum);
! 173: rc = prop_dictionary_set(*type_dict, "entries", propnum);
! 174: PROP_ERR(rc);
! 175: return 0;
! 176: cleanup:
! 177: if (*type_dict)
! 178: prop_object_release(*type_dict);
! 179: return -1;
! 180: }
! 181:
! 182: static int
! 183: store_tbl(gpt_t gpt, const map_t m, prop_dictionary_t *type_dict)
! 184: {
! 185: const struct gpt_ent *ent;
! 186: unsigned int i;
! 187: prop_dictionary_t gpt_dict;
! 188: prop_array_t gpt_array;
! 189: prop_number_t propnum;
! 190: prop_string_t propstr;
! 191: char buf[128];
! 192: uint8_t utfbuf[__arraycount(ent->ent_name) * 3 + 1];
! 193: bool rc;
! 194:
! 195: *type_dict = NULL;
! 196:
! 197: gpt_array = prop_array_create();
! 198: PROP_ERR(gpt_array);
! 199:
! 200: *type_dict = prop_dictionary_create();
! 201: PROP_ERR(*type_dict);
! 202:
! 203: ent = m->map_data;
! 204: for (i = 1, ent = m->map_data;
! 205: (const char *)ent < (const char *)(m->map_data) +
! 206: m->map_size * gpt->secsz; i++, ent++) {
! 207: gpt_dict = prop_dictionary_create();
! 208: PROP_ERR(gpt_dict);
! 209: propnum = prop_number_create_integer(i);
! 210: PROP_ERR(propnum);
! 211: rc = prop_dictionary_set(gpt_dict, "index", propnum);
! 212: PROP_ERR(propnum);
! 213: gpt_uuid_snprintf(buf, sizeof(buf), "%d", ent->ent_type);
! 214: propstr = prop_string_create_cstring(buf);
! 215: PROP_ERR(propstr);
! 216: rc = prop_dictionary_set(gpt_dict, "type", propstr);
! 217: gpt_uuid_snprintf(buf, sizeof(buf), "%d", ent->ent_guid);
! 218: propstr = prop_string_create_cstring(buf);
! 219: PROP_ERR(propstr);
! 220: rc = prop_dictionary_set(gpt_dict, "guid", propstr);
! 221: PROP_ERR(propstr);
! 222: propnum = prop_uint(le64toh(ent->ent_lba_start));
! 223: PROP_ERR(propnum);
! 224: rc = prop_dictionary_set(gpt_dict, "start", propnum);
! 225: PROP_ERR(rc);
! 226: propnum = prop_uint(le64toh(ent->ent_lba_end));
! 227: PROP_ERR(rc);
! 228: rc = prop_dictionary_set(gpt_dict, "end", propnum);
! 229: PROP_ERR(rc);
! 230: propnum = prop_uint(le64toh(ent->ent_attr));
! 231: PROP_ERR(propnum);
! 232: rc = prop_dictionary_set(gpt_dict, "attributes", propnum);
! 233: PROP_ERR(rc);
! 234: utf16_to_utf8(ent->ent_name, __arraycount(ent->ent_name),
! 235: utfbuf, __arraycount(utfbuf));
! 236: if (utfbuf[0] != '\0') {
! 237: propstr = prop_string_create_cstring((char *)utfbuf);
! 238: PROP_ERR(propstr);
! 239: rc = prop_dictionary_set(gpt_dict, "name", propstr);
! 240: PROP_ERR(rc);
! 241: }
! 242: rc = prop_array_add(gpt_array, gpt_dict);
! 243: PROP_ERR(rc);
1.1 jnemeth 244: }
1.1.6.2 ! martin 245: rc = prop_dictionary_set(*type_dict, "gpt_array", gpt_array);
! 246: PROP_ERR(rc);
! 247: prop_object_release(gpt_array);
! 248: return 0;
! 249: cleanup:
! 250: if (*type_dict)
! 251: prop_object_release(*type_dict);
! 252: if (gpt_array)
! 253: prop_object_release(gpt_array);
! 254: return -1;
! 255: }
1.1 jnemeth 256:
1.1.6.2 ! martin 257: static int
! 258: backup(gpt_t gpt, const char *outfile)
1.1 jnemeth 259: {
1.1.6.2 ! martin 260: map_t m;
1.1 jnemeth 261: struct mbr *mbr;
262: unsigned int i;
1.1.6.2 ! martin 263: prop_dictionary_t props, type_dict;
! 264: prop_array_t mbr_array;
1.1 jnemeth 265: prop_data_t propdata;
266: prop_number_t propnum;
1.1.6.2 ! martin 267: char *propext;
1.1 jnemeth 268: bool rc;
1.1.6.2 ! martin 269: FILE *fp;
1.1 jnemeth 270:
271: props = prop_dictionary_create();
272: PROP_ERR(props);
1.1.6.2 ! martin 273: propnum = prop_number_create_integer(gpt->secsz);
1.1.6.1 snj 274: PROP_ERR(propnum);
275: rc = prop_dictionary_set(props, "sector_size", propnum);
276: PROP_ERR(rc);
1.1.6.2 ! martin 277: m = map_first(gpt);
1.1 jnemeth 278: while (m != NULL) {
279: switch (m->map_type) {
280: case MAP_TYPE_MBR:
281: case MAP_TYPE_PMBR:
282: type_dict = prop_dictionary_create();
283: PROP_ERR(type_dict);
284: mbr = m->map_data;
285: propdata = prop_data_create_data_nocopy(mbr->mbr_code,
286: sizeof(mbr->mbr_code));
287: PROP_ERR(propdata);
288: rc = prop_dictionary_set(type_dict, "code", propdata);
289: PROP_ERR(rc);
290: mbr_array = NULL;
291: for (i = 0; i < 4; i++) {
1.1.6.2 ! martin 292: if (store_mbr(gpt, i, mbr, &mbr_array) == -1)
! 293: goto cleanup;
1.1 jnemeth 294: }
295: if (mbr_array != NULL) {
296: rc = prop_dictionary_set(type_dict,
297: "mbr_array", mbr_array);
298: PROP_ERR(rc);
299: prop_object_release(mbr_array);
300: }
301: rc = prop_dictionary_set(props, "MBR", type_dict);
302: PROP_ERR(rc);
303: prop_object_release(type_dict);
304: break;
305: case MAP_TYPE_PRI_GPT_HDR:
1.1.6.2 ! martin 306: if (store_gpt(gpt, m->map_data, &type_dict) == -1)
! 307: goto cleanup;
! 308:
1.1 jnemeth 309: rc = prop_dictionary_set(props, "GPT_HDR", type_dict);
310: PROP_ERR(rc);
311: prop_object_release(type_dict);
312: break;
313: case MAP_TYPE_PRI_GPT_TBL:
1.1.6.2 ! martin 314: if (store_tbl(gpt, m, &type_dict) == -1)
! 315: goto cleanup;
1.1 jnemeth 316: rc = prop_dictionary_set(props, "GPT_TBL", type_dict);
317: PROP_ERR(rc);
318: prop_object_release(type_dict);
319: break;
320: }
321: m = m->map_next;
322: }
323: propext = prop_dictionary_externalize(props);
324: PROP_ERR(propext);
325: prop_object_release(props);
1.1.6.2 ! martin 326: fp = strcmp(outfile, "-") == 0 ? stdout : fopen(outfile, "w");
! 327: if (fp == NULL) {
! 328: gpt_warn(gpt, "Can't open `%s'", outfile);
! 329: free(propext);
! 330: goto cleanup;
! 331: }
! 332: fputs(propext, fp);
! 333: if (fp != stdout)
! 334: fclose(fp);
1.1.6.1 snj 335: free(propext);
1.1.6.2 ! martin 336: return 0;
! 337: cleanup:
! 338: if (props)
! 339: prop_object_release(props);
! 340: return -1;
1.1 jnemeth 341: }
342:
1.1.6.2 ! martin 343: static int
! 344: cmd_backup(gpt_t gpt, int argc, char *argv[])
1.1 jnemeth 345: {
1.1.6.2 ! martin 346: int ch;
! 347: const char *outfile = "-";
1.1 jnemeth 348:
1.1.6.2 ! martin 349: while ((ch = getopt(argc, argv, "o:")) != -1) {
! 350: switch(ch) {
! 351: case 'o':
! 352: outfile = optarg;
! 353: break;
! 354: default:
! 355: return usage();
1.1 jnemeth 356: }
357: }
1.1.6.2 ! martin 358: if (argc != optind)
! 359: return usage();
1.1 jnemeth 360:
1.1.6.2 ! martin 361: return backup(gpt, outfile);
1.1 jnemeth 362: }
CVSweb <webmaster@jp.NetBSD.org>