Bring the gpt labeling program in from FreeBSD.
[dragonfly.git] / sbin / gpt / show.c
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  * $FreeBSD: src/sbin/gpt/show.c,v 1.14 2006/06/22 22:22:32 marcel Exp $
27  * $DragonFly: src/sbin/gpt/show.c,v 1.1 2007/06/16 22:29:27 dillon Exp $
28  */
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
42 static int show_label = 0;
43 static int show_uuid = 0;
44
45 static void
46 usage_show(void)
47 {
48
49         fprintf(stderr,
50             "usage: %s [-lu] device ...\n", getprogname());
51         exit(1);
52 }
53
54 static const char *
55 friendly(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
92 unfriendly:
93         uuid_to_string(t, &s, NULL);
94         strlcpy(buf, s, sizeof buf);
95         free(s);
96         return (buf);
97 }
98
99 static void
100 show(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
178 int
179 cmd_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 }