Revisions for 0.6.10 release
This commit is contained in:
22
NEWS
22
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
|
- Enable disk-wipe (-z and -Z) and verification (-v) operations in
|
||||||
(gdisk: 'u' on experts' menu; sgdisk: -R or --replicate option)
|
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):
|
0.6.9 (7/4/2010):
|
||||||
------------------
|
------------------
|
||||||
|
|||||||
163
attributes.cc
163
attributes.cc
@@ -8,36 +8,38 @@
|
|||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
#define __STDC_CONSTANT_MACROS
|
#define __STDC_CONSTANT_MACROS
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "attributes.h"
|
#include "attributes.h"
|
||||||
|
#include "support.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Constructor. Its main task is to initialize the attribute name
|
string Attributes::atNames[NUM_ATR];
|
||||||
// data.
|
Attributes::staticInit Attributes::staticInitializer;
|
||||||
Attributes::Attributes(void) {
|
|
||||||
int i;
|
|
||||||
ostringstream temp;
|
|
||||||
|
|
||||||
|
Attributes::staticInit::staticInit (void) {
|
||||||
|
ostringstream temp;
|
||||||
|
|
||||||
// Most bits are undefined, so start by giving them an
|
// Most bits are undefined, so start by giving them an
|
||||||
// appropriate name
|
// appropriate name
|
||||||
for (i = 1; i < NUM_ATR; i++) {
|
for (int i = 0; i < NUM_ATR; i++) {
|
||||||
|
temp.str("");
|
||||||
temp << "Undefined bit #" << i;
|
temp << "Undefined bit #" << i;
|
||||||
atNames[i] = temp.str();
|
Attributes::atNames[i] = temp.str();
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
// Now reset those names that are defined....
|
// Now reset those names that are defined....
|
||||||
atNames[0] = "system partition"; // required for computer to operate
|
Attributes::atNames[0] = "system partition"; // required for computer to operate
|
||||||
atNames[1] = "hide from EFI";
|
Attributes::atNames[1] = "hide from EFI";
|
||||||
atNames[2] = "legacy BIOS bootable";
|
Attributes::atNames[2] = "legacy BIOS bootable";
|
||||||
atNames[60] = "read-only";
|
Attributes::atNames[60] = "read-only";
|
||||||
atNames[62] = "hidden";
|
Attributes::atNames[62] = "hidden";
|
||||||
atNames[63] = "do not automount";
|
Attributes::atNames[63] = "do not automount";
|
||||||
} // Attributes constructor
|
} // Attributes::staticInit::staticInit
|
||||||
|
|
||||||
// Destructor.
|
// Destructor.
|
||||||
Attributes::~Attributes(void) {
|
Attributes::~Attributes(void) {
|
||||||
@@ -45,7 +47,8 @@ Attributes::~Attributes(void) {
|
|||||||
|
|
||||||
// Display current attributes to user
|
// Display current attributes to user
|
||||||
void Attributes::DisplayAttributes(void) {
|
void Attributes::DisplayAttributes(void) {
|
||||||
int i;
|
uint32_t i;
|
||||||
|
int numSet = 0;
|
||||||
|
|
||||||
cout << "Attribute value is ";
|
cout << "Attribute value is ";
|
||||||
cout.setf(ios::uppercase);
|
cout.setf(ios::uppercase);
|
||||||
@@ -53,37 +56,137 @@ void Attributes::DisplayAttributes(void) {
|
|||||||
cout.width(16);
|
cout.width(16);
|
||||||
cout << hex << attributes << dec << ". Set fields are:\n";
|
cout << hex << attributes << dec << ". Set fields are:\n";
|
||||||
for (i = 0; i < NUM_ATR; i++) {
|
for (i = 0; i < NUM_ATR; i++) {
|
||||||
if (((attributes >> i) % 2) == 1) { // bit is set
|
if ((UINT64_C(1) << i) & attributes) {
|
||||||
if (atNames[NUM_ATR - i - 1].substr(0, 9) != "Undefined")
|
cout << i << " (" << Attributes::GetAttributeName(i) << ")" << "\n";
|
||||||
cout << atNames[NUM_ATR - i - 1] << "\n";
|
numSet++;
|
||||||
} // if
|
} // if
|
||||||
} // for
|
} // for
|
||||||
cout.fill(' ');
|
cout.fill(' ');
|
||||||
|
if (numSet == 0)
|
||||||
|
cout << " No fields set\n";
|
||||||
|
cout << "\n";
|
||||||
} // Attributes::DisplayAttributes()
|
} // Attributes::DisplayAttributes()
|
||||||
|
|
||||||
// Prompt user for attribute changes
|
// Prompt user for attribute changes
|
||||||
void Attributes::ChangeAttributes(void) {
|
void Attributes::ChangeAttributes(void) {
|
||||||
int response, i;
|
int response;
|
||||||
uint64_t bitValue;
|
uint64_t bitValue;
|
||||||
|
|
||||||
cout << "Known attributes are:\n";
|
cout << "Known attributes are:\n";
|
||||||
for (i = 0; i < NUM_ATR; i++) {
|
ListAttributes();
|
||||||
if (atNames[i].substr(0, 9) != "Undefined")
|
cout << "\n";
|
||||||
cout << i << " - " << atNames[i] << "\n";
|
|
||||||
} // for
|
|
||||||
|
|
||||||
do {
|
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) {
|
if (response != 64) {
|
||||||
bitValue = PowerOf2(uint32_t (NUM_ATR - response - 1)); // Find the integer value of the bit
|
bitValue = UINT64_C(1) << response; // Find the integer value of the bit
|
||||||
if ((bitValue & attributes) == bitValue) { // bit is set
|
if (bitValue & attributes) { // bit is set
|
||||||
attributes -= bitValue; // so unset it
|
attributes &= ~bitValue; // so unset it
|
||||||
cout << "Have disabled the '" << atNames[response] << "' attribute.\n";
|
cout << "Have disabled the '" << atNames[response] << "' attribute.\n";
|
||||||
} else { // bit is not set
|
} else { // bit is not set
|
||||||
attributes += bitValue; // so set it
|
attributes |= bitValue; // so set it
|
||||||
cout << "Have enabled the '" << atNames[response] << "' attribute.\n";
|
cout << "Have enabled the '" << atNames[response] << "' attribute.\n";
|
||||||
} // if/else
|
} // if/else
|
||||||
} // if
|
} // if
|
||||||
} while (response != 64);
|
} while (response != 64);
|
||||||
} // Attributes::ChangeAttributes()
|
} // 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()
|
||||||
|
|||||||
22
attributes.h
22
attributes.h
@@ -2,10 +2,7 @@
|
|||||||
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
//#include <unistd.h>
|
#include <string>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "support.h"
|
|
||||||
|
|
||||||
#ifndef __GPT_ATTRIBUTES
|
#ifndef __GPT_ATTRIBUTES
|
||||||
#define __GPT_ATTRIBUTES
|
#define __GPT_ATTRIBUTES
|
||||||
@@ -16,16 +13,27 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class Attributes {
|
class Attributes {
|
||||||
|
|
||||||
|
private:
|
||||||
|
class staticInit {public: staticInit (void);};
|
||||||
|
static string atNames[NUM_ATR];
|
||||||
|
static Attributes::staticInit staticInitializer;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint64_t attributes;
|
uint64_t attributes;
|
||||||
string atNames[NUM_ATR];
|
|
||||||
public:
|
public:
|
||||||
Attributes(void);
|
Attributes(const uint64_t a = 0) {SetAttributes (a);}
|
||||||
~Attributes(void);
|
~Attributes(void);
|
||||||
void SetAttributes(uint64_t a) {attributes = a;}
|
void SetAttributes(const uint64_t a) {attributes = a;}
|
||||||
uint64_t GetAttributes(void) {return attributes;}
|
uint64_t GetAttributes(void) {return attributes;}
|
||||||
void DisplayAttributes(void);
|
void DisplayAttributes(void);
|
||||||
void ChangeAttributes(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
|
}; // class Attributes
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
18
current.spec
18
current.spec
@@ -1,11 +1,11 @@
|
|||||||
Summary: An fdisk-like partitioning tool for GPT disks
|
Summary: An fdisk-like partitioning tool for GPT disks
|
||||||
Name: gdisk
|
Name: gdisk
|
||||||
Version: 0.6.9
|
Version: 0.6.10
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
License: GPLv2
|
License: GPLv2
|
||||||
URL: http://www.rodsbooks.com/gdisk
|
URL: http://www.rodsbooks.com/gdisk
|
||||||
Group: Applications/System
|
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)
|
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@@ -23,9 +23,9 @@ CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_CXX_FLAGS" make
|
|||||||
|
|
||||||
%install
|
%install
|
||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
mkdir -p $RPM_BUILD_ROOT/sbin
|
mkdir -p $RPM_BUILD_ROOT/usr/sbin
|
||||||
install -Dp -m0755 gdisk $RPM_BUILD_ROOT/sbin
|
install -Dp -m0755 gdisk $RPM_BUILD_ROOT/usr/sbin
|
||||||
install -Dp -m0755 sgdisk $RPM_BUILD_ROOT/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 gdisk.8 $RPM_BUILD_ROOT/%{_mandir}/man8/gdisk.8
|
||||||
install -Dp -m0644 sgdisk.8 $RPM_BUILD_ROOT/%{_mandir}/man8/sgdisk.8
|
install -Dp -m0644 sgdisk.8 $RPM_BUILD_ROOT/%{_mandir}/man8/sgdisk.8
|
||||||
|
|
||||||
@@ -35,10 +35,10 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%files
|
%files
|
||||||
%defattr(-,root,root -)
|
%defattr(-,root,root -)
|
||||||
%doc NEWS COPYING README
|
%doc NEWS COPYING README
|
||||||
/sbin/gdisk
|
/usr/sbin/gdisk
|
||||||
/sbin/sgdisk
|
/usr/sbin/sgdisk
|
||||||
%doc %{_mandir}/man8*
|
%doc %{_mandir}/man8*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Sun Jul 4 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.9
|
* Sun Aug 22 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.10
|
||||||
- Created spec file for 0.6.9 release
|
- Created spec file for 0.6.10 release
|
||||||
|
|||||||
11
gdisk.8
11
gdisk.8
@@ -1,6 +1,6 @@
|
|||||||
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
|
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
|
||||||
.\" May be distributed under the GNU General Public License
|
.\" 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"
|
.SH "NAME"
|
||||||
gdisk \- Interactive GUID partition table (GPT) manipulator
|
gdisk \- Interactive GUID partition table (GPT) manipulator
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
@@ -524,6 +524,15 @@ results in a table with partitions numbered from 2\-5. Transposing
|
|||||||
partitions in this way has no effect on their disk space allocation; it
|
partitions in this way has no effect on their disk space allocation; it
|
||||||
only alters their order in the partition table.
|
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
|
.TP
|
||||||
.B v
|
.B v
|
||||||
Verify disk. This option is identical to the 'v' option in the main menu.
|
Verify disk. This option is identical to the 'v' option in the main menu.
|
||||||
|
|||||||
53
gpt.cc
53
gpt.cc
@@ -645,7 +645,7 @@ int GPTData::LoadPartitions(const string & deviceFilename) {
|
|||||||
break;
|
break;
|
||||||
case use_abort:
|
case use_abort:
|
||||||
allOK = 0;
|
allOK = 0;
|
||||||
cerr << "Aborting because of invalid partition data!\n";
|
cerr << "Invalid partition data!\n";
|
||||||
break;
|
break;
|
||||||
} // switch
|
} // switch
|
||||||
|
|
||||||
@@ -1510,7 +1510,7 @@ int GPTData::PartsToMBR(PartNotes & notes) {
|
|||||||
int mbrNum = 0, numConverted = 0;
|
int mbrNum = 0, numConverted = 0;
|
||||||
struct PartInfo convInfo;
|
struct PartInfo convInfo;
|
||||||
|
|
||||||
protectiveMBR.EmptyMBR();
|
protectiveMBR.EmptyMBR(0);
|
||||||
protectiveMBR.SetDiskSize(diskSize);
|
protectiveMBR.SetDiskSize(diskSize);
|
||||||
notes.Rewind();
|
notes.Rewind();
|
||||||
while (notes.GetNextInfo(&convInfo) >= 0) {
|
while (notes.GetNextInfo(&convInfo) >= 0) {
|
||||||
@@ -2205,7 +2205,7 @@ uint32_t GPTData::ComputeAlignment(void) {
|
|||||||
if (partitions[i].IsUsed()) {
|
if (partitions[i].IsUsed()) {
|
||||||
found = 0;
|
found = 0;
|
||||||
while (!found) {
|
while (!found) {
|
||||||
align = PowerOf2(exponent);
|
align = UINT64_C(1)<<exponent;
|
||||||
if ((partitions[i].GetFirstLBA() % align) == 0) {
|
if ((partitions[i].GetFirstLBA() % align) == 0) {
|
||||||
found = 1;
|
found = 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -2252,6 +2252,53 @@ void GPTData::ReversePartitionBytes() {
|
|||||||
} // for
|
} // for
|
||||||
} // GPTData::ReversePartitionBytes()
|
} // 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 *
|
* Additional non-class support functions *
|
||||||
|
|||||||
9
gpt.h
9
gpt.h
@@ -16,7 +16,7 @@
|
|||||||
#ifndef __GPTSTRUCTS
|
#ifndef __GPTSTRUCTS
|
||||||
#define __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-
|
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
|
||||||
// numbered value to refer to partition numbers. (Most will be 0 or positive,
|
// numbered value to refer to partition numbers. (Most will be 0 or positive,
|
||||||
@@ -179,6 +179,7 @@ public:
|
|||||||
uint64_t GetPartFirstLBA(uint32_t i) {return partitions[i].GetFirstLBA();}
|
uint64_t GetPartFirstLBA(uint32_t i) {return partitions[i].GetFirstLBA();}
|
||||||
uint64_t GetPartLastLBA(uint32_t i) {return partitions[i].GetLastLBA();}
|
uint64_t GetPartLastLBA(uint32_t i) {return partitions[i].GetLastLBA();}
|
||||||
uint32_t CountParts(void);
|
uint32_t CountParts(void);
|
||||||
|
bool ValidPartNum (const uint32_t partNum);
|
||||||
|
|
||||||
// Find information about free space
|
// Find information about free space
|
||||||
uint64_t FindFirstAvailable(uint64_t start = 0);
|
uint64_t FindFirstAvailable(uint64_t start = 0);
|
||||||
@@ -200,6 +201,12 @@ public:
|
|||||||
// Endianness functions
|
// Endianness functions
|
||||||
void ReverseHeaderBytes(struct GPTHeader* header);
|
void ReverseHeaderBytes(struct GPTHeader* header);
|
||||||
void ReversePartitionBytes(); // for endianness
|
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
|
}; // class GPTData
|
||||||
|
|
||||||
// Function prototypes....
|
// Function prototypes....
|
||||||
|
|||||||
@@ -266,7 +266,6 @@ void GPTDataTextUI::SetAttributes(uint32_t partNum) {
|
|||||||
Attributes theAttr;
|
Attributes theAttr;
|
||||||
|
|
||||||
theAttr.SetAttributes(partitions[partNum].GetAttributes());
|
theAttr.SetAttributes(partitions[partNum].GetAttributes());
|
||||||
theAttr.DisplayAttributes();
|
|
||||||
theAttr.ChangeAttributes();
|
theAttr.ChangeAttributes();
|
||||||
partitions[partNum].SetAttributes(theAttr.GetAttributes());
|
partitions[partNum].SetAttributes(theAttr.GetAttributes());
|
||||||
} // GPTDataTextUI::SetAttributes()
|
} // GPTDataTextUI::SetAttributes()
|
||||||
|
|||||||
25
sgdisk.8
25
sgdisk.8
@@ -1,6 +1,6 @@
|
|||||||
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
|
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
|
||||||
.\" May be distributed under the GNU General Public License
|
.\" 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"
|
.SH "NAME"
|
||||||
sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
|
sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
@@ -153,6 +153,20 @@ freshly formatted disks. This alignment value is necessary to obtain optimum
|
|||||||
performance with Western Digital Advanced Format and similar drives with larger
|
performance with Western Digital Advanced Format and similar drives with larger
|
||||||
physical than logical sector sizes and with some types of RAID arrays.
|
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
|
.TP
|
||||||
.B \-b, \-\-backup=file
|
.B \-b, \-\-backup=file
|
||||||
Save partition data to a backup file. You can back up your current
|
Save partition data to a backup file. You can back up your current
|
||||||
@@ -210,7 +224,7 @@ that follows the backup GPT data structures. This command moves the backup
|
|||||||
GPT data structures to the end of the disk, where they belong.
|
GPT data structures to the end of the disk, where they belong.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B E, \-\-end\-of\-largest
|
.B \-E, \-\-end\-of\-largest
|
||||||
Displays the sector number of the end of the largest available block of
|
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
|
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
|
part of \fI\-n\fR's option to create a partition. If no unallocated
|
||||||
@@ -339,6 +353,13 @@ table with partitions numbered from 2\-5. Transposing partitions in this
|
|||||||
way has no effect on their disk space allocation; it only alters their
|
way has no effect on their disk space allocation; it only alters their
|
||||||
order in the partition table.
|
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
|
.TP
|
||||||
.B \-s, \-\-sort
|
.B \-s, \-\-sort
|
||||||
Sort partition entries. GPT partition numbers need not match the order of
|
Sort partition entries. GPT partition numbers need not match the order of
|
||||||
|
|||||||
92
sgdisk.cc
92
sgdisk.cc
@@ -19,13 +19,12 @@
|
|||||||
#include "gpt.h"
|
#include "gpt.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "parttypes.h"
|
#include "parttypes.h"
|
||||||
|
#include "attributes.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define MAX_OPTIONS 50
|
#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 BuildMBR(GPTData* theGPT, char* argument, int isHybrid);
|
||||||
int CountColons(char* argument);
|
int CountColons(char* argument);
|
||||||
|
|
||||||
@@ -39,15 +38,18 @@ int main(int argc, char *argv[]) {
|
|||||||
unsigned int hexCode;
|
unsigned int hexCode;
|
||||||
uint32_t tableSize = 128;
|
uint32_t tableSize = 128;
|
||||||
uint64_t startSector, endSector;
|
uint64_t startSector, endSector;
|
||||||
|
char *attributeOperation = NULL;
|
||||||
char *device = NULL;
|
char *device = NULL;
|
||||||
char *newPartInfo = NULL, *typeCode = NULL, *partName = NULL;
|
char *newPartInfo = NULL, *typeCode = NULL, *partName = NULL;
|
||||||
char *backupFile = NULL, *twoParts = NULL, *hybrids = NULL, *mbrParts;
|
char *backupFile = NULL, *twoParts = NULL, *hybrids = NULL, *mbrParts;
|
||||||
char *partGUID = NULL, *diskGUID = NULL, *outDevice = NULL;
|
char *partGUID = NULL, *diskGUID = NULL, *outDevice = NULL;
|
||||||
|
string cmd;
|
||||||
PartType typeHelper;
|
PartType typeHelper;
|
||||||
|
|
||||||
poptContext poptCon;
|
poptContext poptCon;
|
||||||
struct poptOption theOptions[] =
|
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"},
|
{"set-alignment", 'a', POPT_ARG_INT, &alignment, 'a', "set sector alignment", "value"},
|
||||||
{"backup", 'b', POPT_ARG_STRING, &backupFile, 'b', "backup GPT to file", "file"},
|
{"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"},
|
{"change-name", 'c', POPT_ARG_STRING, &partName, 'c', "change partition's name", "partnum:name"},
|
||||||
@@ -98,6 +100,11 @@ int main(int argc, char *argv[]) {
|
|||||||
// with options that don't require a device filename....
|
// with options that don't require a device filename....
|
||||||
while ((opt = poptGetNextOpt(poptCon)) > 0) {
|
while ((opt = poptGetNextOpt(poptCon)) > 0) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'A':
|
||||||
|
cmd = GetString(attributeOperation, 1);
|
||||||
|
if (cmd == "list")
|
||||||
|
Attributes::ListAttributes();
|
||||||
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
typeHelper.ShowAllTypes();
|
typeHelper.ShowAllTypes();
|
||||||
break;
|
break;
|
||||||
@@ -125,6 +132,25 @@ int main(int argc, char *argv[]) {
|
|||||||
saveNonGPT = 0; // flag so we don't overwrite unless directed to do so
|
saveNonGPT = 0; // flag so we don't overwrite unless directed to do so
|
||||||
while ((opt = poptGetNextOpt(poptCon)) > 0) {
|
while ((opt = poptGetNextOpt(poptCon)) > 0) {
|
||||||
switch (opt) {
|
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':
|
case 'a':
|
||||||
theGPT.SetAlignment(alignment);
|
theGPT.SetAlignment(alignment);
|
||||||
break;
|
break;
|
||||||
@@ -339,6 +365,31 @@ int main(int argc, char *argv[]) {
|
|||||||
retval = 4;
|
retval = 4;
|
||||||
} // if
|
} // if
|
||||||
} else { // if loaded OK
|
} 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;
|
retval = 2;
|
||||||
} // if/else loaded OK
|
} // if/else loaded OK
|
||||||
} // if (device != NULL)
|
} // if (device != NULL)
|
||||||
@@ -347,43 +398,6 @@ int main(int argc, char *argv[]) {
|
|||||||
return retval;
|
return retval;
|
||||||
} // main
|
} // 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
|
// Create a hybrid or regular MBR from GPT data structures
|
||||||
int BuildMBR(GPTData* theGPT, char* argument, int isHybrid) {
|
int BuildMBR(GPTData* theGPT, char* argument, int isHybrid) {
|
||||||
int numParts, allOK = 1, i;
|
int numParts, allOK = 1, i;
|
||||||
|
|||||||
41
support.cc
41
support.cc
@@ -244,16 +244,35 @@ void ReverseBytes(void* theValue, int numBytes) {
|
|||||||
} // if
|
} // if
|
||||||
} // ReverseBytes()
|
} // ReverseBytes()
|
||||||
|
|
||||||
// Compute (2 ^ value). Given the return type, value must be 63 or less.
|
// Extract integer data from argument string, which should be colon-delimited
|
||||||
// Used in some bit-fiddling functions
|
uint64_t GetInt(const string & argument, int itemNum) {
|
||||||
uint64_t PowerOf2(uint32_t value) {
|
int startPos = -1, endPos = -1;
|
||||||
uint64_t retval = 1;
|
uint64_t retval = 0;
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
if (value < 64) {
|
while (itemNum-- > 0) {
|
||||||
for (i = 0; i < value; i++) {
|
startPos = endPos + 1;
|
||||||
retval *= 2;
|
endPos = argument.find(':', startPos);
|
||||||
} // for
|
}
|
||||||
} else retval = 0;
|
if (endPos == (int) string::npos)
|
||||||
|
endPos = argument.length();
|
||||||
|
endPos--;
|
||||||
|
|
||||||
|
istringstream inString(argument.substr(startPos, endPos - startPos + 1));
|
||||||
|
inString >> retval;
|
||||||
return 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()
|
||||||
@@ -55,6 +55,9 @@ string BytesToSI(uint64_t size);
|
|||||||
unsigned char StrToHex(const string & input, unsigned int position);
|
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
|
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
|
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
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user