Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: cgpt/cmd_show.c

Issue 2719008: Nearly complete rewrite of cgpt tool. (Closed) Base URL: ssh://git@chromiumos-git//vboot_reference.git
Patch Set: Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cgpt/cmd_repair.c ('k') | cgpt/endian.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cgpt.h"
6
7 #define __STDC_FORMAT_MACROS
8 #include <getopt.h>
9 #include <inttypes.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "cgptlib_internal.h"
15
16 static void Usage(void)
17 {
18 printf("\nUsage: %s show [OPTIONS] DRIVE\n\n"
19 "Display the GPT table\n\n"
20 "Options:\n"
21 " -n Numeric output only\n"
22 " -v Verbose output\n"
23 " -q Quick output\n"
24 " -i NUM Show specified partition only - pick one of:\n"
25 " -b beginning sector\n"
26 " -s partition size\n"
27 " -t type guid\n"
28 " -u unique guid\n"
29 " -l label\n"
30 " -S Successful flag\n"
31 " -T Tries flag\n"
32 " -P Priority flag\n"
33 " -A raw 64-bit attribute value\n"
34 "\n", progname);
35 }
36
37
38 /* Generate output like:
39 *
40 * [AB-CD-EF-01] for group = 1
41 * [ABCD-EF01] for group = 3 (low byte first)
42 *
43 * Needs (size*3-1+3) bytes of space in 'buf' (included the tailing '\0').
44 */
45 #define BUFFER_SIZE(size) (size *3 - 1 + 3)
46 static short Uint8To2Chars(const uint8_t t) {
47 int h = t >> 4;
48 int l = t & 0xf;
49 h = (h >= 0xA) ? h - 0xA + 'A' : h + '0';
50 l = (l >= 0xA) ? l - 0xA + 'A' : l + '0';
51 return (h << 8) + l;
52 }
53 static void RawDump(const uint8_t *memory, const int size,
54 char *buf, int group) {
55 int i, outlen = 0;
56 buf[outlen++] = '[';
57 for (i = 0; i < size; ++i) {
58 short c2 = Uint8To2Chars(memory[i]);
59 buf[outlen++] = c2 >> 8;
60 buf[outlen++] = c2 & 0xff;
61 if (i != (size - 1) && ((i + 1) % group) == 0)
62 buf[outlen++] = '-';
63 }
64 buf[outlen++] = ']';
65 buf[outlen++] = '\0';
66 }
67
68 /* Output formatters */
69
70
71
72 #define TITLE_FMT "%10s%10s%8s %s\n"
73 #define GPT_FMT "%10d%10d%8s %s\n"
74 #define GPT_MORE "%10s%10s%8s ", "", "", ""
75 #define PARTITION_FMT "%10d%10d%8d %s\n"
76 #define PARTITION_MORE "%10s%10s%8s %s%s\n", "", "", ""
77
78 static void HeaderDetails(GptHeader *header, const char *indent, int raw) {
79 int i;
80
81 printf("%sSig: ", indent);
82 if (!raw) {
83 printf("[");
84 for (i = 0; i < sizeof(header->signature); ++i)
85 printf("%c", header->signature[i]);
86 printf("]");
87 } else {
88 char buf[BUFFER_SIZE(sizeof(header->signature))];
89 RawDump((uint8_t *)header->signature, sizeof(header->signature), buf, 1);
90 printf("%s", buf);
91 }
92 printf("\n");
93
94 printf("%sRev: 0x%08x\n", indent, header->revision);
95 printf("%sSize: %d\n", indent, header->size);
96 printf("%sHeader CRC: 0x%08x\n", indent, header->header_crc32);
97 printf("%sMy LBA: %lld\n", indent, (long long)header->my_lba);
98 printf("%sFirst LBA: %lld\n", indent, (long long)header->first_usable_lba);
99 printf("%sLast LBA: %lld\n", indent, (long long)header->last_usable_lba);
100
101 { /* For disk guid */
102 char buf[GUID_STRLEN];
103 GuidToStr(&header->disk_uuid, buf);
104 printf("%sDisk UUID: %s\n", indent, buf);
105 }
106
107 printf("%sEntries LBA: %lld\n", indent, (long long)header->entries_lba);
108 printf("%sNumber of entries: %d\n", indent, header->number_of_entries);
109 printf("%sSize of entry: %d\n", indent, header->size_of_entry);
110 printf("%sEntries CRC: 0x%08x\n", indent, header->entries_crc32);
111 }
112
113 void EntryDetails(GptEntry *entry, int index, int raw) {
114 char contents[256];
115 uint8_t label[sizeof(entry->name) * 3 / 2];
116
117 if (!raw) {
118 char type[GUID_STRLEN], unique[GUID_STRLEN];;
119
120 UTF16ToUTF8(entry->name, label);
121 snprintf(contents, sizeof(contents), "Label: \"%s\"", label);
122 printf(PARTITION_FMT, (int)entry->starting_lba,
123 (int)(entry->ending_lba - entry->starting_lba + 1),
124 index+1, contents);
125 if (CGPT_OK == ResolveType(&entry->type, type)) {
126 printf(PARTITION_MORE, "Type: ", type);
127 } else {
128 GuidToStr(&entry->type, type);
129 printf(PARTITION_MORE, "Type: ", type);
130 }
131 GuidToStr(&entry->unique, unique);
132 printf(PARTITION_MORE, "UUID: ", unique);
133 if (!memcmp(&guid_chromeos_kernel, &entry->type, sizeof(Guid))) {
134 int tries = (entry->attributes & CGPT_ATTRIBUTE_TRIES_MASK) >>
135 CGPT_ATTRIBUTE_TRIES_OFFSET;
136 int successful = (entry->attributes & CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
137 CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
138 int priority = (entry->attributes & CGPT_ATTRIBUTE_PRIORITY_MASK) >>
139 CGPT_ATTRIBUTE_PRIORITY_OFFSET;
140 snprintf(contents, sizeof(contents),
141 "priority=%d tries=%d successful=%d",
142 priority, tries, successful);
143 printf(PARTITION_MORE, "Attr: ", contents);
144 }
145 } else {
146 char type[GUID_STRLEN], unique[GUID_STRLEN];
147
148 UTF16ToUTF8(entry->name, label);
149 snprintf(contents, sizeof(contents), "Label: \"%s\"", label);
150 printf(PARTITION_FMT, (int)entry->starting_lba,
151 (int)(entry->ending_lba - entry->starting_lba + 1),
152 index+1, contents);
153 GuidToStr(&entry->type, type);
154 printf(PARTITION_MORE, "Type: ", type);
155 GuidToStr(&entry->unique, unique);
156 printf(PARTITION_MORE, "UUID: ", unique);
157 snprintf(contents, sizeof(contents), "[%" PRIx64 "]", entry->attributes);
158 printf(PARTITION_MORE, "Attr: ", contents);
159 }
160 }
161
162
163 void EntriesDetails(GptData *gpt, const int secondary, int raw) {
164 int i;
165
166 for (i = 0; i < GetNumberOfEntries(gpt); ++i) {
167 GptEntry *entry;
168 entry = GetEntry(gpt, secondary, i);
169
170 if (!memcmp(&guid_unused, &entry->type, sizeof(Guid))) continue;
171
172 EntryDetails(entry, i, raw);
173 }
174 }
175
176 int cmd_show(int argc, char *argv[]) {
177 struct drive drive;
178 int numeric = 0;
179 int verbose = 0;
180 int quick = 0;
181 int partition = 0;
182 int single_item = 0;
183 int gpt_retval;
184
185 int c;
186 int errorcnt = 0;
187 char *e = 0;
188
189 opterr = 0; // quiet, you
190 while ((c=getopt(argc, argv, ":hnvqi:bstulSTPA")) != -1)
191 {
192 switch (c)
193 {
194 case 'n':
195 numeric = 1;
196 break;
197 case 'v':
198 verbose = 1;
199 break;
200 case 'q':
201 quick = 1;
202 break;
203 case 'i':
204 partition = (uint32_t)strtoul(optarg, &e, 0);
205 if (!*optarg || (e && *e))
206 {
207 Error("invalid argument to -%c: \"%s\"\n", c, optarg);
208 errorcnt++;
209 }
210 break;
211 case 'b':
212 case 's':
213 case 't':
214 case 'u':
215 case 'l':
216 case 'S':
217 case 'T':
218 case 'P':
219 case 'A':
220 single_item = c;
221 break;
222
223 case 'h':
224 Usage();
225 return CGPT_OK;
226 case '?':
227 Error("unrecognized option: -%c\n", optopt);
228 errorcnt++;
229 break;
230 case ':':
231 Error("missing argument to -%c\n", optopt);
232 errorcnt++;
233 break;
234 default:
235 errorcnt++;
236 break;
237 }
238 }
239 if (errorcnt)
240 {
241 Usage();
242 return CGPT_FAILED;
243 }
244
245 if (optind >= argc) {
246 Error("missing drive argument\n");
247 Usage();
248 return CGPT_FAILED;
249 }
250
251 if (CGPT_OK != DriveOpen(argv[optind], &drive))
252 return CGPT_FAILED;
253
254 if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) {
255 Error("GptSanityCheck() returned %d: %s\n",
256 gpt_retval, GptError(gpt_retval));
257 return CGPT_FAILED;
258 }
259
260 if (partition) { // show single partition
261
262 if (partition > GetNumberOfEntries(&drive.gpt)) {
263 Error("invalid partition number: %d\n", partition);
264 return CGPT_FAILED;
265 }
266
267 int index = partition - 1;
268 GptEntry *entry = GetEntry(&drive.gpt, PRIMARY, index);
269 char buf[256];
270
271 if (single_item) {
272 switch(single_item) {
273 case 'b':
274 printf("%" PRId64 "\n", entry->starting_lba);
275 break;
276 case 's':
277 printf("%" PRId64 "\n", entry->ending_lba - entry->starting_lba + 1);
278 break;
279 case 't':
280 GuidToStr(&entry->type, buf);
281 printf("%s\n", buf);
282 break;
283 case 'u':
284 GuidToStr(&entry->unique, buf);
285 printf("%s\n", buf);
286 break;
287 case 'l':
288 UTF16ToUTF8(entry->name, (uint8_t *)buf);
289 printf("%s\n", buf);
290 break;
291 case 'S':
292 printf("%d\n", GetSuccessful(&drive.gpt, PRIMARY, index));
293 break;
294 case 'T':
295 printf("%d\n", GetTries(&drive.gpt, PRIMARY, index));
296 break;
297 case 'P':
298 printf("%d\n", GetPriority(&drive.gpt, PRIMARY, index));
299 break;
300 case 'A':
301 printf("0x%" PRIx64 "\n", entry->attributes);
302 break;
303 }
304 } else {
305 printf(TITLE_FMT, "start", "size", "part", "contents");
306 EntryDetails(entry, index, numeric);
307 }
308
309 } else if (quick) { // show all partitions, quickly
310 int i;
311 GptEntry *entry;
312 char type[GUID_STRLEN];
313
314 for (i = 0; i < GetNumberOfEntries(&drive.gpt); ++i) {
315 entry = GetEntry(&drive.gpt, PRIMARY, i);
316
317 if (IsZero(&entry->type))
318 continue;
319
320 if (!numeric && CGPT_OK == ResolveType(&entry->type, type)) {
321 } else {
322 GuidToStr(&entry->type, type);
323 }
324 printf(PARTITION_FMT, (int)entry->starting_lba,
325 (int)(entry->ending_lba - entry->starting_lba + 1),
326 i+1, type);
327 }
328
329 } else { // show all partitions
330
331 if (CGPT_OK != ReadPMBR(&drive)) {
332 Error("Unable to read PMBR\n");
333 return CGPT_FAILED;
334 }
335
336 printf(TITLE_FMT, "start", "size", "part", "contents");
337 char buf[256];
338 PMBRToStr(&drive.pmbr, buf);
339 printf(GPT_FMT, 0, GPT_PMBR_SECTOR, "", buf);
340
341 if (drive.gpt.valid_headers & MASK_PRIMARY) {
342 printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
343 (int)GPT_HEADER_SECTOR, "", "Pri GPT header");
344 if (verbose) {
345 GptHeader *header;
346 char indent[64];
347
348 snprintf(indent, sizeof(indent), GPT_MORE);
349 header = (GptHeader*)drive.gpt.primary_header;
350 HeaderDetails(header, indent, numeric);
351 }
352 } else {
353 printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
354 (int)GPT_HEADER_SECTOR, "INVALID", "Pri GPT header");
355 }
356
357 printf(GPT_FMT, (int)(GPT_PMBR_SECTOR + GPT_HEADER_SECTOR),
358 (int)GPT_ENTRIES_SECTORS,
359 drive.gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
360 "Pri GPT table");
361
362 if (drive.gpt.valid_entries & MASK_PRIMARY)
363 EntriesDetails(&drive.gpt, PRIMARY, numeric);
364
365 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR -
366 GPT_ENTRIES_SECTORS),
367 (int)GPT_ENTRIES_SECTORS,
368 drive.gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
369 "Sec GPT table");
370 /* We show secondary table details if any of following is true.
371 * 1. only secondary is valid.
372 * 2. secondary is not identical to promary.
373 */
374 if ((drive.gpt.valid_entries & MASK_SECONDARY) &&
375 (!(drive.gpt.valid_entries & MASK_PRIMARY) ||
376 memcmp(drive.gpt.primary_entries, drive.gpt.secondary_entries,
377 TOTAL_ENTRIES_SIZE))) {
378 EntriesDetails(&drive.gpt, SECONDARY, numeric);
379 }
380
381 if (drive.gpt.valid_headers & MASK_SECONDARY)
382 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR),
383 (int)GPT_HEADER_SECTOR, "", "Sec GPT header");
384 else
385 printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
386 (int)GPT_HEADER_SECTOR, "INVALID", "Sec GPT header");
387 /* We show secondary header if any of following is true:
388 * 1. only secondary is valid.
389 * 2. secondary is not synonymous to primary.
390 */
391 if ((drive.gpt.valid_headers & MASK_SECONDARY) &&
392 (!(drive.gpt.valid_headers & MASK_PRIMARY) ||
393 !IsSynonymous((GptHeader*)drive.gpt.primary_header,
394 (GptHeader*)drive.gpt.secondary_header))) {
395 if (verbose) {
396 GptHeader *header;
397 char indent[64];
398
399 snprintf(indent, sizeof(indent), GPT_MORE);
400 header = (GptHeader*)drive.gpt.secondary_header;
401 HeaderDetails(header, indent, numeric);
402 }
403 }
404 }
405
406 (void) CheckValid(&drive);
407 (void) DriveClose(&drive, 0);
408
409 return CGPT_OK;
410 }
411
412
413
OLDNEW
« no previous file with comments | « cgpt/cmd_repair.c ('k') | cgpt/endian.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698