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