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