Annotation of src/sbin/gpt/backup.c, Revision 1.15
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.4 christos 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.15 ! christos 36: __RCSID("$NetBSD: backup.c,v 1.14 2015/12/03 01:07:28 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.10 christos 52: #include "gpt_private.h"
1.1 jnemeth 53:
1.11 christos 54: static const char *backuphelp[] = {
1.14 christos 55: "[-o outfile]",
1.11 christos 56: };
57:
58: static int cmd_backup(gpt_t, int, char *[]);
59:
60: struct gpt_cmd c_backup = {
61: "backup",
62: cmd_backup,
63: backuphelp, __arraycount(backuphelp),
64: GPT_READONLY,
65: };
1.1 jnemeth 66:
1.11 christos 67: #define usage() gpt_usage(NULL, &c_backup)
1.1 jnemeth 68:
1.10 christos 69: #define PROP_ERR(x) if (!(x)) { \
70: gpt_warnx(gpt, "proplib failure"); \
71: return -1; \
1.1 jnemeth 72: }
73:
1.12 christos 74: #define prop_uint(a) prop_number_create_unsigned_integer(a)
75:
76: static int
77: store_mbr(gpt_t gpt, unsigned int i, const struct mbr *mbr,
78: prop_array_t *mbr_array)
79: {
80: prop_dictionary_t mbr_dict;
81: prop_number_t propnum;
82: const struct mbr_part *par = &mbr->mbr_part[i];
83: bool rc;
84:
85: if (mbr->mbr_part[i].part_typ == MBR_PTYPE_UNUSED)
86: return 0;
87:
88: mbr_dict = prop_dictionary_create();
89: PROP_ERR(mbr_dict);
90: propnum = prop_number_create_integer(i);
91: PROP_ERR(propnum);
92: rc = prop_dictionary_set(mbr_dict, "index", propnum);
93: PROP_ERR(rc);
94: propnum = prop_uint(par->part_flag);
95: PROP_ERR(propnum);
96: rc = prop_dictionary_set(mbr_dict, "flag", propnum);
97: PROP_ERR(rc);
98: propnum = prop_uint(par->part_shd);
99: PROP_ERR(propnum);
100: rc = prop_dictionary_set(mbr_dict, "start_head", propnum);
101: PROP_ERR(rc);
102: propnum = prop_uint(par->part_ssect);
103: PROP_ERR(propnum);
104: rc = prop_dictionary_set(mbr_dict, "start_sector", propnum);
105: PROP_ERR(rc);
106: propnum = prop_uint(par->part_scyl);
107: PROP_ERR(propnum);
108: rc = prop_dictionary_set(mbr_dict, "start_cylinder", propnum);
109: PROP_ERR(rc);
110: propnum = prop_uint(par->part_typ);
111: PROP_ERR(propnum);
112: rc = prop_dictionary_set(mbr_dict, "type", propnum);
113: PROP_ERR(rc);
114: propnum = prop_uint(par->part_ehd);
115: PROP_ERR(propnum);
116: rc = prop_dictionary_set(mbr_dict, "end_head", propnum);
117: PROP_ERR(rc);
118: propnum = prop_uint(par->part_esect);
119: PROP_ERR(propnum);
120: rc = prop_dictionary_set(mbr_dict, "end_sector", propnum);
121: PROP_ERR(rc);
122: propnum = prop_uint(par->part_ecyl);
123: PROP_ERR(propnum);
124: rc = prop_dictionary_set(mbr_dict, "end_cylinder", propnum);
125: PROP_ERR(rc);
126: propnum = prop_uint(le16toh(par->part_start_lo));
127: PROP_ERR(propnum);
128: rc = prop_dictionary_set(mbr_dict, "lba_start_low", propnum);
129: PROP_ERR(rc);
130: propnum = prop_uint(le16toh(par->part_start_hi));
131: PROP_ERR(propnum);
132: rc = prop_dictionary_set(mbr_dict, "lba_start_high", propnum);
133: PROP_ERR(rc);
134: propnum = prop_uint(le16toh(par->part_size_lo));
135: PROP_ERR(propnum);
136: rc = prop_dictionary_set(mbr_dict, "lba_size_low", propnum);
137: PROP_ERR(rc);
138: propnum = prop_uint(le16toh(par->part_size_hi));
139: PROP_ERR(propnum);
140: rc = prop_dictionary_set(mbr_dict, "lba_size_high", propnum);
141: if (*mbr_array == NULL) {
142: *mbr_array = prop_array_create();
143: PROP_ERR(*mbr_array);
144: }
145: rc = prop_array_add(*mbr_array, mbr_dict);
146: PROP_ERR(rc);
147: return 0;
148: }
149:
150: static int
151: store_gpt(gpt_t gpt, const struct gpt_hdr *hdr, prop_dictionary_t *type_dict)
152: {
153: prop_number_t propnum;
154: prop_string_t propstr;
155: char buf[128];
156: bool rc;
157:
158: *type_dict = prop_dictionary_create();
159: PROP_ERR(type_dict);
160: propnum = prop_uint(le32toh(hdr->hdr_revision));
161: PROP_ERR(propnum);
162: rc = prop_dictionary_set(*type_dict, "revision", propnum);
163: PROP_ERR(rc);
164: gpt_uuid_snprintf(buf, sizeof(buf), "%d", hdr->hdr_guid);
165: propstr = prop_string_create_cstring(buf);
166: PROP_ERR(propstr);
167: rc = prop_dictionary_set(*type_dict, "guid", propstr);
168: PROP_ERR(rc);
169: propnum = prop_number_create_integer(le32toh(hdr->hdr_entries));
170: PROP_ERR(propnum);
171: rc = prop_dictionary_set(*type_dict, "entries", propnum);
172: PROP_ERR(rc);
173: return 0;
174: }
175:
176: static int
177: store_tbl(gpt_t gpt, const map_t m, prop_dictionary_t *type_dict)
178: {
179: const struct gpt_ent *ent;
180: unsigned int i;
181: prop_dictionary_t gpt_dict;
182: prop_array_t gpt_array;
183: prop_number_t propnum;
184: prop_string_t propstr;
185: char buf[128];
186: uint8_t utfbuf[__arraycount(ent->ent_name) * 3 + 1];
187: bool rc;
188:
189: *type_dict = prop_dictionary_create();
190: PROP_ERR(*type_dict);
191:
192: ent = m->map_data;
193: gpt_array = prop_array_create();
194: PROP_ERR(gpt_array);
195: for (i = 1, ent = m->map_data;
196: (const char *)ent < (const char *)(m->map_data) +
197: m->map_size * gpt->secsz; i++, ent++) {
198: gpt_dict = prop_dictionary_create();
199: PROP_ERR(gpt_dict);
200: propnum = prop_number_create_integer(i);
201: PROP_ERR(propnum);
202: rc = prop_dictionary_set(gpt_dict, "index", propnum);
203: PROP_ERR(propnum);
204: gpt_uuid_snprintf(buf, sizeof(buf), "%d", ent->ent_type);
205: propstr = prop_string_create_cstring(buf);
206: PROP_ERR(propstr);
207: rc = prop_dictionary_set(gpt_dict, "type", propstr);
208: gpt_uuid_snprintf(buf, sizeof(buf), "%d", ent->ent_guid);
209: propstr = prop_string_create_cstring(buf);
210: PROP_ERR(propstr);
211: rc = prop_dictionary_set(gpt_dict, "guid", propstr);
212: PROP_ERR(propstr);
213: propnum = prop_uint(le64toh(ent->ent_lba_start));
214: PROP_ERR(propnum);
215: rc = prop_dictionary_set(gpt_dict, "start", propnum);
216: PROP_ERR(rc);
217: propnum = prop_uint(le64toh(ent->ent_lba_end));
218: PROP_ERR(rc);
219: rc = prop_dictionary_set(gpt_dict, "end", propnum);
220: PROP_ERR(rc);
221: propnum = prop_uint(le64toh(ent->ent_attr));
222: PROP_ERR(propnum);
223: rc = prop_dictionary_set(gpt_dict, "attributes", propnum);
224: PROP_ERR(rc);
225: utf16_to_utf8(ent->ent_name, utfbuf, sizeof(utfbuf));
226: if (utfbuf[0] != '\0') {
227: propstr = prop_string_create_cstring((char *)utfbuf);
228: PROP_ERR(propstr);
229: rc = prop_dictionary_set(gpt_dict, "name", propstr);
230: PROP_ERR(rc);
231: }
232: rc = prop_array_add(gpt_array, gpt_dict);
233: PROP_ERR(rc);
234: }
235: rc = prop_dictionary_set(*type_dict, "gpt_array", gpt_array);
236: PROP_ERR(rc);
237: prop_object_release(gpt_array);
238: return 0;
239: }
240:
1.10 christos 241: static int
1.14 christos 242: backup(gpt_t gpt, const char *outfile)
1.1 jnemeth 243: {
1.10 christos 244: map_t m;
1.1 jnemeth 245: struct mbr *mbr;
246: unsigned int i;
1.12 christos 247: prop_dictionary_t props, type_dict;
248: prop_array_t mbr_array;
1.1 jnemeth 249: prop_data_t propdata;
250: prop_number_t propnum;
1.12 christos 251: char *propext;
1.1 jnemeth 252: bool rc;
1.13 christos 253: FILE *fp;
1.1 jnemeth 254:
255: props = prop_dictionary_create();
256: PROP_ERR(props);
1.10 christos 257: propnum = prop_number_create_integer(gpt->secsz);
1.2 jnemeth 258: PROP_ERR(propnum);
259: rc = prop_dictionary_set(props, "sector_size", propnum);
260: PROP_ERR(rc);
1.10 christos 261: m = map_first(gpt);
1.1 jnemeth 262: while (m != NULL) {
263: switch (m->map_type) {
264: case MAP_TYPE_MBR:
265: case MAP_TYPE_PMBR:
266: type_dict = prop_dictionary_create();
267: PROP_ERR(type_dict);
268: mbr = m->map_data;
269: propdata = prop_data_create_data_nocopy(mbr->mbr_code,
270: sizeof(mbr->mbr_code));
271: PROP_ERR(propdata);
272: rc = prop_dictionary_set(type_dict, "code", propdata);
273: PROP_ERR(rc);
274: mbr_array = NULL;
275: for (i = 0; i < 4; i++) {
1.12 christos 276: if (store_mbr(gpt, i, mbr, &mbr_array) == -1)
277: return -1;
1.1 jnemeth 278: }
279: if (mbr_array != NULL) {
280: rc = prop_dictionary_set(type_dict,
281: "mbr_array", mbr_array);
282: PROP_ERR(rc);
283: prop_object_release(mbr_array);
284: }
285: rc = prop_dictionary_set(props, "MBR", type_dict);
286: PROP_ERR(rc);
287: prop_object_release(type_dict);
288: break;
289: case MAP_TYPE_PRI_GPT_HDR:
1.12 christos 290: if (store_gpt(gpt, m->map_data, &type_dict) == -1)
291: return -1;
292:
1.1 jnemeth 293: rc = prop_dictionary_set(props, "GPT_HDR", type_dict);
294: PROP_ERR(rc);
295: prop_object_release(type_dict);
296: break;
297: case MAP_TYPE_PRI_GPT_TBL:
1.12 christos 298: if (store_tbl(gpt, m, &type_dict) == -1)
299: return -1;
1.1 jnemeth 300: rc = prop_dictionary_set(props, "GPT_TBL", type_dict);
301: PROP_ERR(rc);
302: prop_object_release(type_dict);
303: break;
304: }
305: m = m->map_next;
306: }
307: propext = prop_dictionary_externalize(props);
308: PROP_ERR(propext);
309: prop_object_release(props);
1.14 christos 310: fp = strcmp(outfile, "-") == 0 ? stdout : fopen(outfile, "w");
311: if (fp == NULL) {
1.13 christos 312: gpt_warn(gpt, "Can't open `%s'", outfile);
313: return -1;
314: }
315: fputs(propext, fp);
1.15 ! christos 316: if (fp != stdout)
1.14 christos 317: fclose(fp);
1.3 jnemeth 318: free(propext);
1.10 christos 319: return 0;
1.1 jnemeth 320: }
321:
1.11 christos 322: static int
1.10 christos 323: cmd_backup(gpt_t gpt, int argc, char *argv[])
1.1 jnemeth 324: {
1.13 christos 325: int ch;
1.14 christos 326: const char *outfile = "-";
1.13 christos 327:
328: while ((ch = getopt(argc, argv, "o:")) != -1) {
329: switch(ch) {
330: case 'o':
331: outfile = optarg;
332: break;
333: default:
334: return usage();
335: }
336: }
1.10 christos 337: if (argc != optind)
1.11 christos 338: return usage();
1.1 jnemeth 339:
1.14 christos 340: return backup(gpt, outfile);
1.1 jnemeth 341: }
CVSweb <webmaster@jp.NetBSD.org>