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