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 | 2e8e055 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 22 | #include "sgdisk.h" |
Tom Marshall | bb7250f | 2019-07-23 15:18:15 -0700 | [diff] [blame] | 23 | #include "gptcl.h" |
Tom Marshall | 2e8e055 | 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 | 2e8e055 | 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 | 2e8e055 | 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 | 2e8e055 | 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 | 2e8e055 | 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; |
3l H4ck3r C0mf0r7 | 20a492d | 2021-10-10 15:27:53 -0300 | [diff] [blame] | 63 | case hybrid: |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 64 | case gpt: |
| 65 | gptData.JustLooking(); |
| 66 | if (!gptData.LoadPartitions((string) device)) { |
| 67 | cerr << "Failed to read GPT" << endl; |
| 68 | return 9; |
| 69 | } |
| 70 | |
Tom Marshall | 2e8e055 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 71 | ptbl.type = GPT; |
| 72 | ptbl.guid = gptData.GetDiskGUID().AsString(); |
| 73 | for (size_t i = 0; i < gptData.GetNumParts(); i++) { |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 74 | partData = gptData[i]; |
| 75 | if (partData.GetFirstLBA() > 0) { |
Tom Marshall | 2e8e055 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 76 | sgdisk_partition part; |
| 77 | part.num = i + 1; |
| 78 | part.type = partData.GetType().AsString(); |
| 79 | part.guid = partData.GetUniqueGUID().AsString(); |
| 80 | part.name = partData.GetDescription(); |
| 81 | partitions.push_back(part); |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 82 | } |
| 83 | } |
| 84 | break; |
| 85 | default: |
| 86 | cerr << "Unknown partition table" << endl; |
| 87 | return 10; |
| 88 | } |
| 89 | |
Tom Marshall | 2e8e055 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 90 | fflush(stdout); |
| 91 | fflush(stderr); |
| 92 | dup2(stdout_fd, STDOUT_FILENO); |
| 93 | dup2(stderr_fd, STDERR_FILENO); |
| 94 | close(silence); |
| 95 | |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 96 | return 0; |
| 97 | } |
| 98 | |
Tom Marshall | 2e8e055 | 2019-01-15 10:07:29 -0800 | [diff] [blame] | 99 | /* |
| 100 | * Dump partition details in a machine readable format: |
| 101 | * |
| 102 | * DISK [mbr|gpt] [guid] |
| 103 | * PART [n] [type] [guid] |
| 104 | */ |
| 105 | static int android_dump(const char* device) { |
| 106 | sgdisk_partition_table ptbl; |
| 107 | vector<sgdisk_partition> partitions; |
| 108 | int rc = sgdisk_read(device, ptbl, partitions); |
| 109 | if (rc == 0) { |
| 110 | stringstream res; |
| 111 | switch (ptbl.type) { |
| 112 | case MBR: |
| 113 | res << "DISK mbr" << endl; |
| 114 | for (auto& part : partitions) { |
| 115 | res << "PART " << part.num << " " << part.type << endl; |
| 116 | } |
| 117 | break; |
| 118 | case GPT: |
| 119 | res << "DISK gpt " << ptbl.guid << endl; |
| 120 | for (auto& part : partitions) { |
| 121 | res << "PART " << part.num << " " << part.type << " " |
| 122 | << part.guid << " " << part.name << endl; |
| 123 | } |
| 124 | break; |
| 125 | default: |
| 126 | return 10; |
| 127 | } |
| 128 | string partStr = res.str(); |
| 129 | write(STDOUT_FILENO, partStr.c_str(), partStr.length()); |
| 130 | } |
| 131 | return rc; |
| 132 | } |
| 133 | |
Tom Marshall | 25b8b16 | 2015-11-04 15:48:02 -0800 | [diff] [blame] | 134 | extern "C" int main(int argc, char *argv[]) { |
Jeff Sharkey | d4e73c9 | 2015-02-28 20:21:52 -0800 | [diff] [blame] | 135 | for (int i = 0; i < argc; i++) { |
| 136 | if (!strcmp("--android-dump", argv[i])) { |
| 137 | return android_dump(argv[i + 1]); |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | GPTDataCL theGPT; |
| 142 | return theGPT.DoOptions(argc, argv); |
| 143 | } |