Annotation of src/sbin/gpt/show.c, Revision 1.41
1.1 christos 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.16 christos 27: #if HAVE_NBTOOL_CONFIG_H
28: #include "nbtool_config.h"
29: #endif
30:
1.1 christos 31: #include <sys/cdefs.h>
1.2 christos 32: #ifdef __FBSDID
1.1 christos 33: __FBSDID("$FreeBSD: src/sbin/gpt/show.c,v 1.14 2006/06/22 22:22:32 marcel Exp $");
1.2 christos 34: #endif
35: #ifdef __RCSID
1.41 ! christos 36: __RCSID("$NetBSD: show.c,v 1.40 2017/09/06 18:17:18 christos Exp $");
1.2 christos 37: #endif
1.1 christos 38:
1.38 kre 39: #include <sys/bootblock.h>
1.1 christos 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:
1.38 kre 49:
1.1 christos 50: #include "map.h"
51: #include "gpt.h"
1.24 christos 52: #include "gpt_private.h"
1.1 christos 53:
1.25 christos 54: static int cmd_show(gpt_t, int, char *[]);
1.3 riz 55:
1.25 christos 56: static const char *showhelp[] = {
1.33 wiz 57: "[-aglu] [-i index]",
1.25 christos 58: };
59:
1.28 christos 60: #define SHOW_UUID 1
61: #define SHOW_GUID 2
62: #define SHOW_LABEL 4
1.32 martin 63: #define SHOW_ALL 8
1.28 christos 64:
1.25 christos 65: struct gpt_cmd c_show = {
66: "show",
67: cmd_show,
68: showhelp, __arraycount(showhelp),
69: GPT_READONLY,
70: };
1.1 christos 71:
1.25 christos 72: #define usage() gpt_usage(NULL, &c_show)
1.1 christos 73:
1.32 martin 74: static void
75: print_part_type(int map_type, int flags, void *map_data, off_t map_start)
1.1 christos 76: {
77: off_t start;
1.32 martin 78: map_t p;
1.1 christos 79: struct mbr *mbr;
80: struct gpt_ent *ent;
81: unsigned int i;
1.28 christos 82: char buf[128], *b = buf;
1.27 christos 83: uint8_t utfbuf[__arraycount(ent->ent_name) * 3 + 1];
1.1 christos 84:
1.32 martin 85: switch (map_type) {
86: case MAP_TYPE_UNUSED:
87: printf("Unused");
88: break;
89: case MAP_TYPE_MBR:
90: if (map_start != 0)
91: printf("Extended ");
92: printf("MBR");
93: break;
94: case MAP_TYPE_PRI_GPT_HDR:
95: printf("Pri GPT header");
96: break;
97: case MAP_TYPE_SEC_GPT_HDR:
98: printf("Sec GPT header");
99: break;
100: case MAP_TYPE_PRI_GPT_TBL:
101: printf("Pri GPT table");
102: break;
103: case MAP_TYPE_SEC_GPT_TBL:
104: printf("Sec GPT table");
105: break;
106: case MAP_TYPE_MBR_PART:
107: p = map_data;
108: if (p->map_start != 0)
109: printf("Extended ");
110: printf("MBR part ");
111: mbr = p->map_data;
112: for (i = 0; i < 4; i++) {
113: start = le16toh(mbr->mbr_part[i].part_start_hi);
114: start = (start << 16) +
115: le16toh(mbr->mbr_part[i].part_start_lo);
116: if (map_start == p->map_start + start)
117: break;
118: }
1.36 dholland 119: if (i == 4) {
120: /* wasn't there */
121: printf("[partition not found?]");
122: } else {
1.37 christos 123: printf("%d%s", mbr->mbr_part[i].part_typ,
124: mbr->mbr_part[i].part_flag == 0x80 ?
125: " (active)" : "");
1.36 dholland 126: }
1.32 martin 127: break;
128: case MAP_TYPE_GPT_PART:
129: printf("GPT part ");
130: ent = map_data;
131: if (flags & SHOW_LABEL) {
1.41 ! christos 132: utf16_to_utf8(ent->ent_name,
! 133: __arraycount(ent->ent_name), utfbuf,
! 134: __arraycount(utfbuf));
1.32 martin 135: b = (char *)utfbuf;
136: } else if (flags & SHOW_GUID) {
137: gpt_uuid_snprintf( buf, sizeof(buf), "%d",
138: ent->ent_guid);
139: } else if (flags & SHOW_UUID) {
140: gpt_uuid_snprintf(buf, sizeof(buf),
141: "%d", ent->ent_type);
142: } else {
143: gpt_uuid_snprintf(buf, sizeof(buf), "%ls",
144: ent->ent_type);
145: }
146: printf("- %s", b);
147: break;
148: case MAP_TYPE_PMBR:
149: printf("PMBR");
1.38 kre 150: mbr = map_data;
151: if (mbr->mbr_part[0].part_typ == MBR_PTYPE_PMBR &&
152: mbr->mbr_part[0].part_flag == 0x80)
153: printf(" (active)");
1.32 martin 154: break;
155: default:
156: printf("Unknown %#x", map_type);
157: break;
158: }
159: }
160:
161: static int
1.39 kre 162: show(gpt_t gpt, int xshow)
1.32 martin 163: {
164: map_t m;
165:
1.24 christos 166: printf(" %*s", gpt->lbawidth, "start");
167: printf(" %*s", gpt->lbawidth, "size");
1.1 christos 168: printf(" index contents\n");
169:
1.24 christos 170: m = map_first(gpt);
1.1 christos 171: while (m != NULL) {
1.24 christos 172: printf(" %*llu", gpt->lbawidth, (long long)m->map_start);
173: printf(" %*llu", gpt->lbawidth, (long long)m->map_size);
1.1 christos 174: putchar(' ');
175: putchar(' ');
176: if (m->map_index > 0)
177: printf("%5d", m->map_index);
178: else
179: printf(" ");
180: putchar(' ');
181: putchar(' ');
1.39 kre 182: print_part_type(m->map_type, xshow, m->map_data, m->map_start);
1.1 christos 183: putchar('\n');
184: m = m->map_next;
185: }
1.24 christos 186: return 0;
1.1 christos 187: }
188:
1.24 christos 189: static int
1.28 christos 190: show_one(gpt_t gpt, unsigned int entry)
1.12 jnemeth 191: {
1.24 christos 192: map_t m;
1.12 jnemeth 193: struct gpt_ent *ent;
1.19 christos 194: char s1[128], s2[128];
1.27 christos 195: uint8_t utfbuf[__arraycount(ent->ent_name) * 3 + 1];
1.12 jnemeth 196:
1.24 christos 197: for (m = map_first(gpt); m != NULL; m = m->map_next)
1.12 jnemeth 198: if (entry == m->map_index)
199: break;
200: if (m == NULL) {
1.24 christos 201: gpt_warnx(gpt, "Could not find index %d", entry);
202: return -1;
1.12 jnemeth 203: }
204: ent = m->map_data;
205:
206: printf("Details for index %d:\n", entry);
1.29 christos 207: gpt_show_num("Start", (uintmax_t)(m->map_start * gpt->secsz));
208: gpt_show_num("Size", (uintmax_t)(m->map_size * gpt->secsz));
1.12 jnemeth 209:
1.19 christos 210: gpt_uuid_snprintf(s1, sizeof(s1), "%s", ent->ent_type);
1.20 jnemeth 211: gpt_uuid_snprintf(s2, sizeof(s2), "%d", ent->ent_type);
1.12 jnemeth 212: if (strcmp(s1, s2) == 0)
1.19 christos 213: strlcpy(s1, "unknown", sizeof(s1));
1.12 jnemeth 214: printf("Type: %s (%s)\n", s1, s2);
215:
1.19 christos 216: gpt_uuid_snprintf(s2, sizeof(s1), "%d", ent->ent_guid);
1.12 jnemeth 217: printf("GUID: %s\n", s2);
218:
1.41 ! christos 219: utf16_to_utf8(ent->ent_name, __arraycount(ent->ent_name), utfbuf,
! 220: __arraycount(utfbuf));
1.27 christos 221: printf("Label: %s\n", (char *)utfbuf);
1.12 jnemeth 222:
1.31 christos 223: printf("Attributes: ");
1.28 christos 224: if (ent->ent_attr == 0) {
1.31 christos 225: printf("None\n");
226: } else {
227: char buf[1024];
228: printf("%s\n", gpt_attr_list(buf, sizeof(buf), ent->ent_attr));
1.12 jnemeth 229: }
1.31 christos 230:
1.24 christos 231: return 0;
1.12 jnemeth 232: }
233:
1.25 christos 234: static int
1.32 martin 235: show_all(gpt_t gpt)
236: {
237: map_t m;
238: struct gpt_ent *ent;
239: char s1[128], s2[128];
1.34 martin 240: #ifdef HN_AUTOSCALE
241: char human_num[8];
242: #endif
1.32 martin 243: uint8_t utfbuf[__arraycount(ent->ent_name) * 3 + 1];
244: #define PFX " "
245:
246: printf(" %*s", gpt->lbawidth, "start");
247: printf(" %*s", gpt->lbawidth, "size");
248: printf(" index contents\n");
249:
250: m = map_first(gpt);
251: while (m != NULL) {
252: printf(" %*llu", gpt->lbawidth, (long long)m->map_start);
253: printf(" %*llu", gpt->lbawidth, (long long)m->map_size);
254: putchar(' ');
255: putchar(' ');
256: if (m->map_index > 0) {
257: printf("%5d ", m->map_index);
258: print_part_type(m->map_type, 0, m->map_data,
259: m->map_start);
260: putchar('\n');
261:
262: ent = m->map_data;
263:
264: gpt_uuid_snprintf(s1, sizeof(s1), "%s", ent->ent_type);
265: gpt_uuid_snprintf(s2, sizeof(s2), "%d", ent->ent_type);
266: if (strcmp(s1, s2) == 0)
267: strlcpy(s1, "unknown", sizeof(s1));
1.34 martin 268: printf(PFX "Type: %s\n", s1);
269: printf(PFX "TypeID: %s\n", s2);
1.32 martin 270:
271: gpt_uuid_snprintf(s2, sizeof(s1), "%d", ent->ent_guid);
272: printf(PFX "GUID: %s\n", s2);
273:
1.34 martin 274: printf(PFX "Size: ");
275: #ifdef HN_AUTOSCALE
276: if (humanize_number(human_num, sizeof(human_num),
277: (int64_t)(m->map_size * gpt->secsz),
278: "", HN_AUTOSCALE, HN_B) < 0) {
279: #endif
280: printf("%ju",
281: (int64_t)(m->map_size * gpt->secsz));
282: #ifdef HN_AUTOSCALE
283: } else {
284: printf("%s", human_num);
285: }
286: #endif
287: putchar('\n');
288:
1.41 ! christos 289: utf16_to_utf8(ent->ent_name,
! 290: __arraycount(ent->ent_name), utfbuf,
! 291: __arraycount(utfbuf));
1.32 martin 292: printf(PFX "Label: %s\n", (char *)utfbuf);
293:
294: printf(PFX "Attributes: ");
295: if (ent->ent_attr == 0) {
296: printf("None\n");
297: } else {
298: char buf[1024];
299:
300: printf("%s\n", gpt_attr_list(buf, sizeof(buf),
301: ent->ent_attr));
302: }
303: } else {
304: printf(" ");
305: print_part_type(m->map_type, 0, m->map_data,
306: m->map_start);
307: putchar('\n');
308: }
309: m = m->map_next;
310: }
311: return 0;
312: }
313:
314: static int
1.24 christos 315: cmd_show(gpt_t gpt, int argc, char *argv[])
1.1 christos 316: {
1.24 christos 317: int ch;
1.28 christos 318: int xshow = 0;
319: unsigned int entry = 0;
1.1 christos 320:
1.32 martin 321: while ((ch = getopt(argc, argv, "gi:lua")) != -1) {
1.1 christos 322: switch(ch) {
1.32 martin 323: case 'a':
324: xshow |= SHOW_ALL;
325: break;
1.12 jnemeth 326: case 'g':
1.28 christos 327: xshow |= SHOW_GUID;
1.12 jnemeth 328: break;
329: case 'i':
1.35 christos 330: if (gpt_uint_get(gpt, &entry) == -1)
1.25 christos 331: return usage();
1.12 jnemeth 332: break;
1.1 christos 333: case 'l':
1.28 christos 334: xshow |= SHOW_LABEL;
1.1 christos 335: break;
336: case 'u':
1.28 christos 337: xshow |= SHOW_UUID;
1.1 christos 338: break;
339: default:
1.25 christos 340: return usage();
1.1 christos 341: }
342: }
343:
1.24 christos 344: if (argc != optind)
1.25 christos 345: return usage();
1.1 christos 346:
1.32 martin 347: if (xshow & SHOW_ALL)
348: return show_all(gpt);
349:
1.28 christos 350: return entry > 0 ? show_one(gpt, entry) : show(gpt, xshow);
1.1 christos 351: }
CVSweb <webmaster@jp.NetBSD.org>