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 if (i == 4) { 139 /* wasn't there */ 140 printf("[partition not found?]"); 141 } else { 142 printf("%d%s", mbr->mbr_part[i].part_typ, 143 mbr->mbr_part[i].part_flag == 0x80 ? 144 " (active)" : ""); 145 } 146 break; 147 case MAP_TYPE_GPT_PART: 148 printf("GPT part "); 149 ent = m->map_data; 150 if (show_label) { 151 printf("- \"%s\"", 152 utf16_to_utf8(ent->ent_name)); 153 } else if (show_guid) { 154 s = NULL; 155 le_uuid_dec(&ent->ent_uuid, &guid); 156 uuid_to_string(&guid, &s, NULL); 157 printf("- %s", s); 158 free(s); 159 s = NULL; 160 } else { 161 le_uuid_dec(&ent->ent_type, &type); 162 printf("- %s", friendly(&type)); 163 } 164 break; 165 case MAP_TYPE_PMBR: 166 printf("PMBR"); 167 mbr = m->map_data; 168 if (mbr->mbr_part[0].part_typ == DOSPTYP_PMBR && 169 mbr->mbr_part[0].part_flag == 0x80) 170 printf(" (active)"); 171 break; 172 default: 173 printf("Unknown %#x", m->map_type); 174 break; 175 } 176 putchar('\n'); 177 m = m->map_next; 178 } 179 } 180 181 int 182 cmd_show(int argc, char *argv[]) 183 { 184 int ch, fd; 185 186 while ((ch = getopt(argc, argv, "glu")) != -1) { 187 switch(ch) { 188 case 'g': 189 show_guid = true; 190 break; 191 case 'l': 192 show_label = true; 193 break; 194 case 'u': 195 show_uuid = true; 196 break; 197 default: 198 usage_show(); 199 } 200 } 201 202 if (argc == optind) 203 usage_show(); 204 205 while (optind < argc) { 206 fd = gpt_open(argv[optind++]); 207 if (fd == -1) { 208 warn("unable to open device '%s'", device_name); 209 continue; 210 } 211 212 show(fd); 213 214 gpt_close(fd); 215 } 216 217 return (0); 218 } 219