Revisions for 0.6.10 release
diff --git a/NEWS b/NEWS
index 26c666b..777bb8e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,22 @@
-0.6.10 (??/??/2010):
---------------------
+0.6.10 (8/22/2010):
+-------------------
-- Added ability to save partition table from one device to another
- (gdisk: 'u' on experts' menu; sgdisk: -R or --replicate option)
+- Enable disk-wipe (-z and -Z) and verification (-v) operations in
+ sgdisk even if the disk is badly damaged.
+
+- Added support for setting attributes in sgdisk (-A/--attributes option)
+ in sgdisk.
+
+- Fixed bug that created backwards attribute field values (bit #2 was
+ entered as bit #61, etc.).
+
+- Fixed bug that caused creation of hybrid MBR to wipe out the MBR's boot
+ code.
+
+- Added ability to save partition table from one device to another (gdisk:
+ 'u' on experts' menu; sgdisk: -R or --replicate option).
+
+- Fixed inaccessible -C/--recompute-chs option in sgdisk.
0.6.9 (7/4/2010):
------------------
diff --git a/attributes.cc b/attributes.cc
index 527dc87..c9c1d23 100644
--- a/attributes.cc
+++ b/attributes.cc
@@ -8,36 +8,38 @@
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
-#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
+
#include "attributes.h"
+#include "support.h"
using namespace std;
-// Constructor. Its main task is to initialize the attribute name
-// data.
-Attributes::Attributes(void) {
- int i;
- ostringstream temp;
+string Attributes::atNames[NUM_ATR];
+Attributes::staticInit Attributes::staticInitializer;
+Attributes::staticInit::staticInit (void) {
+ ostringstream temp;
+
// Most bits are undefined, so start by giving them an
// appropriate name
- for (i = 1; i < NUM_ATR; i++) {
+ for (int i = 0; i < NUM_ATR; i++) {
+ temp.str("");
temp << "Undefined bit #" << i;
- atNames[i] = temp.str();
+ Attributes::atNames[i] = temp.str();
} // for
// Now reset those names that are defined....
- atNames[0] = "system partition"; // required for computer to operate
- atNames[1] = "hide from EFI";
- atNames[2] = "legacy BIOS bootable";
- atNames[60] = "read-only";
- atNames[62] = "hidden";
- atNames[63] = "do not automount";
-} // Attributes constructor
+ Attributes::atNames[0] = "system partition"; // required for computer to operate
+ Attributes::atNames[1] = "hide from EFI";
+ Attributes::atNames[2] = "legacy BIOS bootable";
+ Attributes::atNames[60] = "read-only";
+ Attributes::atNames[62] = "hidden";
+ Attributes::atNames[63] = "do not automount";
+} // Attributes::staticInit::staticInit
// Destructor.
Attributes::~Attributes(void) {
@@ -45,7 +47,8 @@
// Display current attributes to user
void Attributes::DisplayAttributes(void) {
- int i;
+ uint32_t i;
+ int numSet = 0;
cout << "Attribute value is ";
cout.setf(ios::uppercase);
@@ -53,37 +56,137 @@
cout.width(16);
cout << hex << attributes << dec << ". Set fields are:\n";
for (i = 0; i < NUM_ATR; i++) {
- if (((attributes >> i) % 2) == 1) { // bit is set
- if (atNames[NUM_ATR - i - 1].substr(0, 9) != "Undefined")
- cout << atNames[NUM_ATR - i - 1] << "\n";
+ if ((UINT64_C(1) << i) & attributes) {
+ cout << i << " (" << Attributes::GetAttributeName(i) << ")" << "\n";
+ numSet++;
} // if
} // for
cout.fill(' ');
+ if (numSet == 0)
+ cout << " No fields set\n";
+ cout << "\n";
} // Attributes::DisplayAttributes()
// Prompt user for attribute changes
void Attributes::ChangeAttributes(void) {
- int response, i;
+ int response;
uint64_t bitValue;
cout << "Known attributes are:\n";
- for (i = 0; i < NUM_ATR; i++) {
- if (atNames[i].substr(0, 9) != "Undefined")
- cout << i << " - " << atNames[i] << "\n";
- } // for
+ ListAttributes();
+ cout << "\n";
do {
- response = GetNumber(0, 64, -1, (string) "Toggle which attribute field (0-63, 64 to exit): ");
+ DisplayAttributes();
+ response = GetNumber(0, NUM_ATR, -1, "Toggle which attribute field (0-63, 64 to exit): ");
if (response != 64) {
- bitValue = PowerOf2(uint32_t (NUM_ATR - response - 1)); // Find the integer value of the bit
- if ((bitValue & attributes) == bitValue) { // bit is set
- attributes -= bitValue; // so unset it
- cout << "Have disabled the '" << atNames[response] << "' attribute.\n";
+ bitValue = UINT64_C(1) << response; // Find the integer value of the bit
+ if (bitValue & attributes) { // bit is set
+ attributes &= ~bitValue; // so unset it
+ cout << "Have disabled the '" << atNames[response] << "' attribute.\n";
} else { // bit is not set
- attributes += bitValue; // so set it
+ attributes |= bitValue; // so set it
cout << "Have enabled the '" << atNames[response] << "' attribute.\n";
} // if/else
} // if
} while (response != 64);
} // Attributes::ChangeAttributes()
+// Display all defined attributes on the screen (omits undefined bits).
+void Attributes::ListAttributes(void) {
+ uint32_t bitNum;
+ string tempAttr;
+
+ for (bitNum = 0; bitNum < NUM_ATR; bitNum++) {
+ tempAttr = GetAttributeName(bitNum);
+ if (tempAttr.substr(0, 15) != "Undefined bit #" )
+ cout << bitNum << ": " << Attributes::GetAttributeName(bitNum) << "\n";
+ } // for
+} // Attributes::ListAttributes
+
+void Attributes::ShowAttributes(const uint32_t partNum) {
+ uint32_t bitNum;
+ bool bitset;
+
+ for (bitNum = 0; bitNum < 64; bitNum++) {
+ bitset = (UINT64_C(1) << bitNum) & attributes;
+ if (bitset) {
+ cout << partNum+1 << ":" << bitNum << ":" << bitset
+ << " (" << Attributes::GetAttributeName(bitNum) << ")" << endl;
+ } // if
+ } // for
+} // Attributes::ShowAttributes
+
+// multifaceted attributes access
+// returns true upon success, false upon failure
+bool Attributes::OperateOnAttributes(const uint32_t partNum, const string& attributeOperator, const string& attributeBits) {
+
+ // attribute access opcode
+ typedef enum {
+ ao_or, ao_nand, ao_xor, ao_assignall, // operate on all attributes (bitmask)
+ ao_unknown, // must be after bitmask operators and before bitnum operators
+ ao_set, ao_clear, ao_toggle, ao_get // operate on a single attribute (bitnum)
+ } attribute_opcode_t; // typedef enum
+
+ // translate attribute operator into an attribute opcode
+ attribute_opcode_t attributeOpcode = ao_unknown; { // opcode is not known yet
+ if (attributeOperator == "or") attributeOpcode = ao_or;
+ else if (attributeOperator == "nand") attributeOpcode = ao_nand;
+ else if (attributeOperator == "xor") attributeOpcode = ao_xor;
+ else if (attributeOperator == "=") attributeOpcode = ao_assignall;
+ else if (attributeOperator == "set") attributeOpcode = ao_set;
+ else if (attributeOperator == "clear") attributeOpcode = ao_clear;
+ else if (attributeOperator == "toggle") attributeOpcode = ao_toggle;
+ else if (attributeOperator == "get") attributeOpcode = ao_get;
+ else {
+ cerr << "Unknown attributes operator: " << attributeOperator << endl;
+ return false;
+ } // else
+ } // attributeOpcode
+
+ // get bit mask if operating on entire attribute set
+ uint64_t attributeBitMask; { if (attributeOpcode < ao_unknown) {
+ if (1 != sscanf (attributeBits.c_str(), "%qx", (long long unsigned int*) &attributeBitMask)) {
+ cerr << "Could not convert hex attribute mask" << endl;
+ return false;
+ } // if
+ }} // attributeBitMask, if
+
+ // get bit number and calculate bit mask if operating on a single attribute
+ int bitNum; { if (attributeOpcode > ao_unknown) {
+ if (1 != sscanf (attributeBits.c_str(), "%d", &bitNum)) {
+ cerr << "Could not convert bit number" << endl;
+ return false;
+ } // if
+ const uint64_t one = 1;
+ attributeBitMask = one << bitNum;
+ }} // bitNum, if
+
+ switch (attributeOpcode) {
+ // assign all attributes at once
+ case ao_assignall: attributes = attributeBitMask; break;
+
+ // set individual attribute(s)
+ case ao_set:
+ case ao_or: attributes |= attributeBitMask; break;
+
+ // clear individual attribute(s)
+ case ao_clear:
+ case ao_nand: attributes &= ~attributeBitMask; break;
+
+ // toggle individual attribute(s)
+ case ao_toggle:
+ case ao_xor: attributes ^= attributeBitMask; break;
+
+ // display a single attribute
+ case ao_get: {
+ cout << partNum+1 << ":" << bitNum << ":" <<
+ bool (attributeBitMask & attributes) << endl;
+ break;
+ } // case ao_get
+
+ default: break; // will never get here
+ } // switch
+
+ return true;
+} // Attributes::OperateOnAttributes()
diff --git a/attributes.h b/attributes.h
index ab8cb14..34cf258 100644
--- a/attributes.h
+++ b/attributes.h
@@ -2,10 +2,7 @@
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
#include <stdint.h>
-//#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include "support.h"
+#include <string>
#ifndef __GPT_ATTRIBUTES
#define __GPT_ATTRIBUTES
@@ -16,16 +13,27 @@
using namespace std;
class Attributes {
+
+private:
+ class staticInit {public: staticInit (void);};
+ static string atNames[NUM_ATR];
+ static Attributes::staticInit staticInitializer;
+
protected:
uint64_t attributes;
- string atNames[NUM_ATR];
+
public:
- Attributes(void);
+ Attributes(const uint64_t a = 0) {SetAttributes (a);}
~Attributes(void);
- void SetAttributes(uint64_t a) {attributes = a;}
+ void SetAttributes(const uint64_t a) {attributes = a;}
uint64_t GetAttributes(void) {return attributes;}
void DisplayAttributes(void);
void ChangeAttributes(void);
+ void ShowAttributes(const uint32_t partNum);
+ bool OperateOnAttributes(const uint32_t partNum, const string& attributeOperator, const string& attributeBits);
+
+ static const string& GetAttributeName(const uint32_t bitNum) {return atNames [bitNum];}
+ static void ListAttributes(void);
}; // class Attributes
#endif
diff --git a/current.spec b/current.spec
index 600c21b..009de63 100644
--- a/current.spec
+++ b/current.spec
@@ -1,11 +1,11 @@
Summary: An fdisk-like partitioning tool for GPT disks
Name: gdisk
-Version: 0.6.9
+Version: 0.6.10
Release: 1%{?dist}
License: GPLv2
URL: http://www.rodsbooks.com/gdisk
Group: Applications/System
-Source: http://www.rodsbooks.com/gdisk/gdisk-0.6.9.tgz
+Source: http://www.rodsbooks.com/gdisk/gdisk-0.6.10.tgz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%description
@@ -23,9 +23,9 @@
%install
rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT/sbin
-install -Dp -m0755 gdisk $RPM_BUILD_ROOT/sbin
-install -Dp -m0755 sgdisk $RPM_BUILD_ROOT/sbin
+mkdir -p $RPM_BUILD_ROOT/usr/sbin
+install -Dp -m0755 gdisk $RPM_BUILD_ROOT/usr/sbin
+install -Dp -m0755 sgdisk $RPM_BUILD_ROOT/usr/sbin
install -Dp -m0644 gdisk.8 $RPM_BUILD_ROOT/%{_mandir}/man8/gdisk.8
install -Dp -m0644 sgdisk.8 $RPM_BUILD_ROOT/%{_mandir}/man8/sgdisk.8
@@ -35,10 +35,10 @@
%files
%defattr(-,root,root -)
%doc NEWS COPYING README
-/sbin/gdisk
-/sbin/sgdisk
+/usr/sbin/gdisk
+/usr/sbin/sgdisk
%doc %{_mandir}/man8*
%changelog
-* Sun Jul 4 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.9
-- Created spec file for 0.6.9 release
+* Sun Aug 22 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.10
+- Created spec file for 0.6.10 release
diff --git a/gdisk.8 b/gdisk.8
index e11df37..76600fc 100644
--- a/gdisk.8
+++ b/gdisk.8
@@ -1,6 +1,6 @@
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
-.TH "GDISK" "8" "0.6.9" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "GDISK" "8" "0.6.10" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME"
gdisk \- Interactive GUID partition table (GPT) manipulator
.SH "SYNOPSIS"
@@ -524,6 +524,15 @@
partitions in this way has no effect on their disk space allocation; it
only alters their order in the partition table.
+.TP
+.B u
+Replicate the current device's partition table on another device. You will
+be prompted to type the new device's filename. After the write operation
+completes, you can continue editing the original device's partition table.
+Note that the replicated partition table is an exact copy, including all
+GUIDs; if the device should have its own unique GUIDs, you should use the
+\fBf\fR option on the new disk.
+
.TP
.B v
Verify disk. This option is identical to the 'v' option in the main menu.
diff --git a/gpt.cc b/gpt.cc
index 9bebb12..7dcbc86 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -645,7 +645,7 @@
break;
case use_abort:
allOK = 0;
- cerr << "Aborting because of invalid partition data!\n";
+ cerr << "Invalid partition data!\n";
break;
} // switch
@@ -1510,7 +1510,7 @@
int mbrNum = 0, numConverted = 0;
struct PartInfo convInfo;
- protectiveMBR.EmptyMBR();
+ protectiveMBR.EmptyMBR(0);
protectiveMBR.SetDiskSize(diskSize);
notes.Rewind();
while (notes.GetNextInfo(&convInfo) >= 0) {
@@ -2205,7 +2205,7 @@
if (partitions[i].IsUsed()) {
found = 0;
while (!found) {
- align = PowerOf2(exponent);
+ align = UINT64_C(1)<<exponent;
if ((partitions[i].GetFirstLBA() % align) == 0) {
found = 1;
} else {
@@ -2252,6 +2252,53 @@
} // for
} // GPTData::ReversePartitionBytes()
+// Validate partition number
+bool GPTData::ValidPartNum (const uint32_t partNum) {
+ if (partNum >= numParts) {
+ cerr << "Partition number out of range: " << (signed) partNum << endl;
+ return false;
+ } // if
+ return true;
+} // GPTData::ValidPartNum
+
+// Manage attributes for a partition, based on commands passed to this function.
+// (Function is non-interactive.)
+// Returns 1 if a modification command succeeded, 0 if the command should not have
+// modified data, and -1 if a modification command failed.
+int GPTData::ManageAttributes(int partNum, const string & command, const string & bits) {
+ int retval = 0;
+ Attributes theAttr;
+
+ if (command == "show") {
+ ShowAttributes(partNum);
+ } else if (command == "get") {
+ GetAttribute(partNum, bits);
+ } else {
+ theAttr = partitions[partNum].GetAttributes();
+ if (theAttr.OperateOnAttributes(partNum, command, bits)) {
+ partitions[partNum].SetAttributes(theAttr.GetAttributes());
+ retval = 1;
+ } else {
+ retval = -1;
+ } // if/else
+ } // if/elseif/else
+
+ return retval;
+} // GPTData::ManageAttributes()
+
+// Show all attributes for a specified partition....
+void GPTData::ShowAttributes(const uint32_t partNum) {
+ Attributes theAttr (partitions[partNum].GetAttributes());
+ theAttr.ShowAttributes(partNum);
+} // GPTData::ShowAttributes
+
+// Show whether a single attribute bit is set (terse output)...
+void GPTData::GetAttribute(const uint32_t partNum, const string& attributeBits) {
+ Attributes theAttr (partitions[partNum].GetAttributes());
+ theAttr.OperateOnAttributes(partNum, "get", attributeBits);
+} // GPTData::GetAttribute
+
+
/******************************************
* *
* Additional non-class support functions *
diff --git a/gpt.h b/gpt.h
index 4ead25a..4f0ccf7 100644
--- a/gpt.h
+++ b/gpt.h
@@ -16,7 +16,7 @@
#ifndef __GPTSTRUCTS
#define __GPTSTRUCTS
-#define GPTFDISK_VERSION "0.6.10-pre1"
+#define GPTFDISK_VERSION "0.6.10"
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
// numbered value to refer to partition numbers. (Most will be 0 or positive,
@@ -179,6 +179,7 @@
uint64_t GetPartFirstLBA(uint32_t i) {return partitions[i].GetFirstLBA();}
uint64_t GetPartLastLBA(uint32_t i) {return partitions[i].GetLastLBA();}
uint32_t CountParts(void);
+ bool ValidPartNum (const uint32_t partNum);
// Find information about free space
uint64_t FindFirstAvailable(uint64_t start = 0);
@@ -200,6 +201,12 @@
// Endianness functions
void ReverseHeaderBytes(struct GPTHeader* header);
void ReversePartitionBytes(); // for endianness
+
+ // Attributes functions
+ int ManageAttributes(int partNum, const string & command, const string & bits);
+ void ShowAttributes(const uint32_t partNum);
+ void GetAttribute(const uint32_t partNum, const string& attributeBits);
+
}; // class GPTData
// Function prototypes....
diff --git a/gpttext.cc b/gpttext.cc
index fe64be0..c37e01e 100644
--- a/gpttext.cc
+++ b/gpttext.cc
@@ -266,7 +266,6 @@
Attributes theAttr;
theAttr.SetAttributes(partitions[partNum].GetAttributes());
- theAttr.DisplayAttributes();
theAttr.ChangeAttributes();
partitions[partNum].SetAttributes(theAttr.GetAttributes());
} // GPTDataTextUI::SetAttributes()
diff --git a/sgdisk.8 b/sgdisk.8
index 1855bcd..ecb37d3 100644
--- a/sgdisk.8
+++ b/sgdisk.8
@@ -1,6 +1,6 @@
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
-.TH "SGDISK" "8" "0.6.9" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "SGDISK" "8" "0.6.10" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME"
sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
.SH "SYNOPSIS"
@@ -153,6 +153,20 @@
performance with Western Digital Advanced Format and similar drives with larger
physical than logical sector sizes and with some types of RAID arrays.
+.TP
+.B \-A, \-\-attributes=list|[partnum:show|or|nand|xor|=|set|clear|toggle|get[:bitnum|hexbitmask]]
+View or set partition attributes. Use \fIlist\fR to see defined (known)
+attribute values. Omit the partition number (and even the device filename)
+when using this option. The others require a partition number. The
+\fIshow\fR and \fIget\fR options show the current attribute settings
+(all attributes or for a particular bit, respectively). The \fIor\fR,
+\fInand\fR, \fIxor\fR, \fI\=\fR, \fIset\fR, \fIclear\fR, and
+\fItoggle\fR options enable you to change the attribute bit value. The
+\fIset\fR, \fIclear\fR, \fItoggle\fR, and \fIget\fR options work on a
+bit number; the others work on a hexadecimal bit mask. For example, type
+\fBsgdisk -A 4:set:2 /dev/sdc\fR to set the bit 2 attribute (legacy BIOS
+bootable) on partition 4 on \fI/dev/sdc\fR.
+
.TP
.B \-b, \-\-backup=file
Save partition data to a backup file. You can back up your current
@@ -210,7 +224,7 @@
GPT data structures to the end of the disk, where they belong.
.TP
-.B E, \-\-end\-of\-largest
+.B \-E, \-\-end\-of\-largest
Displays the sector number of the end of the largest available block of
sectors on the disk. A script may store this value and pass it back as
part of \fI\-n\fR's option to create a partition. If no unallocated
@@ -339,6 +353,13 @@
way has no effect on their disk space allocation; it only alters their
order in the partition table.
+.TP
+.B \-R, \-\-replicate=second_device_filename
+Replicate the main device's partition table on the specified second device.
+Note that the replicated partition table is an exact copy, including all
+GUIDs; if the device should have its own unique GUIDs, you should use the
+\-G option on the new disk.
+
.TP
.B \-s, \-\-sort
Sort partition entries. GPT partition numbers need not match the order of
diff --git a/sgdisk.cc b/sgdisk.cc
index 537639d..3927d26 100644
--- a/sgdisk.cc
+++ b/sgdisk.cc
@@ -19,13 +19,12 @@
#include "gpt.h"
#include "support.h"
#include "parttypes.h"
+#include "attributes.h"
using namespace std;
#define MAX_OPTIONS 50
-uint64_t GetInt(char* Info, int itemNum);
-string GetString(char* Info, int itemNum);
int BuildMBR(GPTData* theGPT, char* argument, int isHybrid);
int CountColons(char* argument);
@@ -39,15 +38,18 @@
unsigned int hexCode;
uint32_t tableSize = 128;
uint64_t startSector, endSector;
+ char *attributeOperation = NULL;
char *device = NULL;
char *newPartInfo = NULL, *typeCode = NULL, *partName = NULL;
char *backupFile = NULL, *twoParts = NULL, *hybrids = NULL, *mbrParts;
char *partGUID = NULL, *diskGUID = NULL, *outDevice = NULL;
+ string cmd;
PartType typeHelper;
poptContext poptCon;
struct poptOption theOptions[] =
{
+ {"attributes", 'A', POPT_ARG_STRING, &attributeOperation, 'A', "operate on partition attributes", "list|[partnum:show|or|nand|xor|=|set|clear|toggle|get[:bitnum|hexbitmask]]"},
{"set-alignment", 'a', POPT_ARG_INT, &alignment, 'a', "set sector alignment", "value"},
{"backup", 'b', POPT_ARG_STRING, &backupFile, 'b', "backup GPT to file", "file"},
{"change-name", 'c', POPT_ARG_STRING, &partName, 'c', "change partition's name", "partnum:name"},
@@ -98,6 +100,11 @@
// with options that don't require a device filename....
while ((opt = poptGetNextOpt(poptCon)) > 0) {
switch (opt) {
+ case 'A':
+ cmd = GetString(attributeOperation, 1);
+ if (cmd == "list")
+ Attributes::ListAttributes();
+ break;
case 'L':
typeHelper.ShowAllTypes();
break;
@@ -125,6 +132,25 @@
saveNonGPT = 0; // flag so we don't overwrite unless directed to do so
while ((opt = poptGetNextOpt(poptCon)) > 0) {
switch (opt) {
+ case 'A': {
+ if (cmd != "list") {
+ partNum = (int) GetInt(attributeOperation, 1) - 1;
+ switch (theGPT.ManageAttributes(partNum, GetString(attributeOperation, 2),
+ GetString(attributeOperation, 3))) {
+ case -1:
+ saveData = 0;
+ neverSaveData = 1;
+ break;
+ case 1:
+ theGPT.JustLooking(0);
+ saveData = 1;
+ break;
+ default:
+ break;
+ } // switch
+ } // if
+ break;
+ } // case 'A':
case 'a':
theGPT.SetAlignment(alignment);
break;
@@ -339,6 +365,31 @@
retval = 4;
} // if
} else { // if loaded OK
+ poptResetContext(poptCon);
+ // Do a few types of operations even if there are problems....
+ while ((opt = poptGetNextOpt(poptCon)) > 0) {
+ switch (opt) {
+ case 'v':
+ cout << "Verification may miss some problems!\n";
+ theGPT.Verify();
+ break;
+ case 'z':
+ if (!pretend) {
+ theGPT.DestroyGPT();
+ } // if
+ saveNonGPT = 0;
+ saveData = 0;
+ break;
+ case 'Z':
+ if (!pretend) {
+ theGPT.DestroyGPT();
+ theGPT.DestroyMBR();
+ } // if
+ saveNonGPT = 0;
+ saveData = 0;
+ break;
+ } // switch
+ } // while
retval = 2;
} // if/else loaded OK
} // if (device != NULL)
@@ -347,43 +398,6 @@
return retval;
} // main
-// Extract integer data from argument string, which should be colon-delimited
-uint64_t GetInt(char* argument, int itemNum) {
- int startPos = -1, endPos = -1;
- uint64_t retval = 0;
- string Info;
-
- Info = argument;
- while (itemNum-- > 0) {
- startPos = endPos + 1;
- endPos = Info.find(':', startPos);
- }
- if (endPos == (int) string::npos)
- endPos = Info.length();
- endPos--;
-
- istringstream inString(Info.substr(startPos, endPos - startPos + 1));
- inString >> retval;
- return retval;
-} // GetInt()
-
-// Extract string data from argument string, which should be colon-delimited
-string GetString(char* argument, int itemNum) {
- int startPos = -1, endPos = -1;
- string Info;
-
- Info = argument;
- while (itemNum-- > 0) {
- startPos = endPos + 1;
- endPos = Info.find(':', startPos);
- }
- if (endPos == (int) string::npos)
- endPos = Info.length();
- endPos--;
-
- return Info.substr(startPos, endPos - startPos + 1);
-} // GetString()
-
// Create a hybrid or regular MBR from GPT data structures
int BuildMBR(GPTData* theGPT, char* argument, int isHybrid) {
int numParts, allOK = 1, i;
diff --git a/support.cc b/support.cc
index 11c6200..1711209 100644
--- a/support.cc
+++ b/support.cc
@@ -244,16 +244,35 @@
} // if
} // ReverseBytes()
-// Compute (2 ^ value). Given the return type, value must be 63 or less.
-// Used in some bit-fiddling functions
-uint64_t PowerOf2(uint32_t value) {
- uint64_t retval = 1;
- uint32_t i;
+// Extract integer data from argument string, which should be colon-delimited
+uint64_t GetInt(const string & argument, int itemNum) {
+ int startPos = -1, endPos = -1;
+ uint64_t retval = 0;
- if (value < 64) {
- for (i = 0; i < value; i++) {
- retval *= 2;
- } // for
- } else retval = 0;
+ while (itemNum-- > 0) {
+ startPos = endPos + 1;
+ endPos = argument.find(':', startPos);
+ }
+ if (endPos == (int) string::npos)
+ endPos = argument.length();
+ endPos--;
+
+ istringstream inString(argument.substr(startPos, endPos - startPos + 1));
+ inString >> retval;
return retval;
-} // PowerOf2()
+} // GetInt()
+
+// Extract string data from argument string, which should be colon-delimited
+string GetString(const string & argument, int itemNum) {
+ int startPos = -1, endPos = -1;
+
+ while (itemNum-- > 0) {
+ startPos = endPos + 1;
+ endPos = argument.find(':', startPos);
+ }
+ if (endPos == (int) string::npos)
+ endPos = argument.length();
+ endPos--;
+
+ return argument.substr(startPos, endPos - startPos + 1);
+} // GetString()
\ No newline at end of file
diff --git a/support.h b/support.h
index 8e29f7a..be55294 100644
--- a/support.h
+++ b/support.h
@@ -55,6 +55,9 @@
unsigned char StrToHex(const string & input, unsigned int position);
int IsLittleEndian(void); // Returns 1 if CPU is little-endian, 0 if it's big-endian
void ReverseBytes(void* theValue, int numBytes); // Reverses byte-order of theValue
-uint64_t PowerOf2(uint32_t value);
+
+// Extract colon-separated fields from a string....
+uint64_t GetInt(const string & argument, int itemNum);
+string GetString(const string & Info, int itemNum);
#endif