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
CXX=g++
CFLAGS+=-D_FILE_OFFSET_BITS=64
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -D USE_UTF16
#CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64
#CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -D USE_UTF16
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64
LDFLAGS+=
LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
@@ -14,16 +14,16 @@ DEPEND= makedepend $(CXXFLAGS)
all: cgdisk gdisk sgdisk fixparts
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) -licuio -licuuc -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
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) -licuio -licuuc -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
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) -licuio -licuuc -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
fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts

View File

@@ -1,8 +1,8 @@
CC=gcc
CXX=g++
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 -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
LDFLAGS+=
LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
@@ -14,16 +14,16 @@ DEPEND= makedepend $(CXXFLAGS)
all: gdisk cgdisk sgdisk fixparts
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) -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
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) -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
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 -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
fixparts: $(MBR_LIB_OBJS) fixparts.o
$(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
FixParts (and perhaps in other programs under some circumstances).
- Added check for valid location of backup GPT data to GPT-destruction
options ('z' in gdisk, -z and -Z options to sgdisk). If the backup
GPT data structures aren't at the end of the disk, they aren't erased.
This is done to avoid wiping out data mid-disk that might not be backup
GPT data structures, which could otherwise occur if a RAID array was
resized in certain ways.
- Added GPT regeneration command to GPT-destruction options ('z' in gdisk,
-z and -Z options to sgdisk). This is done to avoid wiping out data
mid-disk that might not be backup 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
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.
* The ICU library (http://site.icu-project.org), which provides support for
Unicode partition names, is recommended on all
platforms except Windows. This library is normally installed in Linux and
OS X, but you may need to install the development headers (libicu-dev or
something similar in Linux; or the libicu36-dev Fink package in OS X). To
compile without ICU support, you must modify the Makefile: Remove the
"-D USE_UTF16" part from the CXXFLAGS line and remove references to
-licuio, -licuuc, -licudata, and -licucore (details vary between
platforms) from the compilation options. Suitable lines are present, but
commented out, in the Makefile, Makefile.solaris, Makefile.freebsd files.
Because of problems with ICU under OS X, the Makefile.mac file doesn't
build against ICU by default.
Unicode partition names, is optional on all platforms except Windows, on
which it's not supported. Using this library was required to get proper
UTF-16 partition name support in GPT fdisk versions prior to 0.8.9, but
as of that version it should not longer be required. Nonetheless, you can
use it if you're having problems with the new UTF-16 support. This
library is normally installed in Linux and OS X, but you may need to
install the development headers (libicu-dev or something similar in
Linux; or the libicu36-dev Fink package in OS X). To compile with ICU
support, you must modify the Makefile: Look for commented-out lines that
refer to USE_UTF16, -licuuc, -licudata, or -licucore. Uncomment them and
comment out the equivalents that lack these lines.
* The cgdisk program requires the ncurses library and its development files
(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;
} // if
// 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[1] = chs[2] = 255;
done = 1;
@@ -1223,7 +1223,7 @@ void BasicMBRData::MaximizePrimaries() {
// Remove primary partitions in excess of 4, starting with the later ones,
// in terms of the array location....
void BasicMBRData::TrimPrimaries(void) {
int numToDelete, i = MAX_MBR_PARTS;
int numToDelete, i = MAX_MBR_PARTS - 1;
numToDelete = NumPrimaries() - 4;
while ((numToDelete > 0) && (i >= 0)) {

View File

@@ -1,6 +1,6 @@
.\" Copyright 2011-2013 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" 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"
cgdisk \- Curses-based GUID partition table (GPT) manipulator
.SH "SYNOPSIS"
@@ -276,7 +276,7 @@ Write data. Use this command to save your changes.
.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
older, the \fBcgdisk\fR ncurses user interface is brand new with GPT fdisk
version 0.8.0. Known bugs and limitations include:

View File

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

View File

@@ -1,11 +1,11 @@
Summary: GPT partitioning and MBR repair software
Name: gptfdisk
Version: 0.8.8
Version: 0.8.9
Release: 1%{?dist}
License: GPLv2
URL: http://www.rodsbooks.com/gdisk
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)
%description
@@ -80,5 +80,5 @@ provides a few additional partition manipulation features.
%changelog
* Mon Oct 14 2013 R Smith <rodsmith@rodsbooks.com> - 0.8.8
- Created spec file for 0.8.8 release
* Mon Feb 17 2014 R Smith <rodsmith@rodsbooks.com> - 0.8.9
- Created spec file for 0.8.9 release

View File

@@ -1,6 +1,6 @@
.\" Copyright 2011-2013 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" 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"
fixparts \- MBR partition table repair utility
.SH "SYNOPSIS"
@@ -202,7 +202,7 @@ see a summary of available options.
.PP
.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:
.TP

View File

@@ -1,6 +1,6 @@
.\" Copyright 2011-2013 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" 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"
gdisk \- Interactive GUID partition table (GPT) manipulator
.SH "SYNOPSIS"
@@ -561,7 +561,7 @@ entering data. When only one option is possible, \fBgdisk\fR
usually bypasses the prompt entirely.
.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:
.TP

View File

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

43
gpt.cc
View File

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

View File

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

View File

@@ -35,7 +35,7 @@ GPTPart::GPTPart(void) {
firstLBA = 0;
lastLBA = 0;
attributes = 0;
memset(name, 0, NAME_SIZE);
memset(name, 0, NAME_SIZE * sizeof(name[0]) );
} // Default constructor
GPTPart::~GPTPart(void) {
@@ -52,11 +52,13 @@ string GPTPart::GetTypeName(void) {
return partitionType.TypeName();
} // GPTPart::GetNameType()
#ifdef USE_UTF16
// Return a Unicode description of the partition type (e.g., "Linux/Windows
// data" or "Linux swap").
UnicodeString GPTPart::GetUTypeName(void) {
return partitionType.UTypeName();
} // GPTPart::GetNameType()
#endif
// Compute and return the partition's length (or 0 if the end is incorrectly
// set before the beginning).
@@ -74,18 +76,61 @@ UnicodeString GPTPart::GetDescription(void) {
return (UChar*) name;
} // GPTPart::GetDescription()
#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 theName;
int i = 0;
theName = "";
while ((i < NAME_SIZE) && (name[i] != '\0')) {
theName += name[i];
i+=2;
} // while
return theName;
} // GPTPart::GetDescription() (Windows version)
// convert name to utf32 then to utf8
string utf8 ;
size_t pos = 0 ;
while ( ( pos < NAME_SIZE ) && ( name[ pos ] != 0 ) ) {
uint16_t cp = name[ pos ++ ] ;
if ( ! IsLittleEndian() ) ReverseBytes( & cp , 2 ) ;
// first to utf32
uint32_t uni ;
if ( cp < 0xd800 || cp > 0xdfff ) {
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
// 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
// type.
void GPTPart::SetType(PartType t) {
#ifdef USE_UTF16
if (GetDescription() == partitionType.UTypeName()) {
#else
if (GetDescription() == partitionType.TypeName()) {
#endif
SetName(t.TypeName());
} // if
partitionType = t;
@@ -116,8 +165,8 @@ void GPTPart::SetName(const UnicodeString & theName) {
if (theName.isBogus()) {
cerr << "Bogus UTF-16 name found in GPTPart::SetName()! Name not changed!\n";
} else {
memset(name, 0, NAME_SIZE);
theName.extractBetween(0, NAME_SIZE / 2 - 1, (UChar*) name);
memset(name, 0, NAME_SIZE * sizeof(name[0]) );
theName.extractBetween(0, NAME_SIZE, (UChar*) name);
} // if/else
} // GPTPart::SetName()
@@ -128,16 +177,73 @@ void GPTPart::SetName(const UnicodeString & theName) {
// requires a UTF-16LE string. This function creates a simple-minded copy
// for this.
void GPTPart::SetName(const string & theName) {
int i, length;
if (theName.length() < (NAME_SIZE / 2))
length = theName.length();
else
length = NAME_SIZE / 2;
memset(name, 0, NAME_SIZE);
for (i = 0; i < length; i++)
name[i * 2] = theName[i];
} // GPTPart::SetName(), ASCII version
// convert utf8 to utf32 then to utf16le
size_t len = theName.length() ;
size_t pos = 0 ;
for ( size_t i = 0 ; pos < NAME_SIZE && i < len ; ) {
uint32_t uni ;
uint8_t cp = theName[ i ++ ] ;
int todo ;
if ( cp < 0x80 ) {
uni = cp ;
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
// 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;
lastLBA = orig.lastLBA;
attributes = orig.attributes;
memcpy(name, orig.name, NAME_SIZE);
memcpy(name, orig.name, NAME_SIZE * sizeof( name[ 0 ] ) );
return *this;
} // assignment operator
@@ -196,7 +302,44 @@ void GPTPart::ShowSummary(int partNum, uint32_t blockSize) {
GetDescription().extractBetween(0, 23, description);
cout << description << "\n";
#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
cout.fill(' ');
} // if
@@ -237,7 +380,7 @@ void GPTPart::BlankPartition(void) {
firstLBA = 0;
lastLBA = 0;
attributes = 0;
memset(name, 0, NAME_SIZE);
memset(name, 0, NAME_SIZE * sizeof( name[0]) );
} // GPTPart::BlankPartition
// Returns 1 if the two partitions overlap, 0 if they don't
@@ -256,7 +399,7 @@ void GPTPart::ReversePartBytes(void) {
ReverseBytes(&firstLBA, 8);
ReverseBytes(&lastLBA, 8);
ReverseBytes(&attributes, 8);
for (i = 0; i < NAME_SIZE; i += 2)
for (i = 0; i < NAME_SIZE; i ++ )
ReverseBytes(name + i, 2);
} // GPTPart::ReverseBytes()
@@ -271,7 +414,11 @@ void GPTPart::ChangeType(void) {
int changeName;
PartType tempType = (GUIDData) "00000000-0000-0000-0000-000000000000";
#ifdef USE_UTF16
changeName = (GetDescription() == GetUTypeName());
#else
changeName = (GetDescription() == GetTypeName());
#endif
cout << "Current type is '" << GetTypeName() << "'\n";
do {

View File

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

View File

@@ -309,7 +309,11 @@ int GPTDataTextUI::SetName(uint32_t partNum) {
if (IsUsedPartNum(partNum)) {
cout << "Enter name: ";
#ifdef USE_UTF16
theName = ReadUString();
#else
theName = ReadString();
#endif
partitions[partNum].SetName(theName);
} else {
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"
<< "added to the hybrid MBR, in sequence: ";
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) {
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 << "s\tresize partition table\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 << "w\twrite table to disk and exit\n";
cout << "z\tzap (destroy) GPT data structures and exit\n";
@@ -894,6 +898,7 @@ int GetMBRTypeCode(int defType) {
return typeCode;
} // GetMBRTypeCode
#ifdef USE_UTF16
// Note: ReadUString() is here rather than in support.cc so that the ICU
// libraries need not be linked to fixparts.
@@ -904,4 +909,5 @@ int GetMBRTypeCode(int defType) {
UnicodeString ReadUString(void) {
return ReadString().c_str();
} // ReadUString()
#endif

View File

@@ -24,8 +24,13 @@
using namespace std;
bool GUIDData::firstInstance = 1;
GUIDData::GUIDData(void) {
srand((unsigned int) time(0));
if (firstInstance) {
srand((unsigned int) time(0));
firstInstance = 0;
} // if
Zero();
} // 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,
// it will be necessary to modify various GPT classes to compensate.
class GUIDData {
private:
static bool firstInstance;
protected:
my_uuid_t uuidData;
string DeleteSpaces(string s);

View File

@@ -315,6 +315,7 @@ string PartType::TypeName(void) const {
return typeName;
} // PartType::TypeName()
#ifdef USE_UTF16
// Return the Unicode description of the partition type (e.g., "Linux filesystem")
UnicodeString PartType::UTypeName(void) const {
AType* theItem = allTypes;
@@ -334,6 +335,7 @@ UnicodeString PartType::UTypeName(void) const {
} // if (!found)
return typeName;
} // PartType::TypeName()
#endif
// 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

View File

@@ -1,6 +1,6 @@
.\" Copyright 2011-2013 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" 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"
sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
.SH "SYNOPSIS"
@@ -490,7 +490,7 @@ sgdisk, but may with gdisk)
Disk replication operation (-R) failed
.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:
.TP

View File

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

View File

@@ -8,7 +8,7 @@
#ifndef __GPTSUPPORT
#define __GPTSUPPORT
#define GPTFDISK_VERSION "0.8.8.4"
#define GPTFDISK_VERSION "0.8.9"
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
// Darwin (Mac OS) & FreeBSD: disk IOCTLs are different, and there is no lseek64
@@ -67,7 +67,7 @@
#define GPT_SIZE 128
#define HEADER_SIZE UINT32_C(92)
#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;