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