xref: /aosp_15_r20/external/vboot_reference/cgpt/cmd_add.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 /* Copyright 2012 The ChromiumOS Authors
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 
6 #include <getopt.h>
7 #include <string.h>
8 
9 #include "cgpt.h"
10 #include "vboot_host.h"
11 
12 extern const char* progname;
13 
Usage(void)14 static void Usage(void)
15 {
16   printf("\nUsage: %s add [OPTIONS] DRIVE\n\n"
17          "Add, edit, or remove a partition entry.\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          "  -i NUM       Specify partition (default is next available)\n"
23          "  -b NUM       First block (a.k.a. start of partition)\n"
24          "  -s NUM       Size (in blocks)\n"
25          "  -t GUID      Partition Type GUID\n"
26          "  -u GUID      Partition Unique ID\n"
27          "  -l LABEL     Label\n"
28          "  -E NUM       set Error counter flag (0|1)\n"
29          "  -S NUM       set Successful flag (0|1)\n"
30          "  -T NUM       set Tries flag (0-15)\n"
31          "  -P NUM       set Priority flag (0-15)\n"
32          "  -R NUM       set Required flag (0|1)\n"
33          "  -B NUM       set Legacy Boot flag (0|1)\n"
34          "  -A NUM       set raw 16-bit attribute value (bits 48-63)\n"
35          "\n"
36          "Use the -i option to modify an existing partition.\n"
37          "The -b, -s, and -t options must be given for new partitions.\n"
38          "\n", progname);
39   PrintTypes();
40 }
41 
cmd_add(int argc,char * argv[])42 int cmd_add(int argc, char *argv[]) {
43 
44   CgptAddParams params;
45   memset(&params, 0, sizeof(params));
46 
47   int c;
48   int errorcnt = 0;
49   char *e = 0;
50 
51   opterr = 0;                     // quiet, you
52   while ((c=getopt(argc, argv, ":hi:b:s:t:u:l:E:S:T:P:R:B:A:D:")) != -1)
53   {
54     switch (c)
55     {
56     case 'D':
57       params.drive_size = strtoull(optarg, &e, 0);
58       errorcnt += check_int_parse(c, e);
59       break;
60     case 'i':
61       params.partition = (uint32_t)strtoul(optarg, &e, 0);
62       errorcnt += check_int_parse(c, e);
63       break;
64     case 'b':
65       params.set_begin = 1;
66       params.begin = strtoull(optarg, &e, 0);
67       errorcnt += check_int_parse(c, e);
68       break;
69     case 's':
70       params.set_size = 1;
71       params.size = strtoull(optarg, &e, 0);
72       errorcnt += check_int_parse(c, e);
73       break;
74     case 't':
75       params.set_type = 1;
76       if (CGPT_OK != SupportedType(optarg, &params.type_guid) &&
77           CGPT_OK != StrToGuid(optarg, &params.type_guid)) {
78         Error("invalid argument to -%c: %s\n", c, optarg);
79         errorcnt++;
80       }
81       break;
82     case 'u':
83       params.set_unique = 1;
84       if (CGPT_OK != StrToGuid(optarg, &params.unique_guid)) {
85         Error("invalid argument to -%c: %s\n", c, optarg);
86         errorcnt++;
87       }
88       break;
89     case 'l':
90       params.label = optarg;
91       break;
92     case 'E':
93       params.set_error_counter = 1;
94       params.error_counter = (uint32_t)strtoul(optarg, &e, 0);
95       errorcnt += check_int_parse(c, e);
96       errorcnt += check_int_limit(c, params.error_counter, 0, 1);
97       break;
98     case 'S':
99       params.set_successful = 1;
100       params.successful = (uint32_t)strtoul(optarg, &e, 0);
101       errorcnt += check_int_parse(c, e);
102       errorcnt += check_int_limit(c, params.successful, 0, 1);
103       break;
104     case 'T':
105       params.set_tries = 1;
106       params.tries = (uint32_t)strtoul(optarg, &e, 0);
107       errorcnt += check_int_parse(c, e);
108       errorcnt += check_int_limit(c, params.tries, 0, 15);
109       break;
110     case 'P':
111       params.set_priority = 1;
112       params.priority = (uint32_t)strtoul(optarg, &e, 0);
113       errorcnt += check_int_parse(c, e);
114       errorcnt += check_int_limit(c, params.priority, 0, 15);
115       break;
116     case 'R':
117       params.set_required = 1;
118       params.required = (uint32_t)strtoul(optarg, &e, 0);
119       errorcnt += check_int_parse(c, e);
120       errorcnt += check_int_limit(c, params.required, 0, 1);
121       break;
122     case 'B':
123       params.set_legacy_boot = 1;
124       params.legacy_boot = (uint32_t)strtoul(optarg, &e, 0);
125       errorcnt += check_int_parse(c, e);
126       errorcnt += check_int_limit(c, params.legacy_boot, 0, 1);
127       break;
128     case 'A':
129       params.set_raw = 1;
130       params.raw_value = strtoull(optarg, &e, 0);
131       errorcnt += check_int_parse(c, e);
132       break;
133 
134     case 'h':
135       Usage();
136       return CGPT_OK;
137     case '?':
138       Error("unrecognized option: -%c\n", optopt);
139       errorcnt++;
140       break;
141     case ':':
142       Error("missing argument to -%c\n", optopt);
143       errorcnt++;
144       break;
145     default:
146       errorcnt++;
147       break;
148     }
149   }
150   if (errorcnt)
151   {
152     Usage();
153     return CGPT_FAILED;
154   }
155 
156   if (optind >= argc)
157   {
158     Error("missing drive argument\n");
159     return CGPT_FAILED;
160   }
161 
162   params.drive_name = argv[optind];
163 
164   return CgptAdd(&params);
165 }
166