Removed libicu dependency for UTF-16 partition names. Version 0.8.9

release.
This commit is contained in:
Roderick W. Smith
2014-02-17 16:17:11 -05:00
parent 22e88b5be2
commit 84aaff6b9c
22 changed files with 277 additions and 114 deletions

View File

@@ -1,8 +1,8 @@
CC=gcc CC=gcc
CXX=g++ CXX=g++
CFLAGS+=-D_FILE_OFFSET_BITS=64 CFLAGS+=-D_FILE_OFFSET_BITS=64
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -D USE_UTF16 #CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -D USE_UTF16
#CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64
LDFLAGS+= LDFLAGS+=
LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
MBR_LIBS=support diskio diskio-unix basicmbr mbrpart MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
@@ -14,16 +14,16 @@ DEPEND= makedepend $(CXXFLAGS)
all: cgdisk gdisk sgdisk fixparts all: cgdisk gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o gdisk: $(LIB_OBJS) gdisk.o gpttext.o
# $(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -luuid -o gdisk $(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -luuid -o gdisk
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -licuio -licuuc -luuid -o gdisk # $(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -licuio -licuuc -luuid -o gdisk
cgdisk: $(LIB_OBJS) cgdisk.o gptcurses.o cgdisk: $(LIB_OBJS) cgdisk.o gptcurses.o
# $(CXX) $(LIB_OBJS) cgdisk.o gptcurses.o $(LDFLAGS) -luuid -lncurses -o cgdisk $(CXX) $(LIB_OBJS) cgdisk.o gptcurses.o $(LDFLAGS) -luuid -lncursesw -o cgdisk
$(CXX) $(LIB_OBJS) cgdisk.o gptcurses.o $(LDFLAGS) -licuio -licuuc -luuid -lncurses -o cgdisk # $(CXX) $(LIB_OBJS) cgdisk.o gptcurses.o $(LDFLAGS) -licuio -licuuc -luuid -lncurses -o cgdisk
sgdisk: $(LIB_OBJS) sgdisk.o gptcl.o sgdisk: $(LIB_OBJS) sgdisk.o gptcl.o
# $(CXX) $(LIB_OBJS) sgdisk.o gptcl.o $(LDFLAGS) -luuid -lpopt -o sgdisk $(CXX) $(LIB_OBJS) sgdisk.o gptcl.o $(LDFLAGS) -luuid -lpopt -o sgdisk
$(CXX) $(LIB_OBJS) sgdisk.o gptcl.o $(LDFLAGS) -licuio -licuuc -luuid -lpopt -o sgdisk # $(CXX) $(LIB_OBJS) sgdisk.o gptcl.o $(LDFLAGS) -licuio -licuuc -luuid -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts $(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts

View File

@@ -1,8 +1,8 @@
CC=gcc CC=gcc
CXX=g++ CXX=g++
CFLAGS+=-D_FILE_OFFSET_BITS=64 CFLAGS+=-D_FILE_OFFSET_BITS=64
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -D USE_UTF16 -I/usr/local/include #CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -D USE_UTF16 -I/usr/local/include
#CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -I /usr/local/include CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -I /usr/local/include
LDFLAGS+= LDFLAGS+=
LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
MBR_LIBS=support diskio diskio-unix basicmbr mbrpart MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
@@ -14,16 +14,16 @@ DEPEND= makedepend $(CXXFLAGS)
all: gdisk cgdisk sgdisk fixparts all: gdisk cgdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o gdisk: $(LIB_OBJS) gdisk.o gpttext.o
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o -L/usr/local/lib $(LDFLAGS) -licuio -luuid -o gdisk # $(CXX) $(LIB_OBJS) gdisk.o gpttext.o -L/usr/local/lib $(LDFLAGS) -licuio -luuid -o gdisk
# $(CXX) $(LIB_OBJS) gdisk.o gpttext.o -L/usr/local/lib $(LDFLAGS) -luuid -o gdisk $(CXX) $(LIB_OBJS) gdisk.o gpttext.o -L/usr/local/lib $(LDFLAGS) -luuid -o gdisk
cgdisk: $(LIB_OBJS) cgdisk.o gptcurses.o cgdisk: $(LIB_OBJS) cgdisk.o gptcurses.o
$(CXX) $(LIB_OBJS) cgdisk.o gptcurses.o -L/usr/local/lib $(LDFLAGS) -licuio -luuid -lncurses -o cgdisk # $(CXX) $(LIB_OBJS) cgdisk.o gptcurses.o -L/usr/local/lib $(LDFLAGS) -licuio -luuid -lncurses -o cgdisk
# $(CXX) $(LIB_OBJS) cgdisk.o gptcurses.o -L/usr/local/lib $(LDFLAGS) -luuid -lncurses -o cgdisk $(CXX) $(LIB_OBJS) cgdisk.o gptcurses.o -L/usr/local/lib $(LDFLAGS) -luuid -lncurses -o cgdisk
sgdisk: $(LIB_OBJS) sgdisk.o gptcl.o sgdisk: $(LIB_OBJS) sgdisk.o gptcl.o
$(CXX) $(LIB_OBJS) sgdisk.o gptcl.o -L/usr/local/lib $(LDFLAGS) -luuid -licuio -lpopt -o sgdisk # $(CXX) $(LIB_OBJS) sgdisk.o gptcl.o -L/usr/local/lib $(LDFLAGS) -luuid -licuio -lpopt -o sgdisk
# $(CXX) $(LIB_OBJS) sgdisk.o gptcl.o -L/usr/local/lib $(LDFLAGS) -luuid -lpopt -o sgdisk $(CXX) $(LIB_OBJS) sgdisk.o gptcl.o -L/usr/local/lib $(LDFLAGS) -luuid -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o -L/usr/local/lib $(LDFLAGS) -o fixparts $(CXX) $(MBR_LIB_OBJS) fixparts.o -L/usr/local/lib $(LDFLAGS) -o fixparts

16
NEWS
View File

@@ -1,15 +1,15 @@
0.8.9 (??/??/2014): 0.8.9 (2/17/2014):
------------------- ------------------
- Removed dependency on libicu for UTF-16 support.
- Fixed spurious "0xEE partition doesn't start on sector 1" warning in - Fixed spurious "0xEE partition doesn't start on sector 1" warning in
FixParts (and perhaps in other programs under some circumstances). FixParts (and perhaps in other programs under some circumstances).
- Added check for valid location of backup GPT data to GPT-destruction - Added GPT regeneration command to GPT-destruction options ('z' in gdisk,
options ('z' in gdisk, -z and -Z options to sgdisk). If the backup -z and -Z options to sgdisk). This is done to avoid wiping out data
GPT data structures aren't at the end of the disk, they aren't erased. mid-disk that might not be backup GPT data structures, which could
This is done to avoid wiping out data mid-disk that might not be backup otherwise occur if a RAID array was resized in certain ways.
GPT data structures, which could otherwise occur if a RAID array was
resized in certain ways.
- Added check for an oversized 0xEE protective partition. The program now - Added check for an oversized 0xEE protective partition. The program now
auto-repairs this condition on loading if the GPT data seem otherwise auto-repairs this condition on loading if the GPT data seem otherwise

22
README
View File

@@ -174,17 +174,17 @@ be used instead. In addition, note these requirements:
FreeBSD, the e2fsprogs-libuuid port must be installed. FreeBSD, the e2fsprogs-libuuid port must be installed.
* The ICU library (http://site.icu-project.org), which provides support for * The ICU library (http://site.icu-project.org), which provides support for
Unicode partition names, is recommended on all Unicode partition names, is optional on all platforms except Windows, on
platforms except Windows. This library is normally installed in Linux and which it's not supported. Using this library was required to get proper
OS X, but you may need to install the development headers (libicu-dev or UTF-16 partition name support in GPT fdisk versions prior to 0.8.9, but
something similar in Linux; or the libicu36-dev Fink package in OS X). To as of that version it should not longer be required. Nonetheless, you can
compile without ICU support, you must modify the Makefile: Remove the use it if you're having problems with the new UTF-16 support. This
"-D USE_UTF16" part from the CXXFLAGS line and remove references to library is normally installed in Linux and OS X, but you may need to
-licuio, -licuuc, -licudata, and -licucore (details vary between install the development headers (libicu-dev or something similar in
platforms) from the compilation options. Suitable lines are present, but Linux; or the libicu36-dev Fink package in OS X). To compile with ICU
commented out, in the Makefile, Makefile.solaris, Makefile.freebsd files. support, you must modify the Makefile: Look for commented-out lines that
Because of problems with ICU under OS X, the Makefile.mac file doesn't refer to USE_UTF16, -licuuc, -licudata, or -licucore. Uncomment them and
build against ICU by default. comment out the equivalents that lack these lines.
* The cgdisk program requires the ncurses library and its development files * The cgdisk program requires the ncurses library and its development files
(headers). Most Linux distributions install ncurses by default, but you (headers). Most Linux distributions install ncurses by default, but you

View File

@@ -671,7 +671,7 @@ int BasicMBRData::LBAtoCHS(uint64_t lba, uint8_t * chs) {
done = 1; done = 1;
} // if } // if
// If LBA value is too large for CHS, max out CHS values.... // If LBA value is too large for CHS, max out CHS values....
if ((!done) && (lba >= (numHeads * numSecspTrack * MAX_CYLINDERS))) { if ((!done) && (lba >= ((uint64_t) numHeads * numSecspTrack * MAX_CYLINDERS))) {
chs[0] = 254; chs[0] = 254;
chs[1] = chs[2] = 255; chs[1] = chs[2] = 255;
done = 1; done = 1;
@@ -1223,7 +1223,7 @@ void BasicMBRData::MaximizePrimaries() {
// Remove primary partitions in excess of 4, starting with the later ones, // Remove primary partitions in excess of 4, starting with the later ones,
// in terms of the array location.... // in terms of the array location....
void BasicMBRData::TrimPrimaries(void) { void BasicMBRData::TrimPrimaries(void) {
int numToDelete, i = MAX_MBR_PARTS; int numToDelete, i = MAX_MBR_PARTS - 1;
numToDelete = NumPrimaries() - 4; numToDelete = NumPrimaries() - 4;
while ((numToDelete > 0) && (i >= 0)) { while ((numToDelete > 0) && (i >= 0)) {

View File

@@ -1,6 +1,6 @@
.\" Copyright 2011-2013 Roderick W. Smith (rodsmith@rodsbooks.com) .\" Copyright 2011-2013 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 "CGDISK" "8" "0.8.8" "Roderick W. Smith" "GPT fdisk Manual" .TH "CGDISK" "8" "0.8.9" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME" .SH "NAME"
cgdisk \- Curses-based GUID partition table (GPT) manipulator cgdisk \- Curses-based GUID partition table (GPT) manipulator
.SH "SYNOPSIS" .SH "SYNOPSIS"
@@ -276,7 +276,7 @@ Write data. Use this command to save your changes.
.SH "BUGS" .SH "BUGS"
As of October 2013 (version 0.8.8), \fBcgdisk\fR should be considered As of February 2014 (version 0.8.9), \fBcgdisk\fR should be considered
beta software. Although the underlying partition manipulation code is much beta software. Although the underlying partition manipulation code is much
older, the \fBcgdisk\fR ncurses user interface is brand new with GPT fdisk older, the \fBcgdisk\fR ncurses user interface is brand new with GPT fdisk
version 0.8.0. Known bugs and limitations include: version 0.8.0. Known bugs and limitations include:

View File

@@ -75,4 +75,5 @@ int main(int argc, char *argv[]) {
} else { } else {
Report("Could not load partitions from '" + device + "'! Aborting!"); Report("Could not load partitions from '" + device + "'! Aborting!");
} // if/else } // if/else
return 0;
} // main } // main

View File

@@ -1,11 +1,11 @@
Summary: GPT partitioning and MBR repair software Summary: GPT partitioning and MBR repair software
Name: gptfdisk Name: gptfdisk
Version: 0.8.8 Version: 0.8.9
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/gptfdisk-0.8.8.tar.gz Source: http://www.rodsbooks.com/gdisk/gptfdisk-0.8.9.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%description %description
@@ -80,5 +80,5 @@ provides a few additional partition manipulation features.
%changelog %changelog
* Mon Oct 14 2013 R Smith <rodsmith@rodsbooks.com> - 0.8.8 * Mon Feb 17 2014 R Smith <rodsmith@rodsbooks.com> - 0.8.9
- Created spec file for 0.8.8 release - Created spec file for 0.8.9 release

View File

@@ -1,6 +1,6 @@
.\" Copyright 2011-2013 Roderick W. Smith (rodsmith@rodsbooks.com) .\" Copyright 2011-2013 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 "FIXPARTS" "8" "0.8.8" "Roderick W. Smith" "FixParts Manual" .TH "FIXPARTS" "8" "0.8.9" "Roderick W. Smith" "FixParts Manual"
.SH "NAME" .SH "NAME"
fixparts \- MBR partition table repair utility fixparts \- MBR partition table repair utility
.SH "SYNOPSIS" .SH "SYNOPSIS"
@@ -202,7 +202,7 @@ see a summary of available options.
.PP .PP
.SH "BUGS" .SH "BUGS"
As of October 2013 (version 0.8.8), \fBfixparts\fR As of February 2014 (version 0.8.9), \fBfixparts\fR
should be considered beta software. Known bugs and limitations include: should be considered beta software. Known bugs and limitations include:
.TP .TP

View File

@@ -1,6 +1,6 @@
.\" Copyright 2011-2013 Roderick W. Smith (rodsmith@rodsbooks.com) .\" Copyright 2011-2013 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.8.8" "Roderick W. Smith" "GPT fdisk Manual" .TH "GDISK" "8" "0.8.9" "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"
@@ -561,7 +561,7 @@ entering data. When only one option is possible, \fBgdisk\fR
usually bypasses the prompt entirely. usually bypasses the prompt entirely.
.SH "BUGS" .SH "BUGS"
As of October 2013 (version 0.8.8), \fBgdisk\fR As of February 2014 (version 0.8.9), \fBgdisk\fR
should be considered beta software. Known bugs and limitations include: should be considered beta software. Known bugs and limitations include:
.TP .TP

View File

@@ -58,4 +58,5 @@ int main(int argc, char* argv[]) {
cerr << "Usage: " << argv[0] << " [-l] device_file\n"; cerr << "Usage: " << argv[0] << " [-l] device_file\n";
break; break;
} // switch } // switch
return 1 ;
} // main } // main

43
gpt.cc
View File

@@ -1314,6 +1314,7 @@ int GPTData::DestroyGPT(void) {
uint8_t* emptyTable; uint8_t* emptyTable;
memset(blankSector, 0, sizeof(blankSector)); memset(blankSector, 0, sizeof(blankSector));
ClearGPTData();
if (myDisk.OpenForWrite()) { if (myDisk.OpenForWrite()) {
if (!myDisk.Seek(mainHeader.currentLBA)) if (!myDisk.Seek(mainHeader.currentLBA))
@@ -1327,8 +1328,8 @@ int GPTData::DestroyGPT(void) {
tableSize = numParts * mainHeader.sizeOfPartitionEntries; tableSize = numParts * mainHeader.sizeOfPartitionEntries;
emptyTable = new uint8_t[tableSize]; emptyTable = new uint8_t[tableSize];
if (emptyTable == NULL) { if (emptyTable == NULL) {
cerr << "Could not allocate memory in GPTData::DestroyGPT()! Aborting operation!\n"; cerr << "Could not allocate memory in GPTData::DestroyGPT()! Terminating!\n";
return(0); exit(1);
} // if } // if
memset(emptyTable, 0, tableSize); memset(emptyTable, 0, tableSize);
if (allOK) { if (allOK) {
@@ -1338,30 +1339,24 @@ int GPTData::DestroyGPT(void) {
allOK = 0; allOK = 0;
} // if write failed } // if write failed
} // if } // if
if (!myDisk.Seek(secondHeader.partitionEntriesLBA))
if (secondHeader.currentLBA == (diskSize - UINT64_C(1))) { allOK = 0;
if (!myDisk.Seek(secondHeader.partitionEntriesLBA)) if (allOK) {
sum = myDisk.Write(emptyTable, tableSize);
if (sum != tableSize) {
cerr << "Warning! GPT backup partition table not overwritten! Error is "
<< errno << "\n";
allOK = 0; allOK = 0;
if (allOK) { } // if wrong size written
sum = myDisk.Write(emptyTable, tableSize); } // if
if (sum != tableSize) { if (!myDisk.Seek(secondHeader.currentLBA))
cerr << "Warning! GPT backup partition table not overwritten! Error is " allOK = 0;
<< errno << "\n"; if (allOK) {
allOK = 0; if (myDisk.Write(blankSector, 512) != 512) { // blank it out
} // if wrong size written cerr << "Warning! GPT backup header not overwritten! Error is " << errno << "\n";
} // if
if (!myDisk.Seek(secondHeader.currentLBA))
allOK = 0; allOK = 0;
if (allOK) {
if (myDisk.Write(blankSector, 512) != 512) { // blank it out
cerr << "Warning! GPT backup header not overwritten! Error is " << errno << "\n";
allOK = 0;
} // if
} // if } // if
} else { } // if
cout << "Note: The GPT second header is not at the end of the disk end; therefore,\n"
<< "it's not being erased.\n";
}
myDisk.DiskSync(); myDisk.DiskSync();
myDisk.Close(); myDisk.Close();
cout << "GPT data structures destroyed! You may now partition the disk using fdisk or\n" cout << "GPT data structures destroyed! You may now partition the disk using fdisk or\n"
@@ -2444,7 +2439,7 @@ int SizesOK(void) {
allOK = 0; allOK = 0;
} // if } // if
if (sizeof(PartType) != 16) { if (sizeof(PartType) != 16) {
cerr << "PartType is " << sizeof(GUIDData) << " bytes, should be 16 bytes; aborting!\n"; cerr << "PartType is " << sizeof(PartType) << " bytes, should be 16 bytes; aborting!\n";
allOK = 0; allOK = 0;
} // if } // if
return (allOK); return (allOK);

View File

@@ -39,6 +39,7 @@ GPTDataCurses::GPTDataCurses(void) {
if (numInstances > 0) { if (numInstances > 0) {
refresh(); refresh();
} else { } else {
setlocale( LC_ALL , "" );
initscr(); initscr();
cbreak(); cbreak();
noecho(); noecho();
@@ -318,7 +319,7 @@ void GPTDataCurses::DeletePartition(int partNum) {
void GPTDataCurses::ShowInfo(int partNum) { void GPTDataCurses::ShowInfo(int partNum) {
uint64_t size; uint64_t size;
#ifdef USE_UTF16 #ifdef USE_UTF16
char temp[NAME_SIZE / 2 + 1]; char temp[NAME_SIZE + 1];
#endif #endif
clear(); clear();
@@ -335,7 +336,7 @@ void GPTDataCurses::ShowInfo(int partNum) {
printw("Partition size: %lld sectors (%s)\n", size, BytesToIeee(size, blockSize).c_str()); printw("Partition size: %lld sectors (%s)\n", size, BytesToIeee(size, blockSize).c_str());
printw("Attribute flags: %016x\n", partitions[partNum].GetAttributes().GetAttributes()); printw("Attribute flags: %016x\n", partitions[partNum].GetAttributes().GetAttributes());
#ifdef USE_UTF16 #ifdef USE_UTF16
partitions[partNum].GetDescription().extract(0, NAME_SIZE / 2, temp, NAME_SIZE / 2); partitions[partNum].GetDescription().extract(0, NAME_SIZE , temp, NAME_SIZE );
printw("Partition name: '%s'\n", temp); printw("Partition name: '%s'\n", temp);
#else #else
printw("Partition name: '%s'\n", partitions[partNum].GetDescription().c_str()); printw("Partition name: '%s'\n", partitions[partNum].GetDescription().c_str());
@@ -345,21 +346,21 @@ void GPTDataCurses::ShowInfo(int partNum) {
// Prompt for and change a partition's name.... // Prompt for and change a partition's name....
void GPTDataCurses::ChangeName(int partNum) { void GPTDataCurses::ChangeName(int partNum) {
char temp[NAME_SIZE / 2 + 1]; char temp[NAME_SIZE + 1];
if (ValidPartNum(partNum)) { if (ValidPartNum(partNum)) {
move(LINES - 4, 0); move(LINES - 4, 0);
clrtobot(); clrtobot();
move(LINES - 4, 0); move(LINES - 4, 0);
#ifdef USE_UTF16 #ifdef USE_UTF16
partitions[partNum].GetDescription().extract(0, NAME_SIZE / 2, temp, NAME_SIZE / 2); partitions[partNum].GetDescription().extract(0, NAME_SIZE , temp, NAME_SIZE );
printw("Current partition name is '%s'\n", temp); printw("Current partition name is '%s'\n", temp);
#else #else
printw("Current partition name is '%s'\n", partitions[partNum].GetDescription().c_str()); printw("Current partition name is '%s'\n", partitions[partNum].GetDescription().c_str());
#endif #endif
printw("Enter new partition name, or <Enter> to use the current name:\n"); printw("Enter new partition name, or <Enter> to use the current name:\n");
echo(); echo();
getnstr(temp, NAME_SIZE / 2); getnstr(temp, NAME_SIZE );
partitions[partNum].SetName((string) temp); partitions[partNum].SetName((string) temp);
noecho(); noecho();
} // if } // if

View File

@@ -35,7 +35,7 @@ GPTPart::GPTPart(void) {
firstLBA = 0; firstLBA = 0;
lastLBA = 0; lastLBA = 0;
attributes = 0; attributes = 0;
memset(name, 0, NAME_SIZE); memset(name, 0, NAME_SIZE * sizeof(name[0]) );
} // Default constructor } // Default constructor
GPTPart::~GPTPart(void) { GPTPart::~GPTPart(void) {
@@ -52,11 +52,13 @@ string GPTPart::GetTypeName(void) {
return partitionType.TypeName(); return partitionType.TypeName();
} // GPTPart::GetNameType() } // GPTPart::GetNameType()
#ifdef USE_UTF16
// Return a Unicode description of the partition type (e.g., "Linux/Windows // Return a Unicode description of the partition type (e.g., "Linux/Windows
// data" or "Linux swap"). // data" or "Linux swap").
UnicodeString GPTPart::GetUTypeName(void) { UnicodeString GPTPart::GetUTypeName(void) {
return partitionType.UTypeName(); return partitionType.UTypeName();
} // GPTPart::GetNameType() } // GPTPart::GetNameType()
#endif
// Compute and return the partition's length (or 0 if the end is incorrectly // Compute and return the partition's length (or 0 if the end is incorrectly
// set before the beginning). // set before the beginning).
@@ -74,18 +76,61 @@ UnicodeString GPTPart::GetDescription(void) {
return (UChar*) name; return (UChar*) name;
} // GPTPart::GetDescription() } // GPTPart::GetDescription()
#else #else
// Return partition's name field, converted to a C++ ASCII string // Return partition's name field, converted to a C++ UTF-8 string
string GPTPart::GetDescription(void) { string GPTPart::GetDescription(void) {
string theName; // convert name to utf32 then to utf8
int i = 0; string utf8 ;
size_t pos = 0 ;
theName = ""; while ( ( pos < NAME_SIZE ) && ( name[ pos ] != 0 ) ) {
while ((i < NAME_SIZE) && (name[i] != '\0')) { uint16_t cp = name[ pos ++ ] ;
theName += name[i]; if ( ! IsLittleEndian() ) ReverseBytes( & cp , 2 ) ;
i+=2; // first to utf32
} // while uint32_t uni ;
return theName; if ( cp < 0xd800 || cp > 0xdfff ) {
} // GPTPart::GetDescription() (Windows version) uni = cp ;
} // if
else if ( cp < 0xdc00 ) {
// lead surrogate
uni = ( (uint32_t)( cp & 0x3ff ) ) << 10 ;
if ( pos >= NAME_SIZE ) {
// missing trail surrogate, name[] is invalid
break ;
} // if
cp = name[ pos ++ ] ;
if ( cp < 0xdc00 || cp > 0xdfff ) {
// invalid trail surrogate, name[] is invalid
break ;
} // if
// trail surrogate
uni |= cp & 0x3ff ;
uni += 0x10000 ;
} // if
else {
// unexpected trail surrogate, name[] is invalid
break ;
} // if
// then to utf8
if ( uni < 0x80 ) {
utf8 += (char) uni ;
} // if
else if ( uni < 0x800 ) {
utf8 += (char) ( 0xc0 | ( uni >> 6 ) ) ;
utf8 += (char) ( 0x80 | ( uni & 0x3f ) ) ;
} // if
else if ( uni < 0x10000 ) {
utf8 += (char) ( 0xe0 | ( uni >> 12 ) ) ;
utf8 += (char) ( 0x80 | ( ( uni >> 6 ) & 0x3f ) ) ;
utf8 += (char) ( 0x80 | ( uni & 0x3f ) ) ;
} // if
else {
utf8 += (char) ( 0xf0 | ( uni >> 18 ) ) ;
utf8 += (char) ( 0xe0 | ( ( uni >> 12 ) & 0x3f ) ) ;
utf8 += (char) ( 0x80 | ( ( uni >> 6 ) & 0x3f ) ) ;
utf8 += (char) ( 0x80 | ( uni & 0x3f ) ) ;
} // if
}
return utf8 ;
} // GPTPart::GetDescription(), UTF-8 version
#endif #endif
// Return 1 if the partition is in use // Return 1 if the partition is in use
@@ -97,7 +142,11 @@ int GPTPart::IsUsed(void) {
// name *IF* the current name is the generic one for the current partition // name *IF* the current name is the generic one for the current partition
// type. // type.
void GPTPart::SetType(PartType t) { void GPTPart::SetType(PartType t) {
#ifdef USE_UTF16
if (GetDescription() == partitionType.UTypeName()) { if (GetDescription() == partitionType.UTypeName()) {
#else
if (GetDescription() == partitionType.TypeName()) {
#endif
SetName(t.TypeName()); SetName(t.TypeName());
} // if } // if
partitionType = t; partitionType = t;
@@ -116,8 +165,8 @@ void GPTPart::SetName(const UnicodeString & theName) {
if (theName.isBogus()) { if (theName.isBogus()) {
cerr << "Bogus UTF-16 name found in GPTPart::SetName()! Name not changed!\n"; cerr << "Bogus UTF-16 name found in GPTPart::SetName()! Name not changed!\n";
} else { } else {
memset(name, 0, NAME_SIZE); memset(name, 0, NAME_SIZE * sizeof(name[0]) );
theName.extractBetween(0, NAME_SIZE / 2 - 1, (UChar*) name); theName.extractBetween(0, NAME_SIZE, (UChar*) name);
} // if/else } // if/else
} // GPTPart::SetName() } // GPTPart::SetName()
@@ -128,16 +177,73 @@ void GPTPart::SetName(const UnicodeString & theName) {
// requires a UTF-16LE string. This function creates a simple-minded copy // requires a UTF-16LE string. This function creates a simple-minded copy
// for this. // for this.
void GPTPart::SetName(const string & theName) { void GPTPart::SetName(const string & theName) {
int i, length; // convert utf8 to utf32 then to utf16le
size_t len = theName.length() ;
if (theName.length() < (NAME_SIZE / 2)) size_t pos = 0 ;
length = theName.length(); for ( size_t i = 0 ; pos < NAME_SIZE && i < len ; ) {
else uint32_t uni ;
length = NAME_SIZE / 2; uint8_t cp = theName[ i ++ ] ;
memset(name, 0, NAME_SIZE); int todo ;
for (i = 0; i < length; i++) if ( cp < 0x80 ) {
name[i * 2] = theName[i]; uni = cp ;
} // GPTPart::SetName(), ASCII version todo = 0 ;
} // if
else if ( cp < 0xc0 || cp > 0xf7 ) {
// invalid byte, theName is broken
break ;
} // if
else if ( cp < 0xe0 ) {
uni = cp & 0x1f ;
todo = 1 ;
} // if
else if ( cp < 0xf0 ) {
uni = cp & 0x0f ;
todo = 2 ;
} // if
else {
uni = cp & 0x7 ;
todo = 3 ;
} // if
while ( todo > 0 ) {
if ( i >= len ) {
// missing continuation byte, theName is broken
goto break_converter ;
} // if
cp = theName[ i ++ ] ;
if ( cp > 0xbf || cp < 0x80 ) {
// invalid continuation byte, theName is broken
goto break_converter ;
} // if
uni <<= 6 ;
uni |= cp & 0x3f ;
todo -- ;
} // while
// then to utf16le
if ( uni < 0x10000 ) {
name[ pos ] = (uint16_t) uni ;
if ( ! IsLittleEndian() ) ReverseBytes( name + pos , 2 ) ;
pos ++ ;
} // if
else {
if ( pos > NAME_SIZE - 2 ) {
// not enough room for two surrogates, truncate
break ;
} // if
uni -= 0x10000 ;
name[ pos ] = (uint16_t)( uni >> 10 ) | 0xd800 ;
if ( ! IsLittleEndian() ) ReverseBytes( name + pos , 2 ) ;
pos ++ ;
name[ pos ] = (uint16_t)( uni & 0x3ff ) | 0xdc00 ;
if ( ! IsLittleEndian() ) ReverseBytes( name + pos , 2 ) ;
pos ++ ;
}
} // for
break_converter : ;
// finally fill with zeroes
while ( pos < NAME_SIZE ) {
name[ pos ++ ] = 0 ;
} // while
} // GPTPart::SetName(), UTF-8 version
#endif #endif
// Set the name for the partition based on the current GUID partition type // Set the name for the partition based on the current GUID partition type
@@ -152,7 +258,7 @@ GPTPart & GPTPart::operator=(const GPTPart & orig) {
firstLBA = orig.firstLBA; firstLBA = orig.firstLBA;
lastLBA = orig.lastLBA; lastLBA = orig.lastLBA;
attributes = orig.attributes; attributes = orig.attributes;
memcpy(name, orig.name, NAME_SIZE); memcpy(name, orig.name, NAME_SIZE * sizeof( name[ 0 ] ) );
return *this; return *this;
} // assignment operator } // assignment operator
@@ -196,7 +302,44 @@ void GPTPart::ShowSummary(int partNum, uint32_t blockSize) {
GetDescription().extractBetween(0, 23, description); GetDescription().extractBetween(0, 23, description);
cout << description << "\n"; cout << description << "\n";
#else #else
cout << GetDescription().substr(0, 23) << "\n"; string desc = GetDescription() ;
size_t n = 0 ;
size_t i = 0 ;
size_t len = desc.length() ;
while ( n < 22 && i < len ) {
i ++ ;
if ( i >= len ) {
// short description
break ;
} // if
// skip continuation bytes
while ( i < len && ( ( desc[ i ] & 0xC0 ) == 0x80 ) ) {
// utf8 continuation byte
i ++ ;
} // while
n ++ ;
} // while
if ( i < len ) {
n = 0 ;
i = 0 ;
// description is long we will truncate it
while ( n < 19 && i < len ) {
i ++ ;
if ( i >= len ) {
// should not happen
break ;
} // if
// skip continuation bytes
while ( i < len && ( ( desc[ i ] & 0xC0 ) == 0x80 ) ) {
// utf8 continuation byte
i ++ ;
} // while
n ++ ;
} // while
} // for
cout << GetDescription().substr( 0 , i ) ;
if ( i < len ) cout << "..." ;
cout << "\n";
#endif #endif
cout.fill(' '); cout.fill(' ');
} // if } // if
@@ -237,7 +380,7 @@ void GPTPart::BlankPartition(void) {
firstLBA = 0; firstLBA = 0;
lastLBA = 0; lastLBA = 0;
attributes = 0; attributes = 0;
memset(name, 0, NAME_SIZE); memset(name, 0, NAME_SIZE * sizeof( name[0]) );
} // GPTPart::BlankPartition } // GPTPart::BlankPartition
// Returns 1 if the two partitions overlap, 0 if they don't // Returns 1 if the two partitions overlap, 0 if they don't
@@ -256,7 +399,7 @@ void GPTPart::ReversePartBytes(void) {
ReverseBytes(&firstLBA, 8); ReverseBytes(&firstLBA, 8);
ReverseBytes(&lastLBA, 8); ReverseBytes(&lastLBA, 8);
ReverseBytes(&attributes, 8); ReverseBytes(&attributes, 8);
for (i = 0; i < NAME_SIZE; i += 2) for (i = 0; i < NAME_SIZE; i ++ )
ReverseBytes(name + i, 2); ReverseBytes(name + i, 2);
} // GPTPart::ReverseBytes() } // GPTPart::ReverseBytes()
@@ -271,7 +414,11 @@ void GPTPart::ChangeType(void) {
int changeName; int changeName;
PartType tempType = (GUIDData) "00000000-0000-0000-0000-000000000000"; PartType tempType = (GUIDData) "00000000-0000-0000-0000-000000000000";
#ifdef USE_UTF16
changeName = (GetDescription() == GetUTypeName()); changeName = (GetDescription() == GetUTypeName());
#else
changeName = (GetDescription() == GetTypeName());
#endif
cout << "Current type is '" << GetTypeName() << "'\n"; cout << "Current type is '" << GetTypeName() << "'\n";
do { do {

View File

@@ -45,7 +45,7 @@ class GPTPart {
uint64_t firstLBA; uint64_t firstLBA;
uint64_t lastLBA; uint64_t lastLBA;
Attributes attributes; Attributes attributes;
unsigned char name[NAME_SIZE]; uint16_t name[NAME_SIZE];
public: public:
GPTPart(void); GPTPart(void);
~GPTPart(void); ~GPTPart(void);

View File

@@ -309,7 +309,11 @@ int GPTDataTextUI::SetName(uint32_t partNum) {
if (IsUsedPartNum(partNum)) { if (IsUsedPartNum(partNum)) {
cout << "Enter name: "; cout << "Enter name: ";
#ifdef USE_UTF16
theName = ReadUString(); theName = ReadUString();
#else
theName = ReadString();
#endif
partitions[partNum].SetName(theName); partitions[partNum].SetName(theName);
} else { } else {
cerr << "Invalid partition number (" << partNum << ")\n"; cerr << "Invalid partition number (" << partNum << ")\n";
@@ -412,7 +416,7 @@ void GPTDataTextUI::MakeHybrid(void) {
cout << "Type from one to three GPT partition numbers, separated by spaces, to be\n" cout << "Type from one to three GPT partition numbers, separated by spaces, to be\n"
<< "added to the hybrid MBR, in sequence: "; << "added to the hybrid MBR, in sequence: ";
line = ReadString(); line = ReadString();
numPartsToCvt = sscanf(line.c_str(), "%d %d %d", &partNums[0], &partNums[1], &partNums[2]); numPartsToCvt = sscanf(line.c_str(), "%ud %ud %ud", &partNums[0], &partNums[1], &partNums[2]);
if (numPartsToCvt > 0) { if (numPartsToCvt > 0) {
cout << "Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? "; cout << "Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? ";
@@ -854,7 +858,7 @@ void GPTDataTextUI::ShowExpertCommands(void) {
cout << "r\trecovery and transformation options (experts only)\n"; cout << "r\trecovery and transformation options (experts only)\n";
cout << "s\tresize partition table\n"; cout << "s\tresize partition table\n";
cout << "t\ttranspose two partition table entries\n"; cout << "t\ttranspose two partition table entries\n";
cout << "u\tReplicate partition table on new device\n"; cout << "u\treplicate partition table on new device\n";
cout << "v\tverify disk\n"; cout << "v\tverify disk\n";
cout << "w\twrite table to disk and exit\n"; cout << "w\twrite table to disk and exit\n";
cout << "z\tzap (destroy) GPT data structures and exit\n"; cout << "z\tzap (destroy) GPT data structures and exit\n";
@@ -894,6 +898,7 @@ int GetMBRTypeCode(int defType) {
return typeCode; return typeCode;
} // GetMBRTypeCode } // GetMBRTypeCode
#ifdef USE_UTF16
// Note: ReadUString() is here rather than in support.cc so that the ICU // Note: ReadUString() is here rather than in support.cc so that the ICU
// libraries need not be linked to fixparts. // libraries need not be linked to fixparts.
@@ -904,4 +909,5 @@ int GetMBRTypeCode(int defType) {
UnicodeString ReadUString(void) { UnicodeString ReadUString(void) {
return ReadString().c_str(); return ReadString().c_str();
} // ReadUString() } // ReadUString()
#endif

View File

@@ -24,8 +24,13 @@
using namespace std; using namespace std;
bool GUIDData::firstInstance = 1;
GUIDData::GUIDData(void) { GUIDData::GUIDData(void) {
srand((unsigned int) time(0)); if (firstInstance) {
srand((unsigned int) time(0));
firstInstance = 0;
} // if
Zero(); Zero();
} // constructor } // constructor

2
guid.h
View File

@@ -35,6 +35,8 @@ using namespace std;
// Note: This class's data size is critical. If data elements must be added, // Note: This class's data size is critical. If data elements must be added,
// it will be necessary to modify various GPT classes to compensate. // it will be necessary to modify various GPT classes to compensate.
class GUIDData { class GUIDData {
private:
static bool firstInstance;
protected: protected:
my_uuid_t uuidData; my_uuid_t uuidData;
string DeleteSpaces(string s); string DeleteSpaces(string s);

View File

@@ -315,6 +315,7 @@ string PartType::TypeName(void) const {
return typeName; return typeName;
} // PartType::TypeName() } // PartType::TypeName()
#ifdef USE_UTF16
// Return the Unicode description of the partition type (e.g., "Linux filesystem") // Return the Unicode description of the partition type (e.g., "Linux filesystem")
UnicodeString PartType::UTypeName(void) const { UnicodeString PartType::UTypeName(void) const {
AType* theItem = allTypes; AType* theItem = allTypes;
@@ -334,6 +335,7 @@ UnicodeString PartType::UTypeName(void) const {
} // if (!found) } // if (!found)
return typeName; return typeName;
} // PartType::TypeName() } // PartType::TypeName()
#endif
// Return the custom GPT fdisk 2-byte (16-bit) hex code for this GUID partition type // Return the custom GPT fdisk 2-byte (16-bit) hex code for this GUID partition type
// Note that this function ignores entries for which the display variable // Note that this function ignores entries for which the display variable

View File

@@ -1,6 +1,6 @@
.\" Copyright 2011-2013 Roderick W. Smith (rodsmith@rodsbooks.com) .\" Copyright 2011-2013 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.8.8" "Roderick W. Smith" "GPT fdisk Manual" .TH "SGDISK" "8" "0.8.9" "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"
@@ -490,7 +490,7 @@ sgdisk, but may with gdisk)
Disk replication operation (-R) failed Disk replication operation (-R) failed
.SH "BUGS" .SH "BUGS"
As of October 2013 (version 0.8.8), \fBsgdisk\fR As of February 2014 (version 0.8.9), \fBsgdisk\fR
should be considered beta software. Known bugs and limitations include: should be considered beta software. Known bugs and limitations include:
.TP .TP

View File

@@ -77,8 +77,11 @@ int GetNumber(int low, int high, int def, const string & prompt) {
char GetYN(void) { char GetYN(void) {
char response; char response;
string line; string line;
bool again = 0 ;
do { do {
if ( again ) { cout << "Your option? " ; }
again = 1 ;
cout << "(Y/N): "; cout << "(Y/N): ";
line = ReadString(); line = ReadString();
response = toupper(line[0]); response = toupper(line[0]);

View File

@@ -8,7 +8,7 @@
#ifndef __GPTSUPPORT #ifndef __GPTSUPPORT
#define __GPTSUPPORT #define __GPTSUPPORT
#define GPTFDISK_VERSION "0.8.8.4" #define GPTFDISK_VERSION "0.8.9"
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) #if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
// Darwin (Mac OS) & FreeBSD: disk IOCTLs are different, and there is no lseek64 // Darwin (Mac OS) & FreeBSD: disk IOCTLs are different, and there is no lseek64
@@ -67,7 +67,7 @@
#define GPT_SIZE 128 #define GPT_SIZE 128
#define HEADER_SIZE UINT32_C(92) #define HEADER_SIZE UINT32_C(92)
#define GPT_RESERVED 420 #define GPT_RESERVED 420
#define NAME_SIZE 72 #define NAME_SIZE 36 // GPT allows 36 UTF-16LE code units for a name in a 128 byte partition entry
using namespace std; using namespace std;