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