/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include "cgpt.h" #include "vboot_host.h" extern const char* progname; static void Usage(void) { printf("\nUsage: %s find [OPTIONS] [DRIVE]\n\n" "Find a partition by its UUID or label. With no specified DRIVE\n" "it scans all physical drives.\n\n" "Options:\n" " -D NUM Size (in bytes) of the disk where partitions reside\n" " default 0, meaning partitions and GPT structs are\n" " both on DRIVE\n" " -t GUID Search for Partition Type GUID\n" " -u GUID Search for Partition Unique ID\n" " -l LABEL Search for Label\n" " -v Be verbose in displaying matches (repeatable)\n" " -n Numeric output only\n" " -1 Fail if more than one match is found\n" " -M FILE" " Matching partition data must also contain FILE content\n" " -O NUM" " Byte offset into partition to match content (default 0)\n" "\n", progname); PrintTypes(); } // read a file into a buffer, return buffer and update size static uint8_t *ReadFile(const char *filename, uint64_t *size) { FILE *f; uint8_t *buf; long pos; f = fopen(filename, "rb"); if (!f) { return NULL; } fseek(f, 0, SEEK_END); pos = ftell(f); if (pos < 0) { fclose(f); return NULL; } *size = pos; rewind(f); buf = malloc(*size); if (!buf) { fclose(f); return NULL; } if(1 != fread(buf, *size, 1, f)) { fclose(f); free(buf); return NULL; } fclose(f); return buf; } int cmd_find(int argc, char *argv[]) { CgptFindParams params; memset(¶ms, 0, sizeof(params)); int i; int errorcnt = 0; char *e = 0; int c; opterr = 0; // quiet, you while ((c=getopt(argc, argv, ":hv1nt:u:l:M:O:D:")) != -1) { switch (c) { case 'D': params.drive_size = strtoull(optarg, &e, 0); errorcnt += check_int_parse(c, e); break; case 'v': params.verbose++; break; case 'n': params.numeric = 1; break; case '1': params.oneonly = 1; break; case 'l': params.set_label = 1; params.label = optarg; break; case 't': params.set_type = 1; if (CGPT_OK != SupportedType(optarg, ¶ms.type_guid) && CGPT_OK != StrToGuid(optarg, ¶ms.type_guid)) { Error("invalid argument to -%c: %s\n", c, optarg); errorcnt++; } break; case 'u': params.set_unique = 1; if (CGPT_OK != StrToGuid(optarg, ¶ms.unique_guid)) { Error("invalid argument to -%c: %s\n", c, optarg); errorcnt++; } break; case 'M': params.matchbuf = ReadFile(optarg, ¶ms.matchlen); if (!params.matchbuf || !params.matchlen) { Error("Unable to read from %s\n", optarg); errorcnt++; } // Go ahead and allocate space for the comparison too params.comparebuf = (uint8_t *)malloc(params.matchlen); if (!params.comparebuf) { Error("Unable to allocate %" PRIu64 "bytes for comparison buffer\n", params.matchlen); errorcnt++; } break; case 'O': params.matchoffset = strtoull(optarg, &e, 0); errorcnt += check_int_parse(c, e); break; case 'h': Usage(); return CGPT_OK; case '?': Error("unrecognized option: -%c\n", optopt); errorcnt++; break; case ':': Error("missing argument to -%c\n", optopt); errorcnt++; break; default: errorcnt++; break; } } if (!params.set_unique && !params.set_type && !params.set_label) { Error("You must specify at least one of -t, -u, or -l\n"); errorcnt++; } if (errorcnt) { Usage(); return CGPT_FAILED; } if (optind < argc) { for (i=optind; i