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(¶ms, 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, ¶ms.type_guid) && 89 CGPT_OK != StrToGuid(optarg, ¶ms.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, ¶ms.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(¶ms); 185 } 186