Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(608)

Unified Diff: cgpt/cmd_add.c

Issue 2719008: Nearly complete rewrite of cgpt tool. (Closed) Base URL: ssh://git@chromiumos-git//vboot_reference.git
Patch Set: Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cgpt/cgpt_common.c ('k') | cgpt/cmd_boot.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cgpt/cmd_add.c
diff --git a/cgpt/cmd_add.c b/cgpt/cmd_add.c
new file mode 100644
index 0000000000000000000000000000000000000000..18a0285e8143fd1ae8c701ed8213c90c0f9c42d9
--- /dev/null
+++ b/cgpt/cmd_add.c
@@ -0,0 +1,276 @@
+// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cgpt.h"
+
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <uuid/uuid.h>
+
+#include "cgptlib_internal.h"
+
+static void Usage(void)
+{
+ printf("\nUsage: %s add [OPTIONS] DRIVE\n\n"
+ "Add, edit, or remove a partition entry.\n\n"
+ "Options:\n"
+ " -i NUM Specify partition (default is next available)\n"
+ " -b NUM Beginning sector\n"
+ " -s NUM Size in sectors\n"
+ " -t GUID Partition Type GUID\n"
+ " -u GUID Partition Unique ID\n"
+ " -l LABEL Label\n"
+ " -S NUM set Successful flag (0|1)\n"
+ " -T NUM set Tries flag (0-15)\n"
+ " -P NUM set Priority flag (0-15)\n"
+ " -A NUM set raw 64-bit attribute value\n"
+ "\n"
+ "Use the -i option to modify an existing partition.\n"
+ "The -b, -s, and -t options must be given for new partitions.\n"
+ "\n", progname);
+ PrintTypes();
+}
+
+int cmd_add(int argc, char *argv[]) {
+ struct drive drive;
+ int partition = 0;
+ uint64_t begin = 0;
+ uint64_t size = 0;
+ Guid type_guid;
+ Guid unique_guid;
+ char *label = 0;
+ int successful = 0;
+ int tries = 0;
+ int priority = 0;
+ uint64_t raw_value = 0;
+ int set_begin = 0;
+ int set_size = 0;
+ int set_type = 0;
+ int set_unique = 0;
+ int set_successful = 0;
+ int set_tries = 0;
+ int set_priority = 0;
+ int set_raw = 0;
+
+ int gpt_retval;
+ GptEntry *entry;
+ int index;
+
+ int c;
+ int errorcnt = 0;
+ char *e = 0;
+
+ opterr = 0; // quiet, you
+ while ((c=getopt(argc, argv, ":hi:b:s:t:u:l:S:T:P:A:")) != -1)
+ {
+ switch (c)
+ {
+ case 'i':
+ partition = (uint32_t)strtoul(optarg, &e, 0);
+ if (!*optarg || (e && *e))
+ {
+ Error("invalid argument to -%c: \"%s\"\n", c, optarg);
+ errorcnt++;
+ }
+ break;
+ case 'b':
+ set_begin = 1;
+ begin = strtoull(optarg, &e, 0);
+ if (!*optarg || (e && *e))
+ {
+ Error("invalid argument to -%c: \"%s\"\n", c, optarg);
+ errorcnt++;
+ }
+ break;
+ case 's':
+ set_size = 1;
+ size = strtoull(optarg, &e, 0);
+ if (!*optarg || (e && *e))
+ {
+ Error("invalid argument to -%c: \"%s\"\n", c, optarg);
+ errorcnt++;
+ }
+ break;
+ case 't':
+ set_type = 1;
+ if (CGPT_OK != SupportedType(optarg, &type_guid) &&
+ CGPT_OK != StrToGuid(optarg, &type_guid)) {
+ Error("invalid argument to -%c: %s\n", c, optarg);
+ errorcnt++;
+ }
+ break;
+ case 'u':
+ set_unique = 1;
+ if (CGPT_OK != StrToGuid(optarg, &unique_guid)) {
+ Error("invalid argument to -%c: %s\n", c, optarg);
+ errorcnt++;
+ }
+ break;
+ case 'l':
+ label = optarg;
+ break;
+ case 'S':
+ set_successful = 1;
+ successful = (uint32_t)strtoul(optarg, &e, 0);
+ if (!*optarg || (e && *e))
+ {
+ Error("invalid argument to -%c: \"%s\"\n", c, optarg);
+ errorcnt++;
+ }
+ if (successful < 0 || successful > 1) {
+ Error("value for -%c must be between 0 and 1", c);
+ errorcnt++;
+ }
+ break;
+ case 'T':
+ set_tries = 1;
+ tries = (uint32_t)strtoul(optarg, &e, 0);
+ if (!*optarg || (e && *e))
+ {
+ fprintf(stderr, "%s: invalid argument to -%c: \"%s\"\n",
+ progname, c, optarg);
+ errorcnt++;
+ }
+ if (tries < 0 || tries > 15) {
+ Error("value for -%c must be between 0 and 15", c);
+ errorcnt++;
+ }
+ break;
+ case 'P':
+ set_priority = 1;
+ priority = (uint32_t)strtoul(optarg, &e, 0);
+ if (!*optarg || (e && *e))
+ {
+ Error("invalid argument to -%c: \"%s\"\n", c, optarg);
+ errorcnt++;
+ }
+ if (priority < 0 || priority > 15) {
+ Error("value for -%c must be between 0 and 15", c);
+ errorcnt++;
+ }
+ break;
+ case 'A':
+ set_raw = 1;
+ raw_value = strtoull(optarg, &e, 0);
+ if (!*optarg || (e && *e))
+ {
+ Error("invalid argument to -%c: \"%s\"\n", c, optarg);
+ errorcnt++;
+ }
+ break;
+
+ case 'h':
+ Usage();
+ return CGPT_OK;
+ case '?':
+ Error("unrecognized option: -%c\n", optopt);
+ errorcnt++;
+ break;
+ case ':':
+ Error("missing argument to -%c\n", optopt);
+ errorcnt++;
+ break;
+ default:
+ errorcnt++;
+ break;
+ }
+ }
+ if (errorcnt)
+ {
+ Usage();
+ return CGPT_FAILED;
+ }
+
+ if (optind >= argc) {
+ Error("missing drive argument\n");
+ return CGPT_FAILED;
+ }
+
+ if (CGPT_OK != DriveOpen(argv[optind], &drive))
+ return CGPT_FAILED;
+
+ if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) {
+ Error("GptSanityCheck() returned %d: %s\n",
+ gpt_retval, GptError(gpt_retval));
+ return CGPT_FAILED;
+ }
+
+ int max_part = GetNumberOfEntries(&drive.gpt);
+ if (partition) {
+ if (partition > max_part) {
+ Error("invalid partition number: %d\n", partition);
+ goto bad;
+ }
+ index = partition - 1;
+ entry = GetEntry(&drive.gpt, PRIMARY, index);
+ } else {
+ // find next empty partition
+ for (index = 0; index < max_part; index++) {
+ entry = GetEntry(&drive.gpt, PRIMARY, index);
+ if (IsZero(&entry->type)) {
+ partition = index + 1;
+ break;
+ }
+ }
+ if (index >= max_part) {
+ Error("no unused partitions available\n");
+ goto bad;
+ }
+ }
+
+ // New partitions must specify type, begin, and size.
+ if (IsZero(&entry->type)) {
+ if (!set_begin || !set_size || !set_type) {
+ Error("-t, -b, and -s options are required for new partitions\n");
+ goto bad;
+ }
+ if (IsZero(&type_guid)) {
+ Error("New partitions must have a type other than \"unused\"\n");
+ goto bad;
+ }
+ if (!set_unique)
+ uuid_generate((uint8_t *)&entry->unique);
+ }
+
+ if (set_begin)
+ entry->starting_lba = begin;
+ if (set_size)
+ entry->ending_lba = begin + size - 1;
+ if (set_type)
+ memcpy(&entry->type, &type_guid, sizeof(Guid));
+ if (set_unique)
+ memcpy(&entry->unique, &unique_guid, sizeof(Guid));
+ if (label) {
+ uint16_t buf[128];
+ UTF8ToUTF16((uint8_t *)label, buf);
+ memcpy(entry->name, buf, sizeof(entry->name));
+ }
+ if (set_raw) {
+ entry->attributes = raw_value;
+ } else {
+ if (set_successful)
+ SetSuccessful(&drive.gpt, PRIMARY, index, successful);
+ if (set_tries)
+ SetTries(&drive.gpt, PRIMARY, index, tries);
+ if (set_priority)
+ SetPriority(&drive.gpt, PRIMARY, index, priority);
+ }
+
+ RepairEntries(&drive.gpt, MASK_PRIMARY);
+ RepairHeader(&drive.gpt, MASK_PRIMARY);
+
+ drive.gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 |
+ GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2);
+ UpdateCrc(&drive.gpt);
+
+
+ // Write it all out
+ return DriveClose(&drive, 1);
+
+bad:
+ (void) DriveClose(&drive, 0);
+ return CGPT_FAILED;
+}
« no previous file with comments | « cgpt/cgpt_common.c ('k') | cgpt/cmd_boot.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698