Home | History | Annotate | Download | only in cgpt
      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 
     11 extern const char* progname;
     12 
     13 static 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
     37 static 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 
     66 int cmd_find(int argc, char *argv[]) {
     67 
     68   CgptFindParams params;
     69   memset(&params, 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, &params.type_guid) &&
    105           CGPT_OK != StrToGuid(optarg, &params.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, &params.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, &params.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(&params);
    169       }
    170   } else {
    171       CgptFind(&params);
    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