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(¶ms, 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, ¶ms.type_guid) &&
77 CGPT_OK != StrToGuid(optarg, ¶ms.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, ¶ms.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(¶ms);
165 }
166