1// Copyright (c) 2012 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 <getopt.h> 6#include <string.h> 7 8#include "cgpt.h" 9#include "vboot_host.h" 10 11extern const char* progname; 12 13static void Usage(void) 14{ 15 printf("\nUsage: %s find [OPTIONS] [DRIVE]\n\n" 16 "Find a partition by its UUID or label. With no specified DRIVE\n" 17 "it scans all physical drives.\n\n" 18 "Options:\n" 19 " -D NUM Size (in bytes) of the disk where partitions reside\n" 20 " default 0, meaning partitions and GPT structs are\n" 21 " both on DRIVE\n" 22 " -t GUID Search for Partition Type GUID\n" 23 " -u GUID Search for Partition Unique ID\n" 24 " -l LABEL Search for Label\n" 25 " -v Be verbose in displaying matches (repeatable)\n" 26 " -n Numeric output only\n" 27 " -1 Fail if more than one match is found\n" 28 " -M FILE" 29 " Matching partition data must also contain FILE content\n" 30 " -O NUM" 31 " Byte offset into partition to match content (default 0)\n" 32 "\n", progname); 33 PrintTypes(); 34} 35 36// read a file into a buffer, return buffer and update size 37static uint8_t *ReadFile(const char *filename, uint64_t *size) { 38 FILE *f; 39 uint8_t *buf; 40 41 f = fopen(filename, "rb"); 42 if (!f) { 43 return NULL; 44 } 45 46 fseek(f, 0, SEEK_END); 47 *size = ftell(f); 48 rewind(f); 49 50 buf = malloc(*size); 51 if (!buf) { 52 fclose(f); 53 return NULL; 54 } 55 56 if(1 != fread(buf, *size, 1, f)) { 57 fclose(f); 58 free(buf); 59 return NULL; 60 } 61 62 fclose(f); 63 return buf; 64} 65 66int cmd_find(int argc, char *argv[]) { 67 68 CgptFindParams params; 69 memset(¶ms, 0, sizeof(params)); 70 71 int i; 72 int errorcnt = 0; 73 char *e = 0; 74 int c; 75 76 opterr = 0; // quiet, you 77 while ((c=getopt(argc, argv, ":hv1nt:u:l:M:O:D:")) != -1) 78 { 79 switch (c) 80 { 81 case 'D': 82 params.drive_size = strtoull(optarg, &e, 0); 83 if (!*optarg || (e && *e)) 84 { 85 Error("invalid argument to -%c: \"%s\"\n", c, optarg); 86 errorcnt++; 87 } 88 break; 89 case 'v': 90 params.verbose++; 91 break; 92 case 'n': 93 params.numeric = 1; 94 break; 95 case '1': 96 params.oneonly = 1; 97 break; 98 case 'l': 99 params.set_label = 1; 100 params.label = optarg; 101 break; 102 case 't': 103 params.set_type = 1; 104 if (CGPT_OK != SupportedType(optarg, ¶ms.type_guid) && 105 CGPT_OK != StrToGuid(optarg, ¶ms.type_guid)) { 106 Error("invalid argument to -%c: %s\n", c, optarg); 107 errorcnt++; 108 } 109 break; 110 case 'u': 111 params.set_unique = 1; 112 if (CGPT_OK != StrToGuid(optarg, ¶ms.unique_guid)) { 113 Error("invalid argument to -%c: %s\n", c, optarg); 114 errorcnt++; 115 } 116 break; 117 case 'M': 118 params.matchbuf = ReadFile(optarg, ¶ms.matchlen); 119 if (!params.matchbuf || !params.matchlen) { 120 Error("Unable to read from %s\n", optarg); 121 errorcnt++; 122 } 123 // Go ahead and allocate space for the comparison too 124 params.comparebuf = (uint8_t *)malloc(params.matchlen); 125 if (!params.comparebuf) { 126 Error("Unable to allocate %" PRIu64 "bytes for comparison buffer\n", 127 params.matchlen); 128 errorcnt++; 129 } 130 break; 131 case 'O': 132 params.matchoffset = strtoull(optarg, &e, 0); 133 if (!*optarg || (e && *e)) { 134 Error("invalid argument to -%c: \"%s\"\n", c, optarg); 135 errorcnt++; 136 } 137 break; 138 139 case 'h': 140 Usage(); 141 return CGPT_OK; 142 case '?': 143 Error("unrecognized option: -%c\n", optopt); 144 errorcnt++; 145 break; 146 case ':': 147 Error("missing argument to -%c\n", optopt); 148 errorcnt++; 149 break; 150 default: 151 errorcnt++; 152 break; 153 } 154 } 155 if (!params.set_unique && !params.set_type && !params.set_label) { 156 Error("You must specify at least one of -t, -u, or -l\n"); 157 errorcnt++; 158 } 159 if (errorcnt) 160 { 161 Usage(); 162 return CGPT_FAILED; 163 } 164 165 if (optind < argc) { 166 for (i=optind; i<argc; i++) { 167 params.drive_name = argv[i]; 168 CgptFind(¶ms); 169 } 170 } else { 171 CgptFind(¶ms); 172 } 173 174 if (params.oneonly && params.hits != 1) { 175 return CGPT_FAILED; 176 } 177 178 if (params.match_partnum) { 179 return CGPT_OK; 180 } 181 182 return CGPT_FAILED; 183} 184