show.c revision 1.1
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#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: src/sbin/gpt/show.c,v 1.14 2006/06/22 22:22:32 marcel Exp $");
29
30#include <sys/types.h>
31
32#include <err.h>
33#include <stddef.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <unistd.h>
38
39#include "map.h"
40#include "gpt.h"
41
42static int show_label = 0;
43static int show_uuid = 0;
44
45static void
46usage_show(void)
47{
48
49	fprintf(stderr,
50	    "usage: %s [-lu] device ...\n", getprogname());
51	exit(1);
52}
53
54static const char *
55friendly(uuid_t *t)
56{
57	static uuid_t efi_slice = GPT_ENT_TYPE_EFI;
58	static uuid_t mslinux = GPT_ENT_TYPE_MS_BASIC_DATA;
59	static uuid_t freebsd = GPT_ENT_TYPE_FREEBSD;
60	static uuid_t hfs = GPT_ENT_TYPE_APPLE_HFS;
61	static uuid_t linuxswap = GPT_ENT_TYPE_LINUX_SWAP;
62	static uuid_t msr = GPT_ENT_TYPE_MS_RESERVED;
63	static uuid_t swap = GPT_ENT_TYPE_FREEBSD_SWAP;
64	static uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;
65	static uuid_t vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
66	static char buf[80];
67	char *s;
68
69	if (show_uuid)
70		goto unfriendly;
71
72	if (uuid_equal(t, &efi_slice, NULL))
73		return ("EFI System");
74	if (uuid_equal(t, &swap, NULL))
75		return ("FreeBSD swap");
76	if (uuid_equal(t, &ufs, NULL))
77		return ("FreeBSD UFS/UFS2");
78	if (uuid_equal(t, &vinum, NULL))
79		return ("FreeBSD vinum");
80
81	if (uuid_equal(t, &freebsd, NULL))
82		return ("FreeBSD legacy");
83	if (uuid_equal(t, &mslinux, NULL))
84		return ("Linux/Windows");
85	if (uuid_equal(t, &linuxswap, NULL))
86		return ("Linux swap");
87	if (uuid_equal(t, &msr, NULL))
88		return ("Windows reserved");
89	if (uuid_equal(t, &hfs, NULL))
90		return ("Apple HFS");
91
92unfriendly:
93	uuid_to_string(t, &s, NULL);
94	strlcpy(buf, s, sizeof buf);
95	free(s);
96	return (buf);
97}
98
99static void
100show(int fd __unused)
101{
102	uuid_t type;
103	off_t start;
104	map_t *m, *p;
105	struct mbr *mbr;
106	struct gpt_ent *ent;
107	unsigned int i;
108
109	printf("  %*s", lbawidth, "start");
110	printf("  %*s", lbawidth, "size");
111	printf("  index  contents\n");
112
113	m = map_first();
114	while (m != NULL) {
115		printf("  %*llu", lbawidth, (long long)m->map_start);
116		printf("  %*llu", lbawidth, (long long)m->map_size);
117		putchar(' ');
118		putchar(' ');
119		if (m->map_index > 0)
120			printf("%5d", m->map_index);
121		else
122			printf("     ");
123		putchar(' ');
124		putchar(' ');
125		switch (m->map_type) {
126		case MAP_TYPE_MBR:
127			if (m->map_start != 0)
128				printf("Extended ");
129			printf("MBR");
130			break;
131		case MAP_TYPE_PRI_GPT_HDR:
132			printf("Pri GPT header");
133			break;
134		case MAP_TYPE_SEC_GPT_HDR:
135			printf("Sec GPT header");
136			break;
137		case MAP_TYPE_PRI_GPT_TBL:
138			printf("Pri GPT table");
139			break;
140		case MAP_TYPE_SEC_GPT_TBL:
141			printf("Sec GPT table");
142			break;
143		case MAP_TYPE_MBR_PART:
144			p = m->map_data;
145			if (p->map_start != 0)
146				printf("Extended ");
147			printf("MBR part ");
148			mbr = p->map_data;
149			for (i = 0; i < 4; i++) {
150				start = le16toh(mbr->mbr_part[i].part_start_hi);
151				start = (start << 16) +
152				    le16toh(mbr->mbr_part[i].part_start_lo);
153				if (m->map_start == p->map_start + start)
154					break;
155			}
156			printf("%d", mbr->mbr_part[i].part_typ);
157			break;
158		case MAP_TYPE_GPT_PART:
159			printf("GPT part ");
160			ent = m->map_data;
161			if (show_label) {
162				printf("- \"%s\"",
163				    utf16_to_utf8(ent->ent_name));
164			} else {
165				le_uuid_dec(&ent->ent_type, &type);
166				printf("- %s", friendly(&type));
167			}
168			break;
169		case MAP_TYPE_PMBR:
170			printf("PMBR");
171			break;
172		}
173		putchar('\n');
174		m = m->map_next;
175	}
176}
177
178int
179cmd_show(int argc, char *argv[])
180{
181	int ch, fd;
182
183	while ((ch = getopt(argc, argv, "lu")) != -1) {
184		switch(ch) {
185		case 'l':
186			show_label = 1;
187			break;
188		case 'u':
189			show_uuid = 1;
190			break;
191		default:
192			usage_show();
193		}
194	}
195
196	if (argc == optind)
197		usage_show();
198
199	while (optind < argc) {
200		fd = gpt_open(argv[optind++]);
201		if (fd == -1) {
202			warn("unable to open device '%s'", device_name);
203			continue;
204		}
205
206		show(fd);
207
208		gpt_close(fd);
209	}
210
211	return (0);
212}
213