| // sgdisk.cc |
| // Command-line-based version of gdisk. This program is named after sfdisk, |
| // and it can serve a similar role (easily scripted, etc.), but it's used |
| // strictly via command-line arguments, and it doesn't bear much resemblance |
| // to sfdisk in actual use. |
| // |
| // by Rod Smith, project began February 2009; sgdisk begun January 2010. |
| |
| /* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed |
| under the terms of the GNU GPL version 2, as detailed in the COPYING file. */ |
| |
| #include <iostream> |
| #include <fstream> |
| #include <string.h> |
| #include <string> |
| #include <iostream> |
| #include <sstream> |
| #include <errno.h> |
| #include "gptcl.h" |
| #include <fcntl.h> |
| #include <unistd.h> |
| |
| using namespace std; |
| |
| #define MAX_OPTIONS 50 |
| |
| /* |
| * Dump partition details in a machine readable format: |
| * |
| * DISK [mbr|gpt] [guid] |
| * PART [n] [type] [guid] |
| */ |
| static int android_dump(char* device) { |
| BasicMBRData mbrData; |
| GPTData gptData; |
| GPTPart partData; |
| int numParts = 0; |
| stringstream res; |
| |
| /* Silence noisy underlying library */ |
| int stdout = dup(STDOUT_FILENO); |
| int silence = open("/dev/null", 0); |
| dup2(silence, STDOUT_FILENO); |
| dup2(silence, STDERR_FILENO); |
| |
| if (!mbrData.ReadMBRData((string) device)) { |
| cerr << "Failed to read MBR" << endl; |
| return 8; |
| } |
| |
| switch (mbrData.GetValidity()) { |
| case mbr: |
| res << "DISK mbr" << endl; |
| for (int i = 0; i < MAX_MBR_PARTS; i++) { |
| if (mbrData.GetLength(i) > 0) { |
| res << "PART " << (i + 1) << " " << hex |
| << (int) mbrData.GetType(i) << dec << endl; |
| } |
| } |
| break; |
| case hybrid: |
| case gpt: |
| gptData.JustLooking(); |
| if (!gptData.LoadPartitions((string) device)) { |
| cerr << "Failed to read GPT" << endl; |
| return 9; |
| } |
| |
| res << "DISK gpt " << gptData.GetDiskGUID() << endl; |
| numParts = gptData.GetNumParts(); |
| for (int i = 0; i < numParts; i++) { |
| partData = gptData[i]; |
| if (partData.GetFirstLBA() > 0) { |
| res << "PART " << (i + 1) << " " << partData.GetType() << " " |
| << partData.GetUniqueGUID() << " " |
| << partData.GetDescription() << endl; |
| } |
| } |
| break; |
| default: |
| cerr << "Unknown partition table" << endl; |
| return 10; |
| } |
| |
| /* Write our actual output */ |
| string resString = res.str(); |
| write(stdout, resString.c_str(), resString.length()); |
| return 0; |
| } |
| |
| int main(int argc, char *argv[]) { |
| for (int i = 0; i < argc; i++) { |
| if (!strcmp("--android-dump", argv[i])) { |
| return android_dump(argv[i + 1]); |
| } |
| } |
| |
| GPTDataCL theGPT; |
| return theGPT.DoOptions(argc, argv); |
| } |