srs5694 | 1e09372 | 2010-01-05 00:14:19 -0500 | [diff] [blame] | 1 | // sgdisk.cc |
srs5694 | 73ba479 | 2010-01-12 18:18:17 -0500 | [diff] [blame] | 2 | // Command-line-based version of gdisk. This program is named after sfdisk, |
| 3 | // and it can serve a similar role (easily scripted, etc.), but it's used |
| 4 | // strictly via command-line arguments, and it doesn't bear much resemblance |
| 5 | // to sfdisk in actual use. |
srs5694 | 1e09372 | 2010-01-05 00:14:19 -0500 | [diff] [blame] | 6 | // |
srs5694 | 73ba479 | 2010-01-12 18:18:17 -0500 | [diff] [blame] | 7 | // by Rod Smith, project began February 2009; sgdisk begun January 2010. |
srs5694 | 1e09372 | 2010-01-05 00:14:19 -0500 | [diff] [blame] | 8 | |
srs5694 | 64cbd17 | 2011-03-01 22:03:54 -0500 | [diff] [blame] | 9 | /* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed |
srs5694 | 1e09372 | 2010-01-05 00:14:19 -0500 | [diff] [blame] | 10 | under the terms of the GNU GPL version 2, as detailed in the COPYING file. */ |
| 11 | |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 12 | #include <iostream> |
| 13 | #include <fstream> |
| 14 | #include <string.h> |
| 15 | #include <string> |
| 16 | #include <iostream> |
| 17 | #include <sstream> |
| 18 | #include <errno.h> |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 19 | #include <fcntl.h> |
Dan Albert | 8fc8365 | 2015-08-12 15:52:37 -0700 | [diff] [blame] | 20 | #include <unistd.h> |
srs5694 | 73ba479 | 2010-01-12 18:18:17 -0500 | [diff] [blame] | 21 | |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 22 | #include "sgdisk.h" |
Tom Marshall | 7b5b711 | 2019-07-23 15:18:15 -0700 | [diff] [blame] | 23 | #include "gptcl.h" |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 24 | |
srs5694 | 73ba479 | 2010-01-12 18:18:17 -0500 | [diff] [blame] | 25 | using namespace std; |
srs5694 | 1e09372 | 2010-01-05 00:14:19 -0500 | [diff] [blame] | 26 | |
| 27 | #define MAX_OPTIONS 50 |
| 28 | |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 29 | int sgdisk_read(const char* device, sgdisk_partition_table& ptbl, |
| 30 | vector<sgdisk_partition>& partitions) { |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 31 | BasicMBRData mbrData; |
| 32 | GPTData gptData; |
| 33 | GPTPart partData; |
| 34 | int numParts = 0; |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 35 | |
| 36 | /* Silence noisy underlying library */ |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 37 | int stdout_fd = dup(STDOUT_FILENO); |
| 38 | int stderr_fd = dup(STDERR_FILENO); |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 39 | int silence = open("/dev/null", 0); |
| 40 | dup2(silence, STDOUT_FILENO); |
| 41 | dup2(silence, STDERR_FILENO); |
| 42 | |
| 43 | if (!mbrData.ReadMBRData((string) device)) { |
| 44 | cerr << "Failed to read MBR" << endl; |
| 45 | return 8; |
| 46 | } |
| 47 | |
| 48 | switch (mbrData.GetValidity()) { |
| 49 | case mbr: |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 50 | ptbl.type = MBR; |
| 51 | ptbl.guid.clear(); |
| 52 | for (size_t i = 0; i < MAX_MBR_PARTS; i++) { |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 53 | if (mbrData.GetLength(i) > 0) { |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 54 | char typebuf[2+8+1]; |
| 55 | sprintf(typebuf, "%x", (unsigned int)mbrData.GetType(i)); |
| 56 | sgdisk_partition part; |
| 57 | part.num = i + 1; |
| 58 | part.type = typebuf; |
| 59 | partitions.push_back(part); |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 60 | } |
| 61 | } |
| 62 | break; |
| 63 | case gpt: |
| 64 | gptData.JustLooking(); |
| 65 | if (!gptData.LoadPartitions((string) device)) { |
| 66 | cerr << "Failed to read GPT" << endl; |
| 67 | return 9; |
| 68 | } |
| 69 | |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 70 | ptbl.type = GPT; |
| 71 | ptbl.guid = gptData.GetDiskGUID().AsString(); |
| 72 | for (size_t i = 0; i < gptData.GetNumParts(); i++) { |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 73 | partData = gptData[i]; |
| 74 | if (partData.GetFirstLBA() > 0) { |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 75 | sgdisk_partition part; |
| 76 | part.num = i + 1; |
| 77 | part.type = partData.GetType().AsString(); |
| 78 | part.guid = partData.GetUniqueGUID().AsString(); |
| 79 | part.name = partData.GetDescription(); |
| 80 | partitions.push_back(part); |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 81 | } |
| 82 | } |
| 83 | break; |
| 84 | default: |
| 85 | cerr << "Unknown partition table" << endl; |
| 86 | return 10; |
| 87 | } |
| 88 | |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 89 | fflush(stdout); |
| 90 | fflush(stderr); |
| 91 | dup2(stdout_fd, STDOUT_FILENO); |
| 92 | dup2(stderr_fd, STDERR_FILENO); |
| 93 | close(silence); |
| 94 | |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 95 | return 0; |
| 96 | } |
| 97 | |
Tom Marshall | ecb5206 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 98 | /* |
| 99 | * Dump partition details in a machine readable format: |
| 100 | * |
| 101 | * DISK [mbr|gpt] [guid] |
| 102 | * PART [n] [type] [guid] |
| 103 | */ |
| 104 | static int android_dump(const char* device) { |
| 105 | sgdisk_partition_table ptbl; |
| 106 | vector<sgdisk_partition> partitions; |
| 107 | int rc = sgdisk_read(device, ptbl, partitions); |
| 108 | if (rc == 0) { |
| 109 | stringstream res; |
| 110 | switch (ptbl.type) { |
| 111 | case MBR: |
| 112 | res << "DISK mbr" << endl; |
| 113 | for (auto& part : partitions) { |
| 114 | res << "PART " << part.num << " " << part.type << endl; |
| 115 | } |
| 116 | break; |
| 117 | case GPT: |
| 118 | res << "DISK gpt " << ptbl.guid << endl; |
| 119 | for (auto& part : partitions) { |
| 120 | res << "PART " << part.num << " " << part.type << " " |
| 121 | << part.guid << " " << part.name << endl; |
| 122 | } |
| 123 | break; |
| 124 | default: |
| 125 | return 10; |
| 126 | } |
| 127 | string partStr = res.str(); |
| 128 | write(STDOUT_FILENO, partStr.c_str(), partStr.length()); |
| 129 | } |
| 130 | return rc; |
| 131 | } |
| 132 | |
Tom Marshall | 401464e | 2015-11-04 15:48:02 -0800 | [diff] [blame] | 133 | extern "C" int main(int argc, char *argv[]) { |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 134 | for (int i = 0; i < argc; i++) { |
| 135 | if (!strcmp("--android-dump", argv[i])) { |
| 136 | return android_dump(argv[i + 1]); |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | GPTDataCL theGPT; |
| 141 | return theGPT.DoOptions(argc, argv); |
| 142 | } |