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 add [OPTIONS] DRIVE\n\n"
     16          "Add, edit, or remove a partition entry.\n\n"
     17          "Options:\n"
     18          "  -D NUM       Size (in bytes) of the disk where partitions reside\n"
     19          "                 default 0, meaning partitions and GPT structs are\n"
     20          "                 both on DRIVE\n"
     21          "  -i NUM       Specify partition (default is next available)\n"
     22          "  -b NUM       Beginning sector\n"
     23          "  -s NUM       Size in sectors\n"
     24          "  -t GUID      Partition Type GUID\n"
     25          "  -u GUID      Partition Unique ID\n"
     26          "  -l LABEL     Label\n"
     27          "  -S NUM       set Successful flag (0|1)\n"
     28          "  -T NUM       set Tries flag (0-15)\n"
     29          "  -P NUM       set Priority flag (0-15)\n"
     30          "  -A NUM       set raw 64-bit attribute value\n"
     31          "\n"
     32          "Use the -i option to modify an existing partition.\n"
     33          "The -b, -s, and -t options must be given for new partitions.\n"
     34          "\n", progname);
     35   PrintTypes();
     36 }
     37 
     38 int cmd_add(int argc, char *argv[]) {
     39 
     40   CgptAddParams params;
     41   memset(&params, 0, sizeof(params));
     42 
     43   int c;
     44   int errorcnt = 0;
     45   char *e = 0;
     46 
     47   opterr = 0;                     // quiet, you
     48   while ((c=getopt(argc, argv, ":hi:b:s:t:u:l:S:T:P:A:D:")) != -1)
     49   {
     50     switch (c)
     51     {
     52     case 'D':
     53       params.drive_size = strtoull(optarg, &e, 0);
     54       if (!*optarg || (e && *e))
     55       {
     56         Error("invalid argument to -%c: \"%s\"\n", c, optarg);
     57         errorcnt++;
     58       }
     59       break;
     60     case 'i':
     61       params.partition = (uint32_t)strtoul(optarg, &e, 0);
     62       if (!*optarg || (e && *e))
     63       {
     64         Error("invalid argument to -%c: \"%s\"\n", c, optarg);
     65         errorcnt++;
     66       }
     67       break;
     68     case 'b':
     69       params.set_begin = 1;
     70       params.begin = strtoull(optarg, &e, 0);
     71       if (!*optarg || (e && *e))
     72       {
     73         Error("invalid argument to -%c: \"%s\"\n", c, optarg);
     74         errorcnt++;
     75       }
     76       break;
     77     case 's':
     78       params.set_size = 1;
     79       params.size = strtoull(optarg, &e, 0);
     80       if (!*optarg || (e && *e))
     81       {
     82         Error("invalid argument to -%c: \"%s\"\n", c, optarg);
     83         errorcnt++;
     84       }
     85       break;
     86     case 't':
     87       params.set_type = 1;
     88       if (CGPT_OK != SupportedType(optarg, &params.type_guid) &&
     89           CGPT_OK != StrToGuid(optarg, &params.type_guid)) {
     90         Error("invalid argument to -%c: %s\n", c, optarg);
     91         errorcnt++;
     92       }
     93       break;
     94     case 'u':
     95       params.set_unique = 1;
     96       if (CGPT_OK != StrToGuid(optarg, &params.unique_guid)) {
     97         Error("invalid argument to -%c: %s\n", c, optarg);
     98         errorcnt++;
     99       }
    100       break;
    101     case 'l':
    102       params.label = optarg;
    103       break;
    104     case 'S':
    105       params.set_successful = 1;
    106       params.successful = (uint32_t)strtoul(optarg, &e, 0);
    107       if (!*optarg || (e && *e))
    108       {
    109         Error("invalid argument to -%c: \"%s\"\n", c, optarg);
    110         errorcnt++;
    111       }
    112       if (params.successful < 0 || params.successful > 1) {
    113         Error("value for -%c must be between 0 and 1", c);
    114         errorcnt++;
    115       }
    116       break;
    117     case 'T':
    118       params.set_tries = 1;
    119       params.tries = (uint32_t)strtoul(optarg, &e, 0);
    120       if (!*optarg || (e && *e))
    121       {
    122         fprintf(stderr, "%s: invalid argument to -%c: \"%s\"\n",
    123                 progname, c, optarg);
    124         errorcnt++;
    125       }
    126       if (params.tries < 0 || params.tries > 15) {
    127         Error("value for -%c must be between 0 and 15", c);
    128         errorcnt++;
    129       }
    130       break;
    131     case 'P':
    132       params.set_priority = 1;
    133       params.priority = (uint32_t)strtoul(optarg, &e, 0);
    134       if (!*optarg || (e && *e))
    135       {
    136         Error("invalid argument to -%c: \"%s\"\n", c, optarg);
    137         errorcnt++;
    138       }
    139       if (params.priority < 0 || params.priority > 15) {
    140         Error("value for -%c must be between 0 and 15", c);
    141         errorcnt++;
    142       }
    143       break;
    144     case 'A':
    145       params.set_raw = 1;
    146       params.raw_value = strtoull(optarg, &e, 0);
    147       if (!*optarg || (e && *e))
    148       {
    149         Error("invalid argument to -%c: \"%s\"\n", c, optarg);
    150         errorcnt++;
    151       }
    152       break;
    153 
    154     case 'h':
    155       Usage();
    156       return CGPT_OK;
    157     case '?':
    158       Error("unrecognized option: -%c\n", optopt);
    159       errorcnt++;
    160       break;
    161     case ':':
    162       Error("missing argument to -%c\n", optopt);
    163       errorcnt++;
    164       break;
    165     default:
    166       errorcnt++;
    167       break;
    168     }
    169   }
    170   if (errorcnt)
    171   {
    172     Usage();
    173     return CGPT_FAILED;
    174   }
    175 
    176   if (optind >= argc)
    177   {
    178     Error("missing drive argument\n");
    179     return CGPT_FAILED;
    180   }
    181 
    182   params.drive_name = argv[optind];
    183 
    184   return CgptAdd(&params);
    185 }
    186