Index: utility/cgpt/cgpt.c |
diff --git a/utility/cgpt/cgpt.c b/utility/cgpt/cgpt.c |
deleted file mode 100644 |
index 5bcba17c83308fea0d31fbe4ec6c3f25cb8b69ce..0000000000000000000000000000000000000000 |
--- a/utility/cgpt/cgpt.c |
+++ /dev/null |
@@ -1,457 +0,0 @@ |
-/* 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. |
- * |
- * Utility for ChromeOS-specific GPT partitions, Please see corresponding .c |
- * files for more details. |
- */ |
-/* To compile on host without compatility to BSD, we include |
- * endian.h under chroot. */ |
-#define _BSD_SOURCE |
-#include "endian.h" |
- |
-#define __USE_LARGEFILE64 |
-#define __USE_FILE_OFFSET64 |
-#define _LARGEFILE64_SOURCE |
-#include "cgpt.h" |
-#include "cgpt_tofix.h" |
-#include <errno.h> |
-#include <fcntl.h> |
-#include <getopt.h> |
-#include <stdint.h> |
-#include <stdio.h> |
-#include <stdlib.h> |
-#include <string.h> |
-#include <sys/ioctl.h> |
-#include <sys/mount.h> |
-#include <sys/stat.h> |
-#include <sys/types.h> |
-#include <unistd.h> |
-#include "cgptlib_internal.h" |
-#include "utility.h" |
- |
-/* For usage print */ |
-const char* progname; |
- |
-/* Lists all command here. */ |
-struct { |
- const char *name; |
- int (*fp)(int argc, char *argv[]); |
- const char *comment; |
-} cmds[] = { |
- {"add", CgptAdm, "Add a partition to drive"}, |
- {"delete", CgptAdm, "Delete a partition on drive"}, |
- {"modify", CgptAdm, "Modify the partition on drive"}, |
- {"attribute", CgptAttribute, "Update GPT attribute bits " |
- "(for ChromeOS kernel entry only)"}, |
- {"dev", CgptDev, "Developper mode"}, |
- {"repair", CgptRepair, "Repair primary and secondary headers and tables"}, |
- {"show", CgptShow, "Show partition details"}, |
-}; |
- |
-/* Shows main menu. If 'message' is non-NULL, shows it as header. Then, this |
- * traverses cmds[] and shows supported commands and their comments. */ |
-void Usage(const char *message) { |
- int i; |
- |
- if (message) printf("%s\n", message); |
- printf("Usage: %s COMMAND [OPTIONS]\n\n" |
- "Supported COMMANDs:\n\n", |
- progname); |
- for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) { |
- printf(" %-10s %s\n", cmds[i].name, cmds[i].comment); |
- } |
- printf("\nFor more detailed usage, use %s COMMAND --help.\n\n", progname); |
-} |
- |
-/* GUID conversion functions. Accepted format: |
- * |
- * "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" |
- * |
- * Returns CGPT_OK if parsing is successful; otherwise CGPT_FAILED. |
- */ |
-int StrToGuid(const char *str, Guid *guid) { |
- uint32_t time_low, time_mid, time_high_and_version; |
- |
- if (11 > sscanf(str, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", |
- &time_low, |
- (unsigned int *)&time_mid, |
- (unsigned int *)&time_high_and_version, |
- (unsigned int *)&guid->u.Uuid.clock_seq_high_and_reserved, |
- (unsigned int *)&guid->u.Uuid.clock_seq_low, |
- (unsigned int *)&guid->u.Uuid.node[0], |
- (unsigned int *)&guid->u.Uuid.node[1], |
- (unsigned int *)&guid->u.Uuid.node[2], |
- (unsigned int *)&guid->u.Uuid.node[3], |
- (unsigned int *)&guid->u.Uuid.node[4], |
- (unsigned int *)&guid->u.Uuid.node[5])) return CGPT_FAILED; |
- |
- guid->u.Uuid.time_low = htole32(time_low); |
- guid->u.Uuid.time_mid = htole16(time_mid); |
- guid->u.Uuid.time_high_and_version = htole16(time_high_and_version); |
- |
- return CGPT_OK; |
-} |
- |
-void GuidToStr(const Guid *guid, char *str) { |
- sprintf(str, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", |
- le32toh(guid->u.Uuid.time_low), le16toh(guid->u.Uuid.time_mid), |
- le16toh(guid->u.Uuid.time_high_and_version), |
- guid->u.Uuid.clock_seq_high_and_reserved, guid->u.Uuid.clock_seq_low, |
- guid->u.Uuid.node[0], guid->u.Uuid.node[1], guid->u.Uuid.node[2], |
- guid->u.Uuid.node[3], guid->u.Uuid.node[4], guid->u.Uuid.node[5]); |
-} |
- |
-/* Convert UTF16 string to UTF8. Rewritten from gpt utility. |
- * Caller must prepare enough space for UTF8. The rough estimation is: |
- * |
- * utf8 length = bytecount(utf16) * 1.5 |
- */ |
-#define SIZEOF_GPTENTRY_NAME 36 /* sizeof(GptEntry.name[]) */ |
-void UTF16ToUTF8(const uint16_t *utf16, uint8_t *utf8) |
-{ |
- size_t s8idx, s16idx, s16len; |
- uint32_t utfchar; |
- unsigned int next_utf16; |
- |
- for (s16len = 0; s16len < SIZEOF_GPTENTRY_NAME && utf16[s16len]; ++s16len); |
- |
- *utf8 = s8idx = s16idx = 0; |
- while (s16idx < s16len) { |
- utfchar = le16toh(utf16[s16idx++]); |
- if ((utfchar & 0xf800) == 0xd800) { |
- next_utf16 = le16toh(utf16[s16idx]); |
- if ((utfchar & 0x400) != 0 || (next_utf16 & 0xfc00) != 0xdc00) |
- utfchar = 0xfffd; |
- else |
- s16idx++; |
- } |
- if (utfchar < 0x80) { |
- utf8[s8idx++] = utfchar; |
- } else if (utfchar < 0x800) { |
- utf8[s8idx++] = 0xc0 | (utfchar >> 6); |
- utf8[s8idx++] = 0x80 | (utfchar & 0x3f); |
- } else if (utfchar < 0x10000) { |
- utf8[s8idx++] = 0xe0 | (utfchar >> 12); |
- utf8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f); |
- utf8[s8idx++] = 0x80 | (utfchar & 0x3f); |
- } else if (utfchar < 0x200000) { |
- utf8[s8idx++] = 0xf0 | (utfchar >> 18); |
- utf8[s8idx++] = 0x80 | ((utfchar >> 12) & 0x3f); |
- utf8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f); |
- utf8[s8idx++] = 0x80 | (utfchar & 0x3f); |
- } |
- } |
- utf8[s8idx++] = 0; |
-} |
- |
-/* Convert UTF8 string to UTF16. Rewritten from gpt utility. |
- * Caller must prepare enough space for UTF16. The conservative estimation is: |
- * |
- * utf16 bytecount = bytecount(utf8) / 3 * 4 |
- */ |
-void UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16) |
-{ |
- size_t s16idx, s8idx, s8len; |
- uint32_t utfchar; |
- unsigned int c, utfbytes; |
- |
- for (s8len = 0; utf8[s8len]; ++s8len); |
- |
- s8idx = s16idx = 0; |
- utfbytes = 0; |
- do { |
- c = utf8[s8idx++]; |
- if ((c & 0xc0) != 0x80) { |
- /* Initial characters. */ |
- if (utfbytes != 0) { |
- /* Incomplete encoding. */ |
- utf16[s16idx++] = 0xfffd; |
- } |
- if ((c & 0xf8) == 0xf0) { |
- utfchar = c & 0x07; |
- utfbytes = 3; |
- } else if ((c & 0xf0) == 0xe0) { |
- utfchar = c & 0x0f; |
- utfbytes = 2; |
- } else if ((c & 0xe0) == 0xc0) { |
- utfchar = c & 0x1f; |
- utfbytes = 1; |
- } else { |
- utfchar = c & 0x7f; |
- utfbytes = 0; |
- } |
- } else { |
- /* Followup characters. */ |
- if (utfbytes > 0) { |
- utfchar = (utfchar << 6) + (c & 0x3f); |
- utfbytes--; |
- } else if (utfbytes == 0) |
- utfbytes = -1; |
- utfchar = 0xfffd; |
- } |
- if (utfbytes == 0) { |
- if (utfchar >= 0x10000) { |
- utf16[s16idx++] = htole16(0xd800 | ((utfchar>>10)-0x40)); |
- if (s16idx >= SIZEOF_GPTENTRY_NAME) break; |
- utf16[s16idx++] = htole16(0xdc00 | (utfchar & 0x3ff)); |
- } else { |
- utf16[s16idx++] = htole16(utfchar); |
- } |
- } |
- } while (c != 0 && s16idx < SIZEOF_GPTENTRY_NAME); |
- if (s16idx < SIZEOF_GPTENTRY_NAME) |
- utf16[s16idx++] = 0; |
-} |
- |
-struct { |
- Guid type; |
- char *name; |
- char *description; |
-} supported_types[] = { |
- {GPT_ENT_TYPE_UNUSED, "unused", "Unused partition"}, |
- {GPT_ENT_TYPE_EFI, "efi", "EFI System Partition"}, |
- {GPT_ENT_TYPE_CHROMEOS_KERNEL, "croskern", "ChromeOS kernel"}, |
- {GPT_ENT_TYPE_CHROMEOS_ROOTFS, "crosroot", "ChromeOS rootfs"}, |
- {GPT_ENT_TYPE_CHROMEOS_RESERVED, "crosresv", "ChromeOS reserved"}, |
- {GPT_ENT_TYPE_LINUX_DATA, "data", "Linux data"}, |
-}; |
- |
-/* Resolves human-readable GPT type. |
- * Returns CGPT_OK if found. |
- * Returns CGPT_FAILED if no known type found. */ |
-int ResolveType(const Guid *type, char *buf) { |
- int i; |
- for (i = 0; i < ARRAY_COUNT(supported_types); ++i) { |
- if (!Memcmp(type, &supported_types[i].type, sizeof(Guid))) { |
- strcpy(buf, supported_types[i].description); |
- return CGPT_OK; |
- } |
- } |
- return CGPT_FAILED; |
-} |
- |
-int SupportedType(const char *name, Guid *type) { |
- int i; |
- for (i = 0; i < ARRAY_COUNT(supported_types); ++i) { |
- if (!strcmp(name, supported_types[i].name)) { |
- Memcpy(type, &supported_types[i].type, sizeof(Guid)); |
- return CGPT_OK; |
- } |
- } |
- return CGPT_FAILED; |
-} |
- |
-void PrintTypes(void) { |
- int i; |
- printf("\n* For --type option, you can use the following alias, " |
- "instead of hex values:\n"); |
- for (i = 0; i < ARRAY_COUNT(supported_types); ++i) { |
- printf(" %-10s %s\n", supported_types[i].name, |
- supported_types[i].description); |
- } |
- printf("\n"); |
-} |
- |
-/* Loads sectors from 'fd'. |
- * *buf is pointed to an allocated memory when returned, and should be |
- * freed by cgpt_close(). |
- * |
- * fd -- file descriptot. |
- * buf -- pointer to buffer pointer |
- * sector -- offset of starting sector (in sectors) |
- * sector_bytes -- bytes per sector |
- * sector_count -- number of sectors to load |
- * |
- * Returns CGPT_OK for successful. Aborts if any error occurs. |
- */ |
-int Load(const int fd, uint8_t **buf, |
- const uint64_t sector, |
- const uint64_t sector_bytes, |
- const uint64_t sector_count) { |
- int count; /* byte count to read */ |
- int nread; |
- |
- assert(buf); |
- count = sector_bytes * sector_count; |
- *buf = Malloc(count); |
- assert(*buf); |
- |
- if (-1 == lseek64(fd, sector * sector_bytes, SEEK_SET)) |
- goto error_free; |
- |
- nread = read(fd, *buf, count); |
- if (nread < count) |
- goto error_free; |
- |
- return CGPT_OK; |
- |
-error_free: |
- Free(*buf); |
- *buf = 0; |
- abort(); |
-} |
- |
-/* Saves sectors to 'fd'. |
- * |
- * fd -- file descriptot. |
- * buf -- pointer to buffer |
- * sector -- starting sector offset |
- * sector_bytes -- bytes per sector |
- * sector_count -- number of sector to save |
- * |
- * Returns CGPT_OK for successful, CGPT_FAILED for failed. |
- */ |
-int Save(const int fd, const uint8_t *buf, |
- const uint64_t sector, |
- const uint64_t sector_bytes, |
- const uint64_t sector_count) { |
- int count; /* byte count to write */ |
- int nwrote; |
- |
- assert(buf); |
- count = sector_bytes * sector_count; |
- |
- if (-1 == lseek64(fd, sector * sector_bytes, SEEK_SET)) |
- return CGPT_FAILED; |
- |
- nwrote = write(fd, buf, count); |
- if (nwrote < count) |
- return CGPT_FAILED; |
- |
- return CGPT_OK; |
-} |
- |
-int CheckValid(const struct drive *drive) { |
- if ((drive->gpt.valid_headers != MASK_BOTH) || |
- (drive->gpt.valid_entries != MASK_BOTH)) { |
- printf("\n[ERROR] any of GPT header/entries is invalid, " |
- "please run '%s repair' first\n", progname); |
- return CGPT_FAILED; |
- } |
- return CGPT_OK; |
-} |
- |
-/* Opens a block device (a regular file works well too). |
- * |
- * Returns CGPT_FAILED if any error happens. |
- * Returns CGPT_OK if success and information are stored in 'drive'. */ |
-int DriveOpen(const char *drive_path, struct drive *drive) { |
- struct stat stat; |
- int gpt_retval; |
- |
- assert(drive_path); |
- assert(drive); |
- |
- Memset(drive, 0, sizeof(struct drive)); |
- drive->fd = open(drive_path, O_RDWR | O_LARGEFILE); |
- if (drive->fd == -1) { |
- printf("[ERROR] Cannot open drive file [%s]: %s\n", |
- drive_path, strerror(errno)); |
- return CGPT_FAILED; |
- } |
- |
- if (fstat(drive->fd, &stat) == -1) { |
- goto error_close; |
- } |
- if ((stat.st_mode & S_IFMT) != S_IFREG) { |
- if (ioctl(drive->fd, BLKGETSIZE64, &drive->size) < 0) { |
- printf("[ERROR] Cannot get sector size from drive file [%s]: %s\n", |
- drive_path, strerror(errno)); |
- goto error_close; |
- } |
- if (ioctl(drive->fd, BLKSSZGET, &drive->gpt.sector_bytes) < 0) { |
- printf("[ERROR] Cannot get drive size from drive file [%s]: %s\n", |
- drive_path, strerror(errno)); |
- goto error_close; |
- } |
- } else { |
- drive->gpt.sector_bytes = 512; /* bytes */ |
- drive->size = stat.st_size; |
- } |
- if (drive->size % drive->gpt.sector_bytes) { |
- printf("[ERROR] Media size (%llu) is not the multiple of sector size(%d)\n", |
- (long long unsigned int)drive->size, drive->gpt.sector_bytes); |
- goto error_close; |
- } |
- drive->gpt.drive_sectors = drive->size / drive->gpt.sector_bytes; |
- |
- Load(drive->fd, &drive->gpt.primary_header, GPT_PMBR_SECTOR, |
- drive->gpt.sector_bytes, GPT_HEADER_SECTOR); |
- Load(drive->fd, &drive->gpt.secondary_header, |
- drive->gpt.drive_sectors - GPT_PMBR_SECTOR, |
- drive->gpt.sector_bytes, GPT_HEADER_SECTOR); |
- Load(drive->fd, &drive->gpt.primary_entries, |
- GPT_PMBR_SECTOR + GPT_HEADER_SECTOR, |
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS); |
- Load(drive->fd, &drive->gpt.secondary_entries, |
- drive->gpt.drive_sectors - GPT_HEADER_SECTOR - GPT_ENTRIES_SECTORS, |
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS); |
- |
- if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) { |
- printf("[ERROR] GptSanityCheck(): %s\n", GptError(gpt_retval)); |
- goto error_close; |
- } |
- |
- drive->inited = 1; |
- |
- return CGPT_OK; |
- |
-error_close: |
- close(drive->fd); |
- return CGPT_FAILED; |
-} |
- |
-int DriveClose(struct drive *drive) { |
- if (drive->inited) { |
- if (drive->gpt.modified & GPT_MODIFIED_HEADER1) |
- assert(CGPT_OK == |
- Save(drive->fd, drive->gpt.primary_header, GPT_PMBR_SECTOR, |
- drive->gpt.sector_bytes, GPT_HEADER_SECTOR)); |
- if (drive->gpt.modified & GPT_MODIFIED_HEADER2) |
- assert(CGPT_OK == |
- Save(drive->fd, drive->gpt.secondary_header, |
- drive->gpt.drive_sectors - GPT_PMBR_SECTOR, |
- drive->gpt.sector_bytes, GPT_HEADER_SECTOR)); |
- if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1) |
- assert(CGPT_OK == |
- Save(drive->fd, drive->gpt.primary_entries, |
- GPT_PMBR_SECTOR + GPT_HEADER_SECTOR, |
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)); |
- if (drive->gpt.modified & GPT_MODIFIED_ENTRIES2) |
- assert(CGPT_OK == |
- Save(drive->fd, drive->gpt.secondary_entries, |
- drive->gpt.drive_sectors - GPT_HEADER_SECTOR - |
- GPT_ENTRIES_SECTORS, |
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)); |
- |
- close(drive->fd); |
- } |
- |
- Free(drive->gpt.primary_header); |
- drive->gpt.primary_header = 0; |
- Free(drive->gpt.primary_entries); |
- drive->gpt.primary_entries = 0; |
- Free(drive->gpt.secondary_header); |
- drive->gpt.secondary_header = 0; |
- Free(drive->gpt.secondary_entries); |
- drive->gpt.secondary_entries = 0; |
- |
- drive->inited = 0; |
- return CGPT_OK; |
-} |
- |
-int main(int argc, char *argv[]) { |
- char *cmd; |
- int i; |
- |
- progname = argv[0]; |
- cmd = argv[optind++]; |
- for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) { |
- if (cmd && !strcmp(cmds[i].name, cmd)) |
- return cmds[i].fp(argc, argv); |
- } |
- |
- Usage(0); |
- return CGPT_FAILED; |
-} |