2006-03-24 12:08:41 -07:00
|
|
|
/* Copyright (C) 2004 Bart 'plors' Hakvoort
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "../include/Win_GParted.h"
|
2004-11-17 06:00:25 -07:00
|
|
|
#include "../include/GParted_Core.h"
|
2006-03-24 12:08:41 -07:00
|
|
|
#include "../include/OperationCopy.h"
|
|
|
|
#include "../include/OperationCreate.h"
|
|
|
|
#include "../include/OperationDelete.h"
|
|
|
|
#include "../include/OperationFormat.h"
|
|
|
|
#include "../include/OperationResizeMove.h"
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2006-04-02 08:35:21 -06:00
|
|
|
#include "../include/ext2.h"
|
|
|
|
#include "../include/ext3.h"
|
|
|
|
#include "../include/fat16.h"
|
|
|
|
#include "../include/fat32.h"
|
|
|
|
#include "../include/linux_swap.h"
|
|
|
|
#include "../include/reiserfs.h"
|
|
|
|
#include "../include/ntfs.h"
|
|
|
|
#include "../include/xfs.h"
|
|
|
|
#include "../include/jfs.h"
|
|
|
|
#include "../include/hfs.h"
|
|
|
|
#include "../include/hfsplus.h"
|
|
|
|
#include "../include/reiser4.h"
|
|
|
|
#include "../include/ufs.h"
|
|
|
|
|
2006-03-02 14:55:04 -07:00
|
|
|
#include <cerrno>
|
2005-12-10 17:05:28 -07:00
|
|
|
#include <sys/statvfs.h>
|
|
|
|
|
2006-07-30 09:13:41 -06:00
|
|
|
std::vector<Glib::ustring> libparted_messages ; //see ped_exception_handler()
|
2006-02-25 09:30:43 -07:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
namespace GParted
|
|
|
|
{
|
2006-03-14 14:37:47 -07:00
|
|
|
|
2006-02-25 09:30:43 -07:00
|
|
|
GParted_Core::GParted_Core()
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2005-11-26 17:57:11 -07:00
|
|
|
lp_device = NULL ;
|
|
|
|
lp_disk = NULL ;
|
|
|
|
lp_partition = NULL ;
|
2004-11-17 06:00:25 -07:00
|
|
|
p_filesystem = NULL ;
|
|
|
|
|
2006-02-25 09:30:43 -07:00
|
|
|
ped_exception_set_handler( ped_exception_handler ) ;
|
2006-08-09 13:20:20 -06:00
|
|
|
|
|
|
|
//disable automount //FIXME: temporary hack, till i find a better solution...
|
|
|
|
std::ofstream fdi_file( "/usr/share/hal/fdi/policy/gparted-disable-automount.fdi" ) ;
|
|
|
|
if ( fdi_file )
|
|
|
|
{
|
|
|
|
fdi_file << "<deviceinfo version='0.2'>" ;
|
|
|
|
fdi_file << "<device>" ;
|
|
|
|
fdi_file << "<match key='@block.storage_device:storage.hotpluggable' bool='true'>" ;
|
|
|
|
fdi_file << "<merge key='volume.ignore' type='bool'>true</merge>" ;
|
|
|
|
fdi_file << "</match>" ;
|
|
|
|
fdi_file << "</device>" ;
|
|
|
|
fdi_file << "</deviceinfo>" ;
|
|
|
|
|
|
|
|
fdi_file .close() ;
|
|
|
|
}
|
2006-02-25 09:30:43 -07:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
//get valid flags ...
|
2006-02-25 09:30:43 -07:00
|
|
|
for ( PedPartitionFlag flag = ped_partition_flag_next( static_cast<PedPartitionFlag>( NULL ) ) ;
|
|
|
|
flag ;
|
|
|
|
flag = ped_partition_flag_next( flag ) )
|
2006-03-31 03:49:27 -07:00
|
|
|
flags .push_back( flag ) ;
|
2005-01-08 16:45:45 -07:00
|
|
|
|
2005-01-23 07:05:21 -07:00
|
|
|
//throw libpartedversion to the stdout to see which version is actually used.
|
|
|
|
std::cout << "======================" << std::endl ;
|
2006-02-25 09:30:43 -07:00
|
|
|
std::cout << "libparted : " << ped_get_version() << std::endl ;
|
2005-01-23 07:05:21 -07:00
|
|
|
std::cout << "======================" << std::endl ;
|
|
|
|
|
|
|
|
//initialize filesystemlist
|
2006-02-25 09:30:43 -07:00
|
|
|
find_supported_filesystems() ;
|
2004-11-17 06:00:25 -07:00
|
|
|
}
|
|
|
|
|
2006-02-25 09:30:43 -07:00
|
|
|
void GParted_Core::find_supported_filesystems()
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .clear() ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
|
|
|
ext2 fs_ext2;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_ext2 .get_filesystem_support() ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
|
|
|
ext3 fs_ext3;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_ext3 .get_filesystem_support() ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
|
|
|
fat16 fs_fat16;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_fat16 .get_filesystem_support() ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
|
|
|
fat32 fs_fat32;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_fat32 .get_filesystem_support() ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2004-12-14 15:49:44 -07:00
|
|
|
hfs fs_hfs;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_hfs .get_filesystem_support() ) ;
|
2004-12-14 15:49:44 -07:00
|
|
|
|
2005-09-13 08:56:00 -06:00
|
|
|
hfsplus fs_hfsplus;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_hfsplus .get_filesystem_support() ) ;
|
2005-09-13 08:56:00 -06:00
|
|
|
|
2004-12-14 15:49:44 -07:00
|
|
|
jfs fs_jfs;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_jfs .get_filesystem_support() ) ;
|
2004-12-14 15:49:44 -07:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
linux_swap fs_linux_swap;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_linux_swap .get_filesystem_support() ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2006-02-17 14:18:07 -07:00
|
|
|
ntfs fs_ntfs;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_ntfs .get_filesystem_support() ) ;
|
2006-02-17 14:18:07 -07:00
|
|
|
|
2004-12-28 17:09:58 -07:00
|
|
|
reiser4 fs_reiser4;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_reiser4 .get_filesystem_support() ) ;
|
2004-12-28 17:09:58 -07:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
reiserfs fs_reiserfs;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_reiserfs .get_filesystem_support() ) ;
|
2004-11-21 14:49:38 -07:00
|
|
|
|
2006-04-02 08:35:21 -06:00
|
|
|
ufs fs_ufs;
|
|
|
|
FILESYSTEMS .push_back( fs_ufs .get_filesystem_support() ) ;
|
|
|
|
|
2004-12-13 14:24:12 -07:00
|
|
|
xfs fs_xfs;
|
2006-02-25 09:30:43 -07:00
|
|
|
FILESYSTEMS .push_back( fs_xfs .get_filesystem_support() ) ;
|
2004-12-13 14:24:12 -07:00
|
|
|
|
2004-11-21 14:49:38 -07:00
|
|
|
//unknown filesystem (default when no match is found)
|
2005-12-07 04:21:27 -07:00
|
|
|
FS fs ; fs .filesystem = GParted::FS_UNKNOWN ;
|
2004-11-21 14:49:38 -07:00
|
|
|
FILESYSTEMS .push_back( fs ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
}
|
2006-02-02 06:50:37 -07:00
|
|
|
|
|
|
|
void GParted_Core::set_user_devices( const std::vector<Glib::ustring> & user_devices )
|
|
|
|
{
|
|
|
|
this ->device_paths = user_devices ;
|
|
|
|
this ->probe_devices = ! user_devices .size() ;
|
|
|
|
}
|
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
void GParted_Core::set_devices( std::vector<Device> & devices )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2005-12-29 07:21:45 -07:00
|
|
|
devices .clear() ;
|
2004-11-17 06:00:25 -07:00
|
|
|
Device temp_device ;
|
|
|
|
|
2006-01-05 13:01:34 -07:00
|
|
|
init_maps() ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2006-02-02 06:50:37 -07:00
|
|
|
//only probe if no devices were specified as arguments..
|
|
|
|
if ( probe_devices )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-02-02 06:50:37 -07:00
|
|
|
device_paths .clear() ;
|
|
|
|
|
|
|
|
//try to find all available devices
|
|
|
|
ped_device_probe_all();
|
2006-07-11 12:13:27 -06:00
|
|
|
//FIXME: since parted 1.7.1 i detect an unusable /dev/md/0 device (voyager), take a look at this and
|
|
|
|
//find out how to filter it from the list
|
2006-02-02 06:50:37 -07:00
|
|
|
lp_device = ped_device_get_next( NULL );
|
|
|
|
while ( lp_device )
|
|
|
|
{
|
|
|
|
device_paths .push_back( lp_device ->path ) ;
|
2006-07-17 14:54:41 -06:00
|
|
|
|
2006-02-02 06:50:37 -07:00
|
|
|
lp_device = ped_device_get_next( lp_device ) ;
|
|
|
|
}
|
|
|
|
close_device_and_disk() ;
|
2005-12-30 11:11:03 -07:00
|
|
|
|
2006-03-26 02:16:13 -07:00
|
|
|
std::sort( device_paths .begin(), device_paths .end() ) ;
|
|
|
|
}
|
2006-04-04 04:00:55 -06:00
|
|
|
|
2005-12-29 07:21:45 -07:00
|
|
|
for ( unsigned int t = 0 ; t < device_paths .size() ; t++ )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-03-26 12:45:23 -07:00
|
|
|
if ( check_device_path( device_paths[ t ] ) &&
|
|
|
|
open_device_and_disk( device_paths[ t ], false ) &&
|
|
|
|
lp_device )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2005-12-29 07:21:45 -07:00
|
|
|
temp_device .Reset() ;
|
2004-11-19 04:55:38 -07:00
|
|
|
|
2004-11-27 16:31:19 -07:00
|
|
|
//device info..
|
2006-03-14 14:37:47 -07:00
|
|
|
temp_device .add_path( device_paths[ t ] ) ;
|
|
|
|
temp_device .add_paths( get_alternate_paths( temp_device .get_path() ) ) ;
|
|
|
|
|
2005-11-26 17:57:11 -07:00
|
|
|
temp_device .model = lp_device ->model ;
|
|
|
|
temp_device .heads = lp_device ->bios_geom .heads ;
|
|
|
|
temp_device .sectors = lp_device ->bios_geom .sectors ;
|
|
|
|
temp_device .cylinders = lp_device ->bios_geom .cylinders ;
|
2004-11-17 06:00:25 -07:00
|
|
|
temp_device .length = temp_device .heads * temp_device .sectors * temp_device .cylinders ;
|
2006-02-25 03:09:30 -07:00
|
|
|
temp_device .cylsize = temp_device .heads * temp_device .sectors ;
|
2004-12-27 05:08:01 -07:00
|
|
|
|
2006-01-20 16:35:06 -07:00
|
|
|
//make sure cylsize is at least 1 MiB
|
2006-02-25 03:09:30 -07:00
|
|
|
if ( temp_device .cylsize < MEBIBYTE )
|
|
|
|
temp_device .cylsize = MEBIBYTE ;
|
2005-08-30 20:30:25 -06:00
|
|
|
|
2004-12-27 05:08:01 -07:00
|
|
|
//normal harddisk
|
2005-11-26 17:57:11 -07:00
|
|
|
if ( lp_disk )
|
2004-11-27 16:31:19 -07:00
|
|
|
{
|
2005-11-26 17:57:11 -07:00
|
|
|
temp_device .disktype = lp_disk ->type ->name ;
|
|
|
|
temp_device .max_prims = ped_disk_get_max_primary_partition_count( lp_disk ) ;
|
2004-11-29 08:27:33 -07:00
|
|
|
|
2004-12-17 12:45:04 -07:00
|
|
|
set_device_partitions( temp_device ) ;
|
2006-03-07 04:55:27 -07:00
|
|
|
set_mountpoints( temp_device .partitions ) ;
|
2006-01-05 13:01:34 -07:00
|
|
|
set_used_sectors( temp_device .partitions ) ;
|
2006-04-02 12:03:37 -06:00
|
|
|
|
2005-12-10 17:05:28 -07:00
|
|
|
if ( temp_device .highest_busy )
|
2005-11-26 17:57:11 -07:00
|
|
|
temp_device .readonly = ! ped_disk_commit_to_os( lp_disk ) ;
|
2004-11-27 16:31:19 -07:00
|
|
|
}
|
|
|
|
//harddisk without disklabel
|
|
|
|
else
|
|
|
|
{
|
2004-11-28 05:09:04 -07:00
|
|
|
temp_device .disktype = _("unrecognized") ;
|
2004-11-27 16:31:19 -07:00
|
|
|
temp_device .max_prims = -1 ;
|
|
|
|
|
|
|
|
Partition partition_temp ;
|
2006-03-14 14:37:47 -07:00
|
|
|
partition_temp .Set_Unallocated( temp_device .get_path(),
|
|
|
|
0,
|
|
|
|
temp_device .length,
|
|
|
|
false );
|
2006-01-05 13:01:34 -07:00
|
|
|
temp_device .partitions .push_back( partition_temp );
|
2004-11-27 16:31:19 -07:00
|
|
|
}
|
2005-08-30 20:30:25 -06:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
devices .push_back( temp_device ) ;
|
|
|
|
|
2006-01-05 13:01:34 -07:00
|
|
|
close_device_and_disk() ;
|
2004-11-17 06:00:25 -07:00
|
|
|
}
|
|
|
|
}
|
2006-01-05 13:01:34 -07:00
|
|
|
|
|
|
|
//clear leftover information...
|
2006-02-20 07:41:05 -07:00
|
|
|
//NOTE that we cannot clear mountinfo since it might be needed in get_all_mountpoints()
|
2006-03-14 14:37:47 -07:00
|
|
|
alternate_paths .clear() ;
|
2006-03-07 04:55:27 -07:00
|
|
|
fstab_info .clear() ;
|
2004-11-17 06:00:25 -07:00
|
|
|
}
|
|
|
|
|
2006-07-20 13:14:44 -06:00
|
|
|
bool GParted_Core::snap_to_cylinder( const Device & device, Partition & partition, Glib::ustring & error )
|
2006-07-11 12:13:27 -06:00
|
|
|
{
|
2006-07-17 14:54:41 -06:00
|
|
|
if ( ! partition .strict )
|
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
//FIXME: this doesn't work to well, when dealing with layouts which contain an extended partition
|
|
|
|
//because of the metadata length % cylindersize isn't always 0
|
2006-07-17 14:54:41 -06:00
|
|
|
Sector diff = partition .sector_start % device .cylsize ;
|
|
|
|
if ( diff )
|
|
|
|
{
|
|
|
|
if ( diff < ( device .cylsize / 2 ) )
|
|
|
|
partition .sector_start -= diff ;
|
|
|
|
else
|
|
|
|
partition .sector_start += (device .cylsize - diff ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
diff = (partition .sector_end +1) % device .cylsize ;
|
|
|
|
if ( diff )
|
|
|
|
{
|
|
|
|
if ( diff < ( device .cylsize / 2 ) )
|
|
|
|
partition .sector_end -= diff ;
|
|
|
|
else
|
|
|
|
partition .sector_end += (device .cylsize - diff ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( partition .sector_start < 0 )
|
|
|
|
partition .sector_start = 0 ;
|
|
|
|
if ( partition .sector_end > device .length )
|
|
|
|
partition .sector_end = device .length -1 ;
|
2006-07-20 13:14:44 -06:00
|
|
|
|
|
|
|
//ok, do some basic checks on the partition..
|
|
|
|
if ( partition .get_length() <= 0 )
|
|
|
|
{
|
|
|
|
error = String::ucompose( _("A partition cannot have a length of %1 sectors"),
|
|
|
|
partition .get_length() ) ;
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( partition .get_length() < partition .sectors_used )
|
|
|
|
{
|
|
|
|
error = String::ucompose(
|
|
|
|
_("A partition with used sectors (%1) greater than it's length (%2) is not valid"),
|
|
|
|
partition .sectors_used,
|
|
|
|
partition .get_length() ) ;
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
|
2006-07-17 14:54:41 -06:00
|
|
|
//FIXME: it would be perfect if we could check for overlapping with adjacent partitions as well,
|
|
|
|
//however, finding the adjacent partitions is not as easy as it seems and at this moment all the dialogs
|
|
|
|
//already perform these checks. A perfect 'fixme-later' ;)
|
|
|
|
}
|
|
|
|
|
2006-07-11 12:13:27 -06:00
|
|
|
return true ;
|
|
|
|
}
|
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
bool GParted_Core::apply_operation_to_disk( Operation * operation )
|
|
|
|
{
|
2006-09-03 08:24:05 -06:00
|
|
|
bool succes = false ;
|
2006-07-30 09:13:41 -06:00
|
|
|
libparted_messages .clear() ;
|
2006-08-01 06:16:22 -06:00
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
if ( calibrate_partition( operation ->partition_original, operation ->operation_detail ) )
|
2006-08-01 06:16:22 -06:00
|
|
|
switch ( operation ->type )
|
|
|
|
{
|
|
|
|
case OPERATION_DELETE:
|
2006-08-20 03:33:54 -06:00
|
|
|
succes = Delete( operation ->partition_original, operation ->operation_detail ) ;
|
2006-08-01 06:16:22 -06:00
|
|
|
break ;
|
|
|
|
case OPERATION_CREATE:
|
|
|
|
succes = create( operation ->device,
|
|
|
|
operation ->partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
operation ->operation_detail ) ;
|
2006-08-01 06:16:22 -06:00
|
|
|
break ;
|
|
|
|
case OPERATION_RESIZE_MOVE:
|
2006-09-03 08:24:05 -06:00
|
|
|
//in case the to be resized/moved partition was a 'copy of..', we need a real path...
|
|
|
|
operation ->partition_new .add_path( operation ->partition_original .get_path(), true ) ;
|
2006-08-01 06:16:22 -06:00
|
|
|
succes = resize_move( operation ->device,
|
|
|
|
operation ->partition_original,
|
|
|
|
operation ->partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
operation ->operation_detail ) ;
|
2006-08-01 06:16:22 -06:00
|
|
|
break ;
|
|
|
|
case OPERATION_FORMAT:
|
2006-08-20 03:33:54 -06:00
|
|
|
succes = format( operation ->partition_new, operation ->operation_detail ) ;
|
2006-08-01 06:16:22 -06:00
|
|
|
break ;
|
2006-09-03 08:24:05 -06:00
|
|
|
case OPERATION_COPY:
|
|
|
|
//FIXME: think a bit about the process of copying, right now it's always a bit different from the rest...
|
|
|
|
//maybe we should change the function of partition_new and partition_original?
|
|
|
|
succes = calibrate_partition( operation ->partition_new, operation ->operation_detail ) &&
|
|
|
|
calibrate_partition( static_cast<OperationCopy*>( operation ) ->partition_copied,
|
|
|
|
operation ->operation_detail ) &&
|
|
|
|
copy( static_cast<OperationCopy*>( operation ) ->partition_copied,
|
2006-08-01 06:16:22 -06:00
|
|
|
operation ->partition_new,
|
|
|
|
static_cast<OperationCopy*>( operation ) ->partition_copied .get_length(),
|
2006-08-20 03:33:54 -06:00
|
|
|
operation ->operation_detail ) ;
|
2006-08-01 06:16:22 -06:00
|
|
|
break ;
|
|
|
|
}
|
|
|
|
|
2006-08-16 14:30:26 -06:00
|
|
|
if ( libparted_messages .size() > 0 )
|
2006-07-30 09:13:41 -06:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operation ->operation_detail .add_child( OperationDetail( _("libparted messages"), STATUS_INFO ) ) ;
|
2006-07-30 09:13:41 -06:00
|
|
|
|
|
|
|
for ( unsigned int t = 0 ; t < libparted_messages .size() ; t++ )
|
2006-08-20 03:33:54 -06:00
|
|
|
operation ->operation_detail .get_last_child() .add_child(
|
2006-07-30 09:13:41 -06:00
|
|
|
OperationDetail( libparted_messages[ t ], STATUS_NONE, FONT_ITALIC ) ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
return succes ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
bool GParted_Core::set_disklabel( const Glib::ustring & device_path, const Glib::ustring & disklabel )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
|
|
|
bool return_value = false ;
|
|
|
|
|
|
|
|
if ( open_device_and_disk( device_path, false ) )
|
|
|
|
{
|
|
|
|
PedDiskType *type = NULL ;
|
|
|
|
type = ped_disk_type_get( disklabel .c_str() ) ;
|
|
|
|
|
|
|
|
if ( type )
|
|
|
|
{
|
|
|
|
lp_disk = ped_disk_new_fresh( lp_device, type );
|
|
|
|
|
|
|
|
return_value = commit() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
close_device_and_disk() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
return return_value ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GParted_Core::toggle_flag( const Partition & partition, const Glib::ustring & flag, bool state )
|
|
|
|
{
|
|
|
|
bool succes = false ;
|
|
|
|
|
|
|
|
if ( open_device_and_disk( partition .device_path ) )
|
|
|
|
{
|
|
|
|
lp_partition = NULL ;
|
|
|
|
if ( partition .type == GParted::TYPE_EXTENDED )
|
|
|
|
lp_partition = ped_disk_extended_partition( lp_disk ) ;
|
|
|
|
else
|
2006-08-01 06:47:03 -06:00
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
|
|
|
if ( lp_partition )
|
|
|
|
{
|
|
|
|
PedPartitionFlag lp_flag = ped_partition_flag_get_by_name( flag .c_str() ) ;
|
|
|
|
|
|
|
|
if ( lp_flag > 0 && ped_partition_set_flag( lp_partition, lp_flag, state ) )
|
|
|
|
succes = commit() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
close_device_and_disk() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
return succes ;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector<FS> & GParted_Core::get_filesystems() const
|
|
|
|
{
|
|
|
|
return FILESYSTEMS ;
|
|
|
|
}
|
|
|
|
|
|
|
|
const FS & GParted_Core::get_fs( GParted::FILESYSTEM filesystem ) const
|
|
|
|
{
|
|
|
|
for ( unsigned int t = 0 ; t < FILESYSTEMS .size() ; t++ )
|
|
|
|
if ( FILESYSTEMS[ t ] .filesystem == filesystem )
|
|
|
|
return FILESYSTEMS[ t ] ;
|
|
|
|
|
|
|
|
return FILESYSTEMS .back() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Glib::ustring> GParted_Core::get_disklabeltypes()
|
|
|
|
{
|
|
|
|
std::vector<Glib::ustring> disklabeltypes ;
|
|
|
|
|
|
|
|
//msdos should be first in the list
|
|
|
|
disklabeltypes .push_back( "msdos" ) ;
|
|
|
|
|
|
|
|
PedDiskType *disk_type ;
|
|
|
|
for ( disk_type = ped_disk_type_get_next( NULL ) ; disk_type ; disk_type = ped_disk_type_get_next( disk_type ) )
|
|
|
|
if ( static_cast<Glib::ustring>( disk_type->name ) != "msdos" )
|
|
|
|
disklabeltypes .push_back( disk_type->name ) ;
|
|
|
|
|
|
|
|
return disklabeltypes ;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Glib::ustring> GParted_Core::get_all_mountpoints()
|
|
|
|
{
|
|
|
|
std::vector<Glib::ustring> mountpoints ;
|
|
|
|
|
|
|
|
for ( iter_mp = mount_info .begin() ; iter_mp != mount_info .end() ; ++iter_mp )
|
|
|
|
mountpoints .insert( mountpoints .end(), iter_mp ->second .begin(), iter_mp ->second .end() ) ;
|
|
|
|
|
|
|
|
return mountpoints ;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::map<Glib::ustring, bool> GParted_Core::get_available_flags( const Partition & partition )
|
|
|
|
{
|
|
|
|
std::map<Glib::ustring, bool> flag_info ;
|
|
|
|
|
|
|
|
if ( open_device_and_disk( partition .device_path ) )
|
|
|
|
{
|
|
|
|
lp_partition = NULL ;
|
|
|
|
if ( partition .type == GParted::TYPE_EXTENDED )
|
|
|
|
lp_partition = ped_disk_extended_partition( lp_disk ) ;
|
|
|
|
else
|
2006-08-01 06:47:03 -06:00
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
|
|
|
if ( lp_partition )
|
|
|
|
{
|
|
|
|
for ( unsigned int t = 0 ; t < flags .size() ; t++ )
|
|
|
|
if ( ped_partition_is_flag_available( lp_partition, flags[ t ] ) )
|
|
|
|
flag_info[ ped_partition_flag_get_name( flags[ t ] ) ] =
|
|
|
|
ped_partition_get_flag( lp_partition, flags[ t ] ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
close_device_and_disk() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
return flag_info ;
|
|
|
|
}
|
|
|
|
|
|
|
|
//private functions...
|
|
|
|
|
2006-03-05 14:08:49 -07:00
|
|
|
void GParted_Core::init_maps()
|
|
|
|
{
|
2006-03-14 14:37:47 -07:00
|
|
|
alternate_paths .clear() ;
|
2006-03-05 14:08:49 -07:00
|
|
|
mount_info .clear() ;
|
2006-03-07 04:55:27 -07:00
|
|
|
fstab_info .clear() ;
|
2006-03-05 14:08:49 -07:00
|
|
|
|
2006-03-07 04:55:27 -07:00
|
|
|
read_mountpoints_from_file( "/proc/mounts", mount_info ) ;
|
|
|
|
read_mountpoints_from_file( "/etc/mtab", mount_info ) ;
|
|
|
|
read_mountpoints_from_file( "/etc/fstab", fstab_info ) ;
|
2006-01-24 16:37:59 -07:00
|
|
|
|
2006-03-07 04:55:27 -07:00
|
|
|
//sort the mountpoints and remove duplicates.. (no need to do this for fstab_info)
|
2006-03-05 14:08:49 -07:00
|
|
|
for ( iter_mp = mount_info .begin() ; iter_mp != mount_info .end() ; ++iter_mp )
|
2006-01-24 16:37:59 -07:00
|
|
|
{
|
2006-03-05 14:08:49 -07:00
|
|
|
std::sort( iter_mp ->second .begin(), iter_mp ->second .end() ) ;
|
|
|
|
|
|
|
|
iter_mp ->second .erase(
|
|
|
|
std::unique( iter_mp ->second .begin(), iter_mp ->second .end() ),
|
|
|
|
iter_mp ->second .end() ) ;
|
2006-01-05 13:01:34 -07:00
|
|
|
}
|
|
|
|
|
2006-03-14 14:37:47 -07:00
|
|
|
//initialize alternate_paths...
|
2006-03-05 14:08:49 -07:00
|
|
|
std::string line ;
|
2006-01-05 13:01:34 -07:00
|
|
|
std::ifstream proc_partitions( "/proc/partitions" ) ;
|
|
|
|
if ( proc_partitions )
|
|
|
|
{
|
|
|
|
char c_str[255] ;
|
|
|
|
|
|
|
|
while ( getline( proc_partitions, line ) )
|
|
|
|
if ( sscanf( line .c_str(), "%*d %*d %*d %255s", c_str ) == 1 )
|
|
|
|
{
|
|
|
|
line = "/dev/" ;
|
|
|
|
line += c_str ;
|
2006-03-14 14:37:47 -07:00
|
|
|
|
|
|
|
if ( realpath( line .c_str(), c_str ) && line != c_str )
|
|
|
|
{
|
|
|
|
//because we can make no assumption about which path libparted will detect
|
|
|
|
//we add all combinations.
|
|
|
|
alternate_paths[ c_str ] = line ;
|
|
|
|
alternate_paths[ line ] = c_str ;
|
|
|
|
}
|
2006-01-05 13:01:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
proc_partitions .close() ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
void GParted_Core::read_mountpoints_from_file( const Glib::ustring & filename,
|
|
|
|
std::map< Glib::ustring, std::vector<Glib::ustring> > & map )
|
2004-12-29 09:38:45 -07:00
|
|
|
{
|
2006-06-18 02:50:17 -06:00
|
|
|
std::string line ;
|
|
|
|
char node[255], mountpoint[255] ;
|
|
|
|
unsigned int index ;
|
|
|
|
|
|
|
|
std::ifstream file( filename .c_str() ) ;
|
|
|
|
if ( file )
|
2005-12-07 04:21:27 -07:00
|
|
|
{
|
2006-06-18 02:50:17 -06:00
|
|
|
while ( getline( file, line ) )
|
|
|
|
if ( Glib::str_has_prefix( line, "/" ) &&
|
|
|
|
sscanf( line .c_str(), "%255s %255s", node, mountpoint ) == 2 &&
|
|
|
|
static_cast<Glib::ustring>( node ) != "/dev/root" )
|
|
|
|
{
|
|
|
|
line = mountpoint ;
|
|
|
|
|
|
|
|
//see if mountpoint contains spaces and deal with it
|
|
|
|
index = line .find( "\\040" ) ;
|
|
|
|
if ( index < line .length() )
|
|
|
|
line .replace( index, 4, " " ) ;
|
|
|
|
|
|
|
|
map[ node ] .push_back( line ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
file .close() ;
|
2005-12-07 04:21:27 -07:00
|
|
|
}
|
2006-06-18 02:50:17 -06:00
|
|
|
}
|
2006-05-31 14:03:49 -06:00
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
bool GParted_Core::check_device_path( const Glib::ustring & device_path )
|
|
|
|
{
|
|
|
|
return ( device_path .length() > 6 && device_path .is_ascii() ) ;
|
|
|
|
}
|
2004-12-29 09:38:45 -07:00
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
std::vector<Glib::ustring> GParted_Core::get_alternate_paths( const Glib::ustring & path )
|
|
|
|
{
|
|
|
|
std::vector<Glib::ustring> paths ;
|
2005-12-07 04:21:27 -07:00
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
iter = alternate_paths .find( path ) ;
|
|
|
|
if ( iter != alternate_paths .end() )
|
|
|
|
paths .push_back( iter ->second ) ;
|
2005-12-07 04:21:27 -07:00
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
return paths ;
|
2004-12-29 09:38:45 -07:00
|
|
|
}
|
|
|
|
|
2004-12-17 12:45:04 -07:00
|
|
|
void GParted_Core::set_device_partitions( Device & device )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
|
|
|
int EXT_INDEX = -1 ;
|
2006-03-28 11:46:08 -07:00
|
|
|
char * lp_path ;//we have to free the result of ped_partition_get_path()..
|
2004-11-17 06:00:25 -07:00
|
|
|
|
|
|
|
//clear partitions
|
2006-01-05 13:01:34 -07:00
|
|
|
device .partitions .clear() ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2005-11-26 17:57:11 -07:00
|
|
|
lp_partition = ped_disk_next_partition( lp_disk, NULL ) ;
|
|
|
|
while ( lp_partition )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-07-30 09:13:41 -06:00
|
|
|
libparted_messages .clear() ;
|
2006-01-05 13:01:34 -07:00
|
|
|
partition_temp .Reset() ;
|
|
|
|
|
2005-11-26 17:57:11 -07:00
|
|
|
switch ( lp_partition ->type )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
|
|
|
case PED_PARTITION_NORMAL:
|
2006-03-28 11:46:08 -07:00
|
|
|
case PED_PARTITION_LOGICAL:
|
|
|
|
lp_path = ped_partition_get_path( lp_partition ) ;
|
2006-03-14 14:37:47 -07:00
|
|
|
partition_temp .Set( device .get_path(),
|
2006-03-28 11:46:08 -07:00
|
|
|
lp_path,
|
2006-01-05 13:01:34 -07:00
|
|
|
lp_partition ->num,
|
2006-09-03 08:24:05 -06:00
|
|
|
lp_partition ->type == 0 ? GParted::TYPE_PRIMARY : GParted::TYPE_LOGICAL,
|
2006-01-05 13:01:34 -07:00
|
|
|
get_filesystem(),
|
|
|
|
lp_partition ->geom .start,
|
|
|
|
lp_partition ->geom .end,
|
|
|
|
lp_partition ->type,
|
2006-03-28 11:46:08 -07:00
|
|
|
ped_partition_is_busy( lp_partition ) ) ;
|
|
|
|
free( lp_path ) ;
|
2005-08-30 20:30:25 -06:00
|
|
|
|
2006-03-14 14:37:47 -07:00
|
|
|
partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ;
|
2006-02-17 16:20:28 -07:00
|
|
|
set_flags( partition_temp ) ;
|
|
|
|
|
2004-12-27 11:56:57 -07:00
|
|
|
if ( partition_temp .busy && partition_temp .partition_number > device .highest_busy )
|
|
|
|
device .highest_busy = partition_temp .partition_number ;
|
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
break ;
|
2006-03-14 14:37:47 -07:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
case PED_PARTITION_EXTENDED:
|
2006-03-28 11:46:08 -07:00
|
|
|
lp_path = ped_partition_get_path( lp_partition ) ;
|
2006-03-14 14:37:47 -07:00
|
|
|
partition_temp .Set( device .get_path(),
|
2006-03-28 11:46:08 -07:00
|
|
|
lp_path,
|
2006-03-14 14:37:47 -07:00
|
|
|
lp_partition ->num,
|
|
|
|
GParted::TYPE_EXTENDED,
|
|
|
|
GParted::FS_EXTENDED,
|
|
|
|
lp_partition ->geom .start,
|
|
|
|
lp_partition ->geom .end,
|
|
|
|
false,
|
2006-03-28 11:46:08 -07:00
|
|
|
ped_partition_is_busy( lp_partition ) ) ;
|
|
|
|
free( lp_path ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2006-03-14 14:37:47 -07:00
|
|
|
partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ;
|
2006-02-17 16:20:28 -07:00
|
|
|
set_flags( partition_temp ) ;
|
2006-03-14 14:37:47 -07:00
|
|
|
|
2006-01-05 13:01:34 -07:00
|
|
|
EXT_INDEX = device .partitions .size() ;
|
2004-11-17 06:00:25 -07:00
|
|
|
break ;
|
|
|
|
|
2005-12-07 04:21:27 -07:00
|
|
|
default:
|
|
|
|
break;
|
2004-11-17 06:00:25 -07:00
|
|
|
}
|
2006-07-30 09:13:41 -06:00
|
|
|
|
|
|
|
partition_temp .messages .insert( partition_temp .messages .end(),
|
|
|
|
libparted_messages. begin(),
|
|
|
|
libparted_messages .end() ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2004-12-12 13:36:00 -07:00
|
|
|
//if there's an end, there's a partition ;)
|
|
|
|
if ( partition_temp .sector_end > -1 )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
|
|
|
if ( ! partition_temp .inside_extended )
|
2006-01-05 13:01:34 -07:00
|
|
|
device .partitions .push_back( partition_temp );
|
2004-11-17 06:00:25 -07:00
|
|
|
else
|
2006-01-05 13:01:34 -07:00
|
|
|
device .partitions[ EXT_INDEX ] .logicals .push_back( partition_temp ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
}
|
2006-07-30 09:13:41 -06:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
//next partition (if any)
|
2005-12-07 04:21:27 -07:00
|
|
|
lp_partition = ped_disk_next_partition( lp_disk, lp_partition ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
}
|
2004-12-12 13:36:00 -07:00
|
|
|
|
|
|
|
if ( EXT_INDEX > -1 )
|
2006-03-14 14:37:47 -07:00
|
|
|
insert_unallocated( device .get_path(),
|
2006-01-05 13:01:34 -07:00
|
|
|
device .partitions[ EXT_INDEX ] .logicals,
|
|
|
|
device .partitions[ EXT_INDEX ] .sector_start,
|
|
|
|
device .partitions[ EXT_INDEX ] .sector_end,
|
2005-12-13 18:58:15 -07:00
|
|
|
true ) ;
|
2004-12-12 13:36:00 -07:00
|
|
|
|
2006-03-14 14:37:47 -07:00
|
|
|
insert_unallocated( device .get_path(), device .partitions, 0, device .length -1, false ) ;
|
2004-12-12 13:36:00 -07:00
|
|
|
}
|
2006-06-18 02:50:17 -06:00
|
|
|
|
|
|
|
GParted::FILESYSTEM GParted_Core::get_filesystem()
|
2006-04-02 12:03:37 -06:00
|
|
|
{
|
2006-06-18 02:50:17 -06:00
|
|
|
//standard libparted filesystems..
|
|
|
|
if ( lp_partition && lp_partition ->fs_type )
|
2006-04-02 12:03:37 -06:00
|
|
|
{
|
2006-08-01 07:18:22 -06:00
|
|
|
if ( Glib::ustring( lp_partition ->fs_type ->name ) == "extended" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_EXTENDED ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "ext2" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_EXT2 ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "ext3" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_EXT3 ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "linux-swap" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_LINUX_SWAP ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "fat16" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_FAT16 ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "fat32" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_FAT32 ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "ntfs" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_NTFS ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "reiserfs" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_REISERFS ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "xfs" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_XFS ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "jfs" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_JFS ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "hfs" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_HFS ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "hfs+" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_HFSPLUS ;
|
2006-08-01 07:18:22 -06:00
|
|
|
else if ( Glib::ustring( lp_partition ->fs_type ->name ) == "ufs" )
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_UFS ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//other filesystems libparted couldn't detect (i've send patches for these filesystems to the parted guys)
|
|
|
|
char buf[512] ;
|
2006-04-03 12:48:53 -06:00
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
ped_device_open( lp_device );
|
2006-04-03 12:48:53 -06:00
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
//reiser4
|
|
|
|
ped_geometry_read( & lp_partition ->geom, buf, 128, 1 ) ;
|
|
|
|
ped_device_close( lp_device );
|
|
|
|
|
|
|
|
if ( static_cast<Glib::ustring>( buf ) == "ReIsEr4" )
|
|
|
|
return GParted::FS_REISER4 ;
|
|
|
|
|
|
|
|
//no filesystem found....
|
2006-07-30 09:13:41 -06:00
|
|
|
temp = _( "Unable to detect filesystem! Possible reasons are:" ) ;
|
|
|
|
temp += "\n-";
|
|
|
|
temp += _( "The filesystem is damaged" ) ;
|
|
|
|
temp += "\n-" ;
|
|
|
|
temp += _( "The filesystem is unknown to GParted" ) ;
|
|
|
|
temp += "\n-";
|
|
|
|
temp += _( "There is no filesystem available (unformatted)" ) ;
|
|
|
|
|
|
|
|
partition_temp .messages .push_back( temp ) ;
|
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
return GParted::FS_UNKNOWN ;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GParted_Core::insert_unallocated( const Glib::ustring & device_path,
|
|
|
|
std::vector<Partition> & partitions,
|
|
|
|
Sector start,
|
|
|
|
Sector end,
|
|
|
|
bool inside_extended )
|
|
|
|
{
|
|
|
|
partition_temp .Reset() ;
|
|
|
|
partition_temp .Set_Unallocated( device_path, 0, 0, inside_extended ) ;
|
|
|
|
|
|
|
|
//if there are no partitions at all..
|
|
|
|
if ( partitions .empty() )
|
|
|
|
{
|
|
|
|
partition_temp .sector_start = start ;
|
|
|
|
partition_temp .sector_end = end ;
|
|
|
|
|
|
|
|
partitions .push_back( partition_temp );
|
|
|
|
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
|
|
|
//start <---> first partition start
|
|
|
|
if ( (partitions .front() .sector_start - start) >= MEBIBYTE )
|
|
|
|
{
|
|
|
|
partition_temp .sector_start = start ;
|
|
|
|
partition_temp .sector_end = partitions .front() .sector_start -1 ;
|
|
|
|
|
|
|
|
partitions .insert( partitions .begin(), partition_temp );
|
|
|
|
}
|
|
|
|
|
|
|
|
//look for gaps in between
|
|
|
|
for ( unsigned int t =0 ; t < partitions .size() -1 ; t++ )
|
|
|
|
if ( ( partitions[ t +1 ] .sector_start - partitions[ t ] .sector_end ) >= MEBIBYTE )
|
|
|
|
{
|
|
|
|
partition_temp .sector_start = partitions[ t ] .sector_end +1 ;
|
|
|
|
partition_temp .sector_end = partitions[ t +1 ] .sector_start -1 ;
|
|
|
|
|
|
|
|
partitions .insert( partitions .begin() + ++t, partition_temp );
|
2006-04-02 12:03:37 -06:00
|
|
|
}
|
2006-06-18 02:50:17 -06:00
|
|
|
|
|
|
|
//last partition end <---> end
|
|
|
|
if ( (end - partitions .back() .sector_end ) >= MEBIBYTE )
|
|
|
|
{
|
|
|
|
partition_temp .sector_start = partitions .back() .sector_end +1 ;
|
|
|
|
partition_temp .sector_end = end ;
|
|
|
|
|
|
|
|
partitions .push_back( partition_temp );
|
2006-04-02 12:03:37 -06:00
|
|
|
}
|
|
|
|
}
|
2006-06-18 02:50:17 -06:00
|
|
|
|
2006-01-05 13:01:34 -07:00
|
|
|
void GParted_Core::set_mountpoints( std::vector<Partition> & partitions )
|
2005-12-08 10:03:29 -07:00
|
|
|
{
|
|
|
|
for ( unsigned int t = 0 ; t < partitions .size() ; t++ )
|
|
|
|
{
|
2006-03-07 04:55:27 -07:00
|
|
|
if ( ( partitions[ t ] .type == GParted::TYPE_PRIMARY ||
|
|
|
|
partitions[ t ] .type == GParted::TYPE_LOGICAL ) &&
|
|
|
|
partitions[ t ] .filesystem != GParted::FS_LINUX_SWAP )
|
2005-12-08 10:03:29 -07:00
|
|
|
{
|
2006-03-07 04:55:27 -07:00
|
|
|
if ( partitions[ t ] .busy )
|
2005-12-08 10:03:29 -07:00
|
|
|
{
|
2006-03-14 14:37:47 -07:00
|
|
|
for ( unsigned int i = 0 ; i < partitions[ t ] .get_paths() .size() ; i++ )
|
|
|
|
{
|
|
|
|
iter_mp = mount_info .find( partitions[ t ] .get_paths()[ i ] ) ;
|
|
|
|
if ( iter_mp != mount_info .end() )
|
|
|
|
{
|
2006-03-15 09:12:11 -07:00
|
|
|
partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
|
2006-03-14 14:37:47 -07:00
|
|
|
break ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-15 09:12:11 -07:00
|
|
|
if ( partitions[ t ] .get_mountpoints() .empty() )
|
2006-07-30 09:13:41 -06:00
|
|
|
partitions[ t ] .messages .push_back( _("Unable to find mountpoint") ) ;
|
2005-12-08 10:03:29 -07:00
|
|
|
}
|
2006-03-07 04:55:27 -07:00
|
|
|
else
|
|
|
|
{
|
2006-03-14 14:37:47 -07:00
|
|
|
iter_mp = fstab_info .find( partitions[ t ] .get_path() );
|
2006-03-07 04:55:27 -07:00
|
|
|
if ( iter_mp != fstab_info .end() )
|
2006-03-15 09:12:11 -07:00
|
|
|
partitions[ t ] .add_mountpoints( iter_mp ->second ) ;
|
2006-03-07 04:55:27 -07:00
|
|
|
}
|
2005-12-08 10:03:29 -07:00
|
|
|
}
|
2006-03-07 04:55:27 -07:00
|
|
|
else if ( partitions[ t ] .type == GParted::TYPE_EXTENDED )
|
|
|
|
set_mountpoints( partitions[ t ] .logicals ) ;
|
2005-12-08 10:03:29 -07:00
|
|
|
}
|
2006-01-05 13:01:34 -07:00
|
|
|
}
|
2006-03-14 14:37:47 -07:00
|
|
|
|
2005-12-10 17:05:28 -07:00
|
|
|
void GParted_Core::set_used_sectors( std::vector<Partition> & partitions )
|
|
|
|
{
|
|
|
|
struct statvfs sfs ;
|
|
|
|
|
|
|
|
temp = _("Unable to read the contents of this filesystem!") ;
|
|
|
|
temp += "\n" ;
|
|
|
|
temp += _("Because of this some operations may be unavailable.") ;
|
|
|
|
|
|
|
|
for ( unsigned int t = 0 ; t < partitions .size() ; t++ )
|
|
|
|
{
|
2006-02-25 05:25:18 -07:00
|
|
|
if ( partitions[ t ] .filesystem != GParted::FS_LINUX_SWAP &&
|
|
|
|
partitions[ t ] .filesystem != GParted::FS_UNKNOWN )
|
2005-12-10 17:05:28 -07:00
|
|
|
{
|
2006-02-25 05:25:18 -07:00
|
|
|
if ( partitions[ t ] .type == GParted::TYPE_PRIMARY ||
|
|
|
|
partitions[ t ] .type == GParted::TYPE_LOGICAL )
|
2005-12-10 17:05:28 -07:00
|
|
|
{
|
|
|
|
if ( partitions[ t ] .busy )
|
|
|
|
{
|
2006-03-15 09:12:11 -07:00
|
|
|
if ( partitions[ t ] .get_mountpoints() .size() > 0 )
|
2006-07-30 09:13:41 -06:00
|
|
|
{
|
2006-03-15 09:12:11 -07:00
|
|
|
if ( statvfs( partitions[ t ] .get_mountpoint() .c_str(), &sfs ) == 0 )
|
2006-03-05 08:11:47 -07:00
|
|
|
partitions[ t ] .Set_Unused( sfs .f_bfree * (sfs .f_bsize / 512) ) ;
|
|
|
|
else
|
2006-07-30 09:13:41 -06:00
|
|
|
partitions[ t ] .messages .push_back(
|
2006-05-31 14:03:49 -06:00
|
|
|
"statvfs (" +
|
|
|
|
partitions[ t ] .get_mountpoint() +
|
|
|
|
"): " +
|
2006-07-30 09:13:41 -06:00
|
|
|
Glib::strerror( errno ) ) ;
|
2006-03-05 08:11:47 -07:00
|
|
|
}
|
2005-12-10 17:05:28 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch( get_fs( partitions[ t ] .filesystem ) .read )
|
|
|
|
{
|
|
|
|
case GParted::FS::EXTERNAL :
|
2006-08-13 07:31:57 -06:00
|
|
|
if ( set_proper_filesystem( partitions[ t ] .filesystem ) )
|
2006-08-20 03:33:54 -06:00
|
|
|
p_filesystem ->set_used_sectors( partitions[ t ] ) ;
|
2005-12-10 17:05:28 -07:00
|
|
|
break ;
|
|
|
|
case GParted::FS::LIBPARTED :
|
2006-06-18 02:50:17 -06:00
|
|
|
LP_set_used_sectors( partitions[ t ] ) ;
|
2005-12-10 17:05:28 -07:00
|
|
|
break ;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-30 09:13:41 -06:00
|
|
|
if ( partitions[ t ] .sectors_used == -1 )
|
|
|
|
partitions[ t ] .messages .push_back( temp ) ;
|
2005-12-10 17:05:28 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
else if ( partitions[ t ] .type == GParted::TYPE_EXTENDED )
|
|
|
|
set_used_sectors( partitions[ t ] .logicals ) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-06-18 02:50:17 -06:00
|
|
|
|
|
|
|
void GParted_Core::LP_set_used_sectors( Partition & partition )
|
2004-12-12 13:36:00 -07:00
|
|
|
{
|
2006-06-18 02:50:17 -06:00
|
|
|
PedFileSystem *fs = NULL;
|
|
|
|
PedConstraint *constraint = NULL;
|
|
|
|
|
|
|
|
if ( lp_disk )
|
2004-12-12 13:36:00 -07:00
|
|
|
{
|
2006-08-01 06:47:03 -06:00
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
|
2004-12-12 13:36:00 -07:00
|
|
|
|
2006-06-18 02:50:17 -06:00
|
|
|
if ( lp_partition )
|
2004-12-12 13:36:00 -07:00
|
|
|
{
|
2006-06-18 02:50:17 -06:00
|
|
|
fs = ped_file_system_open( & lp_partition ->geom );
|
|
|
|
|
|
|
|
if ( fs )
|
|
|
|
{
|
|
|
|
constraint = ped_file_system_get_resize_constraint( fs ) ;
|
|
|
|
if ( constraint )
|
|
|
|
{
|
|
|
|
partition .Set_Unused( partition .get_length() - constraint ->min_size ) ;
|
|
|
|
|
|
|
|
ped_constraint_destroy( constraint );
|
|
|
|
}
|
|
|
|
|
|
|
|
ped_file_system_close( fs ) ;
|
|
|
|
}
|
2004-12-12 13:36:00 -07:00
|
|
|
}
|
|
|
|
}
|
2006-06-18 02:50:17 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void GParted_Core::set_flags( Partition & partition )
|
|
|
|
{
|
|
|
|
for ( unsigned int t = 0 ; t < flags .size() ; t++ )
|
|
|
|
if ( ped_partition_is_flag_available( lp_partition, flags[ t ] ) &&
|
|
|
|
ped_partition_get_flag( lp_partition, flags[ t ] ) )
|
|
|
|
partition .flags .push_back( ped_partition_flag_get_name( flags[ t ] ) ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
}
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool GParted_Core::create( const Device & device, Partition & new_partition, OperationDetail & operationdetail )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-01-19 12:15:15 -07:00
|
|
|
if ( new_partition .type == GParted::TYPE_EXTENDED )
|
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
return create_partition( new_partition, operationdetail ) ;
|
2006-01-19 12:15:15 -07:00
|
|
|
}
|
2006-08-20 03:33:54 -06:00
|
|
|
else if ( create_partition( new_partition, operationdetail, get_fs( new_partition .filesystem ) .MIN ) )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-06-17 02:56:24 -06:00
|
|
|
if ( new_partition .filesystem == GParted::FS_UNFORMATTED )
|
2004-11-28 07:30:15 -07:00
|
|
|
return true ;
|
2006-06-17 02:56:24 -06:00
|
|
|
else
|
2006-08-20 03:33:54 -06:00
|
|
|
return set_partition_type( new_partition, operationdetail ) &&
|
|
|
|
create_filesystem( new_partition, operationdetail ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool GParted_Core::create_partition( Partition & new_partition, OperationDetail & operationdetail, Sector min_size )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("create empty partition") ) ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
new_partition .partition_number = 0 ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
if ( open_device_and_disk( new_partition .device_path ) )
|
2006-05-31 14:03:49 -06:00
|
|
|
{
|
2006-06-17 14:52:25 -06:00
|
|
|
PedPartitionType type;
|
|
|
|
lp_partition = NULL ;
|
|
|
|
PedConstraint *constraint = NULL ;
|
|
|
|
PedFileSystemType* fs_type = NULL ;
|
|
|
|
|
|
|
|
//create new partition
|
|
|
|
switch ( new_partition .type )
|
2006-05-31 14:03:49 -06:00
|
|
|
{
|
2006-06-17 14:52:25 -06:00
|
|
|
case GParted::TYPE_PRIMARY:
|
|
|
|
type = PED_PARTITION_NORMAL ;
|
|
|
|
break ;
|
|
|
|
case GParted::TYPE_LOGICAL:
|
|
|
|
type = PED_PARTITION_LOGICAL ;
|
|
|
|
break ;
|
|
|
|
case GParted::TYPE_EXTENDED:
|
|
|
|
type = PED_PARTITION_EXTENDED ;
|
|
|
|
break ;
|
|
|
|
|
|
|
|
default :
|
|
|
|
type = PED_PARTITION_FREESPACE;
|
2006-05-31 14:03:49 -06:00
|
|
|
}
|
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
if ( new_partition .type != GParted::TYPE_EXTENDED )
|
|
|
|
fs_type = ped_file_system_type_get( "ext2" ) ;
|
|
|
|
|
|
|
|
lp_partition = ped_partition_new( lp_disk,
|
|
|
|
type,
|
|
|
|
fs_type,
|
|
|
|
new_partition .sector_start,
|
|
|
|
new_partition .sector_end ) ;
|
|
|
|
|
|
|
|
if ( lp_partition )
|
|
|
|
{
|
|
|
|
if ( new_partition .strict )
|
|
|
|
{
|
|
|
|
PedGeometry *geom = ped_geometry_new( lp_device,
|
|
|
|
new_partition .sector_start,
|
|
|
|
new_partition .get_length() ) ;
|
|
|
|
|
|
|
|
if ( geom )
|
|
|
|
constraint = ped_constraint_exact( geom ) ;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
constraint = ped_constraint_any( lp_device );
|
|
|
|
|
|
|
|
if ( constraint )
|
|
|
|
{
|
|
|
|
if ( min_size > 0 )
|
|
|
|
constraint ->min_size = min_size ;
|
2006-08-20 05:47:17 -06:00
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
if ( ped_disk_add_partition( lp_disk, lp_partition, constraint ) && commit() )
|
|
|
|
{
|
|
|
|
//we have to free the result of ped_partition_get_path()..
|
|
|
|
char * lp_path = ped_partition_get_path( lp_partition ) ;
|
|
|
|
new_partition .add_path( lp_path, true ) ;
|
|
|
|
free( lp_path ) ;
|
|
|
|
|
|
|
|
new_partition .partition_number = lp_partition ->num ;
|
|
|
|
new_partition .sector_start = lp_partition ->geom .start ;
|
|
|
|
new_partition .sector_end = lp_partition ->geom .end ;
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child( OperationDetail(
|
2006-06-17 14:52:25 -06:00
|
|
|
String::ucompose( _("path: %1"), new_partition .get_path() ) + "\n" +
|
|
|
|
String::ucompose( _("start: %1"), new_partition .sector_start ) + "\n" +
|
|
|
|
String::ucompose( _("end: %1"), new_partition .sector_end ) + "\n" +
|
2006-07-23 12:43:15 -06:00
|
|
|
String::ucompose( _("size: %1 (%2)"),
|
|
|
|
new_partition .get_length(),
|
2006-07-29 02:27:28 -06:00
|
|
|
Utils::format_size( new_partition .get_length() ) ),
|
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
ped_constraint_destroy( constraint );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close_device_and_disk() ;
|
|
|
|
}
|
2006-09-03 08:24:05 -06:00
|
|
|
//FIXME: if we create an extended partition and want to do some other operation right after it, it may fail...
|
|
|
|
//there is no extended path to wait for, but maybe we could wait for the device_path to appear? (i think the same goes for
|
|
|
|
//resize/move)
|
2006-06-17 14:52:25 -06:00
|
|
|
if ( new_partition .partition_number > 0 &&
|
2006-08-20 05:47:17 -06:00
|
|
|
erase_filesystem_signatures( new_partition ) &&
|
|
|
|
( new_partition .type == GParted::TYPE_EXTENDED || wait_for_node( new_partition .get_path() ) ) )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( STATUS_SUCCES ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
return true ;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( STATUS_ERROR ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool GParted_Core::create_filesystem( const Partition & partition, OperationDetail & operationdetail )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( String::ucompose(
|
|
|
|
_("create new %1 filesystem"),
|
|
|
|
Utils::get_filesystem_string( partition .filesystem ) ) ) ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-08-13 07:31:57 -06:00
|
|
|
bool succes = false ;
|
|
|
|
switch ( get_fs( partition .filesystem ) .create )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-08-13 07:31:57 -06:00
|
|
|
case GParted::FS::NONE:
|
|
|
|
break ;
|
|
|
|
case GParted::FS::GPARTED:
|
|
|
|
break ;
|
|
|
|
case GParted::FS::LIBPARTED:
|
|
|
|
break ;
|
|
|
|
case GParted::FS::EXTERNAL:
|
|
|
|
succes = set_proper_filesystem( partition .filesystem ) &&
|
2006-08-20 03:33:54 -06:00
|
|
|
p_filesystem ->create( partition, operationdetail .get_last_child() ) ;
|
2006-08-13 07:31:57 -06:00
|
|
|
|
|
|
|
break ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
2006-08-13 07:31:57 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
2006-08-13 07:31:57 -06:00
|
|
|
return succes ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool GParted_Core::format( const Partition & partition, OperationDetail & operationdetail )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
|
|
|
//remove all filesystem signatures...
|
|
|
|
erase_filesystem_signatures( partition ) ;
|
2006-08-20 03:33:54 -06:00
|
|
|
|
|
|
|
return set_partition_type( partition, operationdetail ) && create_filesystem( partition, operationdetail ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool GParted_Core::Delete( const Partition & partition, OperationDetail & operationdetail )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
|
|
|
bool return_value = false ;
|
|
|
|
|
|
|
|
if ( open_device_and_disk( partition .device_path ) )
|
|
|
|
{
|
|
|
|
if ( partition .type == GParted::TYPE_EXTENDED )
|
|
|
|
lp_partition = ped_disk_extended_partition( lp_disk ) ;
|
|
|
|
else
|
2006-08-01 06:47:03 -06:00
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-08-26 08:37:06 -06:00
|
|
|
return_value = ped_disk_delete_partition( lp_disk, lp_partition ) && commit( partition .device_path ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
|
|
|
close_device_and_disk() ;
|
|
|
|
}
|
2006-07-30 09:13:41 -06:00
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
return return_value ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GParted_Core::resize_move( const Device & device,
|
|
|
|
const Partition & partition_old,
|
|
|
|
Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-08-27 02:41:25 -06:00
|
|
|
if ( partition_new .strict || calculate_exact_geom( partition_old, partition_new, operationdetail ) )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-08-27 02:41:25 -06:00
|
|
|
if ( partition_old .type == TYPE_EXTENDED )
|
2006-08-20 03:33:54 -06:00
|
|
|
return resize_move_partition( partition_old, partition_new, operationdetail ) ;
|
2006-08-27 02:41:25 -06:00
|
|
|
|
2006-07-23 10:51:38 -06:00
|
|
|
if ( partition_new .sector_start == partition_old .sector_start )
|
2006-08-20 03:33:54 -06:00
|
|
|
return resize( partition_old, partition_new, operationdetail ) ;
|
2006-08-27 02:41:25 -06:00
|
|
|
|
|
|
|
if ( partition_new .get_length() == partition_old .get_length() )
|
|
|
|
return move( device, partition_old, partition_new, operationdetail ) ;
|
|
|
|
|
|
|
|
Partition temp ;
|
|
|
|
if ( partition_new .get_length() > partition_old .get_length() )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-08-27 02:41:25 -06:00
|
|
|
//first move, then grow. Since old.length < new.length and new.start is valid, temp is valid.
|
|
|
|
temp = partition_new ;
|
2006-07-23 12:43:15 -06:00
|
|
|
temp .sector_end = temp .sector_start + partition_old .get_length() -1 ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
2006-08-27 02:41:25 -06:00
|
|
|
|
|
|
|
if ( partition_new .get_length() < partition_old .get_length() )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-08-27 02:41:25 -06:00
|
|
|
//first shrink, then move. Since new.length < old.length and old.start is valid, temp is valid.
|
|
|
|
temp = partition_old ;
|
2006-07-23 12:43:15 -06:00
|
|
|
temp .sector_end = partition_old .sector_start + partition_new .get_length() -1 ;
|
2006-07-23 03:58:45 -06:00
|
|
|
}
|
2006-08-27 02:41:25 -06:00
|
|
|
|
|
|
|
temp .strict = true ;
|
|
|
|
bool succes = resize_move( device, partition_old, temp, operationdetail ) ;
|
|
|
|
temp .strict = false ;
|
|
|
|
|
|
|
|
return succes && resize_move( device, temp, partition_new, operationdetail ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
2006-07-23 03:58:45 -06:00
|
|
|
|
|
|
|
return false ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
|
|
|
|
2006-07-23 10:51:38 -06:00
|
|
|
bool GParted_Core::move( const Device & device,
|
|
|
|
const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail )
|
2006-07-23 10:51:38 -06:00
|
|
|
{
|
2006-08-27 02:41:25 -06:00
|
|
|
if ( partition_old .get_length() != partition_new .get_length() )
|
|
|
|
{
|
|
|
|
operationdetail .add_child( OperationDetail(
|
|
|
|
_("moving requires old and new length to be the same"), STATUS_ERROR, FONT_ITALIC ) ) ;
|
|
|
|
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
return check_repair_filesystem( partition_old, operationdetail ) &&
|
|
|
|
move_filesystem( partition_old, partition_new, operationdetail ) &&
|
|
|
|
resize_move_partition( partition_old, partition_new, operationdetail ) &&
|
|
|
|
check_repair_filesystem( partition_new, operationdetail ) &&
|
|
|
|
maximize_filesystem( partition_new, operationdetail ) ;
|
2006-07-23 10:51:38 -06:00
|
|
|
}
|
|
|
|
|
2006-06-18 13:27:52 -06:00
|
|
|
bool GParted_Core::move_filesystem( const Partition & partition_old,
|
2006-07-23 03:58:45 -06:00
|
|
|
const Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail )
|
2006-05-31 14:03:49 -06:00
|
|
|
{
|
2006-07-11 12:13:27 -06:00
|
|
|
if ( partition_new .sector_start < partition_old .sector_start )
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("move filesystem to the left") ) ) ;
|
2006-07-19 13:02:18 -06:00
|
|
|
else if ( partition_new .sector_start > partition_old .sector_start )
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("move filesystem to the right") ) ) ;
|
2006-07-19 13:02:18 -06:00
|
|
|
else
|
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("move filesystem") ) ) ;
|
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-07-29 02:27:28 -06:00
|
|
|
OperationDetail( _("new and old filesystem have the same positition. skipping this operation"),
|
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-07-19 13:02:18 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( STATUS_SUCCES ) ;
|
2006-07-19 13:02:18 -06:00
|
|
|
return true ;
|
|
|
|
}
|
2006-06-18 13:27:52 -06:00
|
|
|
|
2006-05-31 14:03:49 -06:00
|
|
|
bool succes = false ;
|
2006-07-23 03:58:45 -06:00
|
|
|
switch ( get_fs( partition_old .filesystem ) .move )
|
2006-05-31 14:03:49 -06:00
|
|
|
{
|
2006-07-23 03:58:45 -06:00
|
|
|
case GParted::FS::NONE:
|
|
|
|
break ;
|
|
|
|
case GParted::FS::GPARTED:
|
2006-08-31 14:19:38 -06:00
|
|
|
succes = copy_filesystem( partition_old, partition_new, operationdetail .get_last_child() ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
break ;
|
|
|
|
case GParted::FS::LIBPARTED:
|
|
|
|
succes = resize_move_filesystem_using_libparted( partition_old,
|
|
|
|
partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
break ;
|
|
|
|
case GParted::FS::EXTERNAL:
|
|
|
|
break ;
|
|
|
|
}
|
2006-07-11 12:13:27 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
return succes ;
|
|
|
|
}
|
2006-05-31 14:03:49 -06:00
|
|
|
|
2006-07-23 03:58:45 -06:00
|
|
|
bool GParted_Core::resize_move_filesystem_using_libparted( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("using libparted"), STATUS_NONE ) ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
|
|
|
|
bool return_value = false ;
|
|
|
|
if ( open_device_and_disk( partition_old .device_path ) )
|
2006-06-17 02:56:24 -06:00
|
|
|
{
|
2006-07-23 03:58:45 -06:00
|
|
|
PedPartition * lp_partition = NULL ;
|
|
|
|
PedFileSystem * fs = NULL ;
|
|
|
|
PedGeometry * lp_geom = NULL ;
|
|
|
|
|
2006-08-01 06:47:03 -06:00
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition_old .get_sector() ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
if ( lp_partition )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-07-23 03:58:45 -06:00
|
|
|
fs = ped_file_system_open( & lp_partition ->geom );
|
|
|
|
if ( fs )
|
|
|
|
{
|
|
|
|
lp_geom = ped_geometry_new( lp_device,
|
|
|
|
partition_new .sector_start,
|
|
|
|
partition_new .get_length() ) ;
|
|
|
|
if ( lp_geom )
|
2006-08-20 05:47:17 -06:00
|
|
|
return_value = ped_file_system_resize( fs, lp_geom, NULL ) &&
|
|
|
|
commit( partition_new .get_path() ) ;
|
|
|
|
|
2006-07-23 03:58:45 -06:00
|
|
|
ped_file_system_close( fs );
|
|
|
|
}
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
2006-07-23 03:58:45 -06:00
|
|
|
|
|
|
|
close_device_and_disk() ;
|
2006-06-17 02:56:24 -06:00
|
|
|
}
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-07-23 03:58:45 -06:00
|
|
|
return return_value ;
|
|
|
|
}
|
|
|
|
|
2006-07-23 12:43:15 -06:00
|
|
|
bool GParted_Core::resize( const Partition & partition_old,
|
2006-07-23 10:51:38 -06:00
|
|
|
const Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail )
|
2006-07-23 03:58:45 -06:00
|
|
|
{
|
2006-08-27 02:41:25 -06:00
|
|
|
if ( partition_old .sector_start != partition_new .sector_start )
|
|
|
|
{
|
|
|
|
operationdetail .add_child( OperationDetail(
|
|
|
|
_("resizing requires old and new start to be the same"), STATUS_ERROR, FONT_ITALIC ) ) ;
|
|
|
|
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
|
2006-07-23 03:58:45 -06:00
|
|
|
bool succes = false ;
|
2006-08-20 03:33:54 -06:00
|
|
|
if ( check_repair_filesystem( partition_new, operationdetail ) )
|
2006-06-17 02:56:24 -06:00
|
|
|
{
|
2006-06-17 14:52:25 -06:00
|
|
|
succes = true ;
|
2006-07-23 03:58:45 -06:00
|
|
|
|
|
|
|
if ( succes && partition_new .get_length() < partition_old .get_length() )
|
2006-08-20 03:33:54 -06:00
|
|
|
succes = resize_filesystem( partition_old, partition_new, operationdetail ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
|
|
|
if ( succes )
|
2006-08-20 03:33:54 -06:00
|
|
|
succes = resize_move_partition( partition_old, partition_new, operationdetail ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
//these 2 are always executed, however, if 1 of them fails the whole operation fails
|
|
|
|
if ( ! check_repair_filesystem( partition_new, operationdetail ) )
|
2006-06-17 14:52:25 -06:00
|
|
|
succes = false ;
|
|
|
|
|
|
|
|
//expand filesystem to fit exactly in partition
|
2006-08-20 03:33:54 -06:00
|
|
|
if ( ! maximize_filesystem( partition_new, operationdetail ) )
|
2006-06-17 14:52:25 -06:00
|
|
|
succes = false ;
|
|
|
|
|
|
|
|
return succes ;
|
2006-06-17 02:56:24 -06:00
|
|
|
}
|
2006-06-17 14:52:25 -06:00
|
|
|
|
|
|
|
return false ;
|
2006-06-17 02:56:24 -06:00
|
|
|
}
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2006-06-18 13:38:29 -06:00
|
|
|
bool GParted_Core::resize_move_partition( const Partition & partition_old,
|
2006-07-23 03:58:45 -06:00
|
|
|
const Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-07-11 12:13:27 -06:00
|
|
|
//i'm not too happy with this, but i think it is the correct way from a i18n POV
|
|
|
|
enum Action
|
2006-06-18 13:27:52 -06:00
|
|
|
{
|
2006-07-11 12:13:27 -06:00
|
|
|
NONE = 0,
|
|
|
|
MOVE_RIGHT = 1,
|
|
|
|
MOVE_LEFT = 2,
|
|
|
|
GROW = 3,
|
|
|
|
SHRINK = 4,
|
|
|
|
MOVE_RIGHT_GROW = 5,
|
|
|
|
MOVE_RIGHT_SHRINK = 6,
|
|
|
|
MOVE_LEFT_GROW = 7,
|
|
|
|
MOVE_LEFT_SHRINK = 8
|
|
|
|
} ;
|
|
|
|
Action action = NONE ;
|
|
|
|
|
|
|
|
if ( partition_new .get_length() > partition_old .get_length() )
|
|
|
|
action = GROW ;
|
|
|
|
else if ( partition_new .get_length() < partition_old .get_length() )
|
|
|
|
action = SHRINK ;
|
|
|
|
|
|
|
|
if ( partition_new .sector_start > partition_old .sector_start &&
|
|
|
|
partition_new .sector_end > partition_old .sector_end )
|
|
|
|
action = action == GROW ? MOVE_RIGHT_GROW : action == SHRINK ? MOVE_RIGHT_SHRINK : MOVE_RIGHT ;
|
|
|
|
else if ( partition_new .sector_start < partition_old .sector_start &&
|
|
|
|
partition_new .sector_end < partition_old .sector_end )
|
|
|
|
action = action == GROW ? MOVE_LEFT_GROW : action == SHRINK ? MOVE_LEFT_SHRINK : MOVE_LEFT ;
|
|
|
|
|
|
|
|
Glib::ustring description ;
|
|
|
|
switch ( action )
|
|
|
|
{
|
|
|
|
case NONE :
|
|
|
|
description = _("resize/move partition") ;
|
|
|
|
break ;
|
|
|
|
case MOVE_RIGHT :
|
|
|
|
description = _("move partition to the right") ;
|
|
|
|
break ;
|
|
|
|
case MOVE_LEFT :
|
|
|
|
description = _("move partition to the left") ;
|
|
|
|
break ;
|
|
|
|
case GROW :
|
|
|
|
description = _("grow partition from %1 to %2") ;
|
|
|
|
break ;
|
|
|
|
case SHRINK :
|
|
|
|
description = _("shrink partition from %1 to %2") ;
|
|
|
|
break ;
|
|
|
|
case MOVE_RIGHT_GROW :
|
|
|
|
description = _("move partition to the right and grow it from %1 to %2") ;
|
|
|
|
break ;
|
|
|
|
case MOVE_RIGHT_SHRINK :
|
|
|
|
description = _("move partition to the right and shrink it from %1 to %2") ;
|
|
|
|
break ;
|
|
|
|
case MOVE_LEFT_GROW :
|
|
|
|
description = _("move partition to the left and grow it from %1 to %2") ;
|
|
|
|
break ;
|
|
|
|
case MOVE_LEFT_SHRINK :
|
|
|
|
description = _("move partition to the left and shrink it from %1 to %2") ;
|
|
|
|
break ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ! description .empty() && action != NONE && action != MOVE_LEFT && action != MOVE_RIGHT )
|
|
|
|
description = String::ucompose( description,
|
|
|
|
Utils::format_size( partition_old .get_length() ),
|
|
|
|
Utils::format_size( partition_new .get_length() ) ) ;
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( description ) ) ;
|
2006-07-11 12:13:27 -06:00
|
|
|
|
|
|
|
|
|
|
|
if ( action == NONE )
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-08-31 14:19:38 -06:00
|
|
|
OperationDetail( _("new and old partition have the same size and position. continuing anyway"),
|
2006-07-29 02:27:28 -06:00
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-02-17 14:18:07 -07:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-07-29 02:27:28 -06:00
|
|
|
OperationDetail(
|
2006-02-17 14:18:07 -07:00
|
|
|
String::ucompose( _("old start: %1"), partition_old .sector_start ) + "\n" +
|
|
|
|
String::ucompose( _("old end: %1"), partition_old .sector_end ) + "\n" +
|
2006-07-23 12:43:15 -06:00
|
|
|
String::ucompose( _("old size: %1 (%2)"),
|
|
|
|
partition_old .get_length(),
|
2006-07-29 02:27:28 -06:00
|
|
|
Utils::format_size( partition_old .get_length() ) ),
|
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-01-19 12:15:15 -07:00
|
|
|
|
2006-07-11 12:13:27 -06:00
|
|
|
//finally the actual resize/move
|
2004-11-17 06:00:25 -07:00
|
|
|
bool return_value = false ;
|
|
|
|
|
2004-11-21 14:49:38 -07:00
|
|
|
PedConstraint *constraint = NULL ;
|
2005-11-26 17:57:11 -07:00
|
|
|
lp_partition = NULL ;
|
2006-08-13 08:13:33 -06:00
|
|
|
|
|
|
|
//sometimes the lp_partition ->geom .start,end and length values display random numbers
|
|
|
|
//after going out of the 'if ( lp_partition)' scope. That's why we use some variables here.
|
|
|
|
Sector new_start = -1, new_end = -1 ;
|
2004-11-21 14:49:38 -07:00
|
|
|
|
2005-12-07 15:44:40 -07:00
|
|
|
if ( open_device_and_disk( partition_old .device_path ) )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2005-12-07 04:21:27 -07:00
|
|
|
if ( partition_old .type == GParted::TYPE_EXTENDED )
|
2005-11-26 17:57:11 -07:00
|
|
|
lp_partition = ped_disk_extended_partition( lp_disk ) ;
|
2004-11-21 14:49:38 -07:00
|
|
|
else
|
2006-08-01 06:47:03 -06:00
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition_old .get_sector() ) ;
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2005-11-26 17:57:11 -07:00
|
|
|
if ( lp_partition )
|
2004-11-17 06:00:25 -07:00
|
|
|
{
|
2006-07-23 03:58:45 -06:00
|
|
|
PedGeometry *geom = ped_geometry_new( lp_device,
|
|
|
|
partition_new .sector_start,
|
|
|
|
partition_new .get_length() ) ;
|
|
|
|
constraint = ped_constraint_exact( geom ) ;
|
2006-02-25 09:30:43 -07:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
if ( constraint )
|
|
|
|
{
|
2006-02-17 14:18:07 -07:00
|
|
|
if ( ped_disk_set_partition_geom( lp_disk,
|
|
|
|
lp_partition,
|
|
|
|
constraint,
|
|
|
|
partition_new .sector_start,
|
|
|
|
partition_new .sector_end ) )
|
2006-08-13 08:13:33 -06:00
|
|
|
{
|
|
|
|
new_start = lp_partition ->geom .start ;
|
|
|
|
new_end = lp_partition ->geom .end ;
|
|
|
|
|
2006-08-20 05:47:17 -06:00
|
|
|
return_value = commit( partition_new .type == TYPE_EXTENDED ?
|
|
|
|
"" : partition_new .get_path() ) ;
|
2006-08-13 08:13:33 -06:00
|
|
|
}
|
2004-11-21 14:49:38 -07:00
|
|
|
|
2005-11-29 07:50:20 -07:00
|
|
|
ped_constraint_destroy( constraint );
|
2004-11-21 14:49:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-17 14:18:07 -07:00
|
|
|
close_device_and_disk() ;
|
2004-11-21 14:49:38 -07:00
|
|
|
}
|
2006-02-17 14:18:07 -07:00
|
|
|
|
|
|
|
if ( return_value )
|
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-07-29 02:27:28 -06:00
|
|
|
OperationDetail(
|
2006-08-13 08:13:33 -06:00
|
|
|
String::ucompose( _("new start: %1"), new_start ) + "\n" +
|
|
|
|
String::ucompose( _("new end: %1"), new_end ) + "\n" +
|
2006-07-23 12:43:15 -06:00
|
|
|
String::ucompose( _("new size: %1 (%2)"),
|
2006-08-13 08:13:33 -06:00
|
|
|
new_end - new_start + 1,
|
|
|
|
Utils::format_size( new_end - new_start + 1 ) ),
|
2006-07-29 02:27:28 -06:00
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-02-17 14:18:07 -07:00
|
|
|
}
|
|
|
|
|
2006-08-27 02:41:25 -06:00
|
|
|
operationdetail .get_last_child() .set_status( return_value ? STATUS_SUCCES : STATUS_ERROR ) ;
|
2006-08-20 05:47:17 -06:00
|
|
|
|
|
|
|
return return_value ;
|
2004-11-21 14:49:38 -07:00
|
|
|
}
|
2006-07-23 12:43:15 -06:00
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
bool GParted_Core::resize_filesystem( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail,
|
2006-06-17 14:52:25 -06:00
|
|
|
bool fill_partition )
|
|
|
|
{
|
2006-07-23 03:58:45 -06:00
|
|
|
//by default 'grow' to accomodate expand_filesystem()
|
|
|
|
GParted::FS::Support action = get_fs( partition_old .filesystem ) .grow ;
|
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
if ( ! fill_partition )
|
|
|
|
{
|
|
|
|
if ( partition_new .get_length() < partition_old .get_length() )
|
2006-07-23 03:58:45 -06:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("shrink filesystem") ) ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
action = get_fs( partition_old .filesystem ) .shrink ;
|
|
|
|
}
|
2006-06-17 14:52:25 -06:00
|
|
|
else if ( partition_new .get_length() > partition_old .get_length() )
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("grow filesystem") ) ) ;
|
2006-07-18 15:10:10 -06:00
|
|
|
else
|
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("resize filesystem") ) ) ;
|
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-07-29 02:27:28 -06:00
|
|
|
OperationDetail(
|
2006-08-31 14:19:38 -06:00
|
|
|
_("new and old filesystem have the same size. continuing anyway"),
|
2006-07-29 02:27:28 -06:00
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-07-18 15:10:10 -06:00
|
|
|
}
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
|
|
|
|
2006-07-23 03:58:45 -06:00
|
|
|
bool succes = false ;
|
|
|
|
switch ( action )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-07-23 03:58:45 -06:00
|
|
|
case GParted::FS::NONE:
|
|
|
|
break ;
|
|
|
|
case GParted::FS::GPARTED:
|
|
|
|
break ;
|
|
|
|
case GParted::FS::LIBPARTED:
|
|
|
|
succes = resize_move_filesystem_using_libparted( partition_old,
|
|
|
|
partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
break ;
|
|
|
|
case GParted::FS::EXTERNAL:
|
2006-08-13 07:31:57 -06:00
|
|
|
succes = set_proper_filesystem( partition_new .filesystem ) &&
|
2006-08-20 03:33:54 -06:00
|
|
|
p_filesystem ->resize( partition_new,
|
|
|
|
operationdetail .get_last_child(),
|
|
|
|
fill_partition ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
break ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
2006-07-23 03:58:45 -06:00
|
|
|
|
2006-08-27 02:41:25 -06:00
|
|
|
operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
return succes ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool GParted_Core::maximize_filesystem( const Partition & partition, OperationDetail & operationdetail )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("grow filesystem to fill the partition") ) ) ;
|
2006-07-19 14:54:08 -06:00
|
|
|
|
|
|
|
if ( get_fs( partition .filesystem ) .grow == GParted::FS::NONE )
|
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-07-29 02:27:28 -06:00
|
|
|
OperationDetail( _("growing is not available for this filesystem"),
|
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-07-19 14:54:08 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( STATUS_N_A ) ;
|
2006-07-19 14:54:08 -06:00
|
|
|
return true ;
|
|
|
|
}
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
return resize_filesystem( partition, partition, operationdetail, true ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
2004-11-21 14:49:38 -07:00
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
bool GParted_Core::copy( const Partition & partition_src,
|
|
|
|
Partition & partition_dest,
|
|
|
|
Sector min_size,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail )
|
2006-09-03 08:24:05 -06:00
|
|
|
{//FIXME: add a check to see if dest >= src...
|
2006-08-20 03:33:54 -06:00
|
|
|
if ( check_repair_filesystem( partition_src, operationdetail ) )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
|
|
|
bool succes = true ;
|
2006-08-01 06:16:22 -06:00
|
|
|
if ( partition_dest .status == GParted::STAT_COPY )
|
2006-08-20 03:33:54 -06:00
|
|
|
succes = create_partition( partition_dest, operationdetail, min_size ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
if ( succes && set_partition_type( partition_dest, operationdetail ) )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail(
|
2006-06-17 14:52:25 -06:00
|
|
|
String::ucompose( _("copy filesystem of %1 to %2"),
|
|
|
|
partition_src .get_path(),
|
|
|
|
partition_dest .get_path() ) ) ) ;
|
|
|
|
|
|
|
|
switch ( get_fs( partition_dest .filesystem ) .copy )
|
|
|
|
{
|
2006-09-03 08:24:05 -06:00
|
|
|
case GParted::FS::GPARTED :
|
2006-06-17 14:52:25 -06:00
|
|
|
succes = copy_filesystem( partition_src,
|
|
|
|
partition_dest,
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
break ;
|
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
case GParted::FS::LIBPARTED :
|
2006-06-17 14:52:25 -06:00
|
|
|
//FIXME: see if copying through libparted has any advantages
|
|
|
|
break ;
|
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
case GParted::FS::EXTERNAL :
|
2006-08-13 07:31:57 -06:00
|
|
|
succes = set_proper_filesystem( partition_dest .filesystem ) &&
|
2006-08-20 03:33:54 -06:00
|
|
|
p_filesystem ->copy( partition_src .get_path(),
|
2006-06-17 14:52:25 -06:00
|
|
|
partition_dest .get_path(),
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
break ;
|
|
|
|
|
|
|
|
default :
|
|
|
|
succes = false ;
|
|
|
|
break ;
|
|
|
|
}
|
|
|
|
|
2006-08-27 02:41:25 -06:00
|
|
|
operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
|
|
|
return ( succes &&
|
2006-08-20 03:33:54 -06:00
|
|
|
check_repair_filesystem( partition_dest, operationdetail ) &&
|
|
|
|
maximize_filesystem( partition_dest, operationdetail ) ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
|
2006-05-23 15:17:34 -06:00
|
|
|
bool GParted_Core::copy_filesystem( const Partition & partition_src,
|
2006-08-08 13:04:29 -06:00
|
|
|
const Partition & partition_dst,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail )
|
2006-05-27 13:51:55 -06:00
|
|
|
{
|
2006-08-31 14:19:38 -06:00
|
|
|
operationdetail .add_child( OperationDetail( _("using internal algorithm"), STATUS_NONE ) ) ;
|
2006-09-03 08:24:05 -06:00
|
|
|
|
|
|
|
operationdetail .add_child( OperationDetail( _("finding optimal blocksize"), STATUS_NONE ) ) ;
|
|
|
|
|
|
|
|
Sector optimal_blocksize = 64, N = 32768 ;
|
|
|
|
Sector offset_read = partition_src .sector_start,
|
|
|
|
offset_write = partition_dst .sector_start ;
|
|
|
|
|
|
|
|
if ( partition_dst .sector_start > partition_src .sector_start )
|
|
|
|
{
|
|
|
|
offset_read += (partition_src .get_length() -N) ;
|
|
|
|
offset_write += (partition_src .get_length() -N) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sector done = 0 ;
|
|
|
|
Glib::Timer timer ;
|
|
|
|
double smallest_time = 1000000 ;
|
|
|
|
bool succes = true ;
|
2006-08-31 14:19:38 -06:00
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
while ( succes &&
|
|
|
|
timer .elapsed() <= smallest_time &&
|
|
|
|
std::abs( done ) + N <= partition_src .get_length() &&
|
|
|
|
optimal_blocksize * 2 < N )
|
|
|
|
{
|
|
|
|
if ( done != 0 )
|
|
|
|
{
|
|
|
|
smallest_time = timer .elapsed() ;
|
|
|
|
optimal_blocksize *= 2 ;
|
|
|
|
}
|
|
|
|
|
|
|
|
timer .reset() ;
|
|
|
|
succes = copy_blocks( partition_src .device_path,
|
|
|
|
partition_dst .device_path,
|
|
|
|
offset_read + done,
|
|
|
|
offset_write + done,
|
|
|
|
N,
|
|
|
|
optimal_blocksize,
|
|
|
|
operationdetail .get_last_child() ) ;
|
|
|
|
timer.stop() ;
|
|
|
|
|
|
|
|
operationdetail .get_last_child() .get_last_child() .add_child( OperationDetail(
|
|
|
|
String::ucompose( _("%1 seconds"), timer .elapsed() ), STATUS_NONE, FONT_ITALIC ) ) ;
|
|
|
|
|
|
|
|
if ( ( partition_dst .sector_start > partition_src .sector_start ) )
|
|
|
|
done -= N ;
|
|
|
|
else
|
|
|
|
done += N ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( timer .elapsed() > smallest_time )
|
|
|
|
optimal_blocksize /= 2 ;
|
|
|
|
|
|
|
|
operationdetail .get_last_child() .add_child( OperationDetail(
|
|
|
|
String::ucompose( _("optimal blocksize is %1 sectors (%2)"), optimal_blocksize, Utils::format_size( optimal_blocksize ) ),
|
|
|
|
STATUS_NONE ) ) ;
|
|
|
|
|
|
|
|
return succes &&
|
2006-08-31 14:19:38 -06:00
|
|
|
copy_blocks( partition_src .device_path,
|
2006-09-03 08:24:05 -06:00
|
|
|
partition_dst .device_path,
|
|
|
|
partition_src .sector_start + ( partition_dst .sector_start > partition_src .sector_start ? 0 : done ),
|
|
|
|
partition_dst .sector_start + ( partition_dst .sector_start > partition_src .sector_start ? 0 : done ),
|
|
|
|
partition_src .get_length() - std::abs( done ),
|
|
|
|
optimal_blocksize,
|
|
|
|
operationdetail ) ;
|
2006-05-23 15:17:34 -06:00
|
|
|
}
|
2006-06-17 03:55:32 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool GParted_Core::check_repair_filesystem( const Partition & partition, OperationDetail & operationdetail )
|
2006-06-17 03:55:32 -06:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail(
|
2006-06-17 03:55:32 -06:00
|
|
|
String::ucompose( _("check filesystem on %1 for errors and (if possible) fix them"),
|
|
|
|
partition .get_path() ) ) ) ;
|
|
|
|
|
2006-08-13 07:31:57 -06:00
|
|
|
bool succes = false ;
|
|
|
|
switch ( get_fs( partition .filesystem ) .check )
|
2006-07-19 14:54:08 -06:00
|
|
|
{
|
2006-08-13 07:31:57 -06:00
|
|
|
case GParted::FS::NONE:
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child(
|
|
|
|
OperationDetail( _("checking is not available for this filesystem"),
|
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-07-19 14:54:08 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( STATUS_N_A ) ;
|
2006-08-13 07:31:57 -06:00
|
|
|
return true ;
|
2006-07-19 14:54:08 -06:00
|
|
|
|
2006-08-13 07:31:57 -06:00
|
|
|
break ;
|
|
|
|
case GParted::FS::GPARTED:
|
|
|
|
break ;
|
|
|
|
case GParted::FS::LIBPARTED:
|
|
|
|
break ;
|
|
|
|
case GParted::FS::EXTERNAL:
|
|
|
|
succes = set_proper_filesystem( partition .filesystem ) &&
|
2006-08-20 03:33:54 -06:00
|
|
|
p_filesystem ->check_repair( partition, operationdetail .get_last_child() ) ;
|
2006-06-17 03:55:32 -06:00
|
|
|
|
2006-08-13 07:31:57 -06:00
|
|
|
break ;
|
2006-06-17 03:55:32 -06:00
|
|
|
}
|
2006-08-13 07:31:57 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
2006-08-13 07:31:57 -06:00
|
|
|
return succes ;
|
2006-06-17 03:55:32 -06:00
|
|
|
}
|
2006-05-23 15:17:34 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool GParted_Core::set_partition_type( const Partition & partition, OperationDetail & operationdetail )
|
2005-11-24 08:59:31 -07:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail(
|
|
|
|
String::ucompose( _("set partitiontype on %1"), partition .get_path() ) ) ) ;
|
2006-08-01 07:18:22 -06:00
|
|
|
|
2005-11-29 07:50:20 -07:00
|
|
|
bool return_value = false ;
|
|
|
|
|
2005-12-07 15:44:40 -07:00
|
|
|
if ( open_device_and_disk( partition .device_path ) )
|
2005-11-24 08:59:31 -07:00
|
|
|
{
|
2006-02-17 16:20:28 -07:00
|
|
|
PedFileSystemType * fs_type =
|
2006-03-28 05:40:29 -07:00
|
|
|
ped_file_system_type_get( Utils::get_filesystem_string( partition .filesystem ) .c_str() ) ;
|
2005-11-24 08:59:31 -07:00
|
|
|
|
|
|
|
//default is Linux (83)
|
|
|
|
if ( ! fs_type )
|
|
|
|
fs_type = ped_file_system_type_get( "ext2" ) ;
|
|
|
|
|
|
|
|
if ( fs_type )
|
|
|
|
{
|
2006-08-01 06:47:03 -06:00
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
|
2005-11-24 08:59:31 -07:00
|
|
|
|
2006-08-20 05:47:17 -06:00
|
|
|
if ( lp_partition &&
|
|
|
|
ped_partition_set_system( lp_partition, fs_type ) &&
|
|
|
|
commit( partition .get_path() ) )
|
2006-08-01 07:18:22 -06:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-08-01 07:18:22 -06:00
|
|
|
OperationDetail( String::ucompose( _("new partitiontype: %1"),
|
|
|
|
lp_partition ->fs_type ->name ),
|
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
|
|
|
|
2006-08-20 05:47:17 -06:00
|
|
|
return_value = true ;
|
2006-08-01 07:18:22 -06:00
|
|
|
}
|
2005-11-24 08:59:31 -07:00
|
|
|
}
|
|
|
|
|
2006-02-17 14:18:07 -07:00
|
|
|
close_device_and_disk() ;
|
2005-11-24 08:59:31 -07:00
|
|
|
}
|
2005-11-29 07:50:20 -07:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( return_value ? STATUS_SUCCES : STATUS_ERROR ) ;
|
2005-11-29 07:50:20 -07:00
|
|
|
return return_value ;
|
|
|
|
}
|
2006-06-18 13:27:52 -06:00
|
|
|
|
2006-08-15 12:33:56 -06:00
|
|
|
void GParted_Core::set_progress_info( Sector total,
|
|
|
|
Sector done,
|
2006-08-26 08:37:06 -06:00
|
|
|
const Glib::Timer & timer,
|
2006-08-15 12:33:56 -06:00
|
|
|
OperationDetail & operationdetail )
|
2006-08-16 14:30:26 -06:00
|
|
|
{
|
|
|
|
operationdetail .fraction = done / static_cast<double>( total ) ;
|
|
|
|
|
2006-08-26 08:37:06 -06:00
|
|
|
double sec_per_frac = timer .elapsed() / operationdetail .fraction ;
|
2006-08-16 14:30:26 -06:00
|
|
|
|
|
|
|
std::time_t time_remaining = Utils::round( (1.0 - operationdetail .fraction) * sec_per_frac ) ;
|
|
|
|
|
|
|
|
operationdetail .progress_text = String::ucompose( _("%1 of %2 copied (%3 remaining)"),
|
|
|
|
Utils::format_size( done ),
|
|
|
|
Utils::format_size( total ),
|
2006-08-22 13:29:59 -06:00
|
|
|
Utils::format_time( time_remaining) ) ;
|
2006-08-15 12:33:56 -06:00
|
|
|
|
|
|
|
operationdetail .set_description( String::ucompose( _("%1 of %2 copied"), done, total ), FONT_ITALIC ) ;
|
|
|
|
}
|
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
bool GParted_Core::copy_blocks( const Glib::ustring & src_device,
|
|
|
|
const Glib::ustring & dst_device,
|
|
|
|
Sector src_start,
|
|
|
|
Sector dst_start,
|
|
|
|
Sector length,
|
|
|
|
Sector blocksize,
|
|
|
|
OperationDetail & operationdetail )
|
2006-08-26 08:37:06 -06:00
|
|
|
{
|
2006-09-03 08:24:05 -06:00
|
|
|
if ( blocksize > length )
|
|
|
|
blocksize = length ;
|
2006-08-26 08:37:06 -06:00
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
operationdetail .add_child( OperationDetail(
|
|
|
|
String::ucompose( _("copy %1 sectors using a blocksize of %2 sectors"), length, blocksize ) ) ) ;
|
2006-08-26 08:37:06 -06:00
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
Sector done = length % blocksize ;
|
2006-08-08 13:04:29 -06:00
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
if ( dst_start > src_start )
|
|
|
|
{
|
|
|
|
blocksize -= 2*blocksize ;
|
|
|
|
done -= 2*done ;
|
|
|
|
src_start += (length -1) ;
|
|
|
|
dst_start += (length -1) ;
|
|
|
|
}
|
2006-08-26 08:37:06 -06:00
|
|
|
|
2006-08-08 13:04:29 -06:00
|
|
|
bool succes = false ;
|
2006-09-03 08:24:05 -06:00
|
|
|
PedDevice *lp_device_src = ped_device_get( src_device .c_str() );
|
|
|
|
PedDevice *lp_device_dst = src_device != dst_device ? ped_device_get( dst_device .c_str() ) : lp_device_src ;
|
2006-08-08 13:04:29 -06:00
|
|
|
|
|
|
|
if ( lp_device_src && lp_device_dst && ped_device_open( lp_device_src ) && ped_device_open( lp_device_dst ) )
|
|
|
|
{
|
2006-09-03 08:24:05 -06:00
|
|
|
succes = true ;
|
2006-08-08 13:04:29 -06:00
|
|
|
ped_device_sync( lp_device_dst ) ;
|
2006-09-03 08:24:05 -06:00
|
|
|
|
|
|
|
Glib::ustring error_message ;
|
|
|
|
|
|
|
|
if ( done != 0 )
|
|
|
|
succes = copy_block( lp_device_src,
|
|
|
|
lp_device_dst,
|
|
|
|
src_start,
|
|
|
|
dst_start,
|
|
|
|
done,
|
|
|
|
error_message ) ;
|
|
|
|
|
2006-08-08 13:04:29 -06:00
|
|
|
//add an empty sub which we will constantly update in the loop
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child( OperationDetail( "", STATUS_NONE ) ) ;
|
2006-08-26 08:37:06 -06:00
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
Glib::Timer timer_progress_timeout, timer_total ;
|
|
|
|
for( ; succes && std::abs( done ) < length ; done += blocksize )
|
2006-08-08 13:04:29 -06:00
|
|
|
{
|
2006-09-03 08:24:05 -06:00
|
|
|
succes = copy_block( lp_device_src,
|
|
|
|
lp_device_dst,
|
|
|
|
src_start +done,
|
|
|
|
dst_start +done,
|
|
|
|
blocksize,
|
|
|
|
error_message ) ;
|
|
|
|
|
|
|
|
if ( timer_progress_timeout .elapsed() >= 0.5 )
|
2006-08-08 13:04:29 -06:00
|
|
|
{
|
2006-09-03 08:24:05 -06:00
|
|
|
set_progress_info( length,
|
|
|
|
std::abs( done + blocksize ),
|
|
|
|
timer_total,
|
|
|
|
operationdetail .get_last_child() .get_last_child() ) ;
|
|
|
|
|
|
|
|
timer_progress_timeout .reset() ;
|
2006-08-08 13:04:29 -06:00
|
|
|
}
|
|
|
|
}
|
2006-08-20 03:33:54 -06:00
|
|
|
|
2006-08-26 08:37:06 -06:00
|
|
|
//reset fraction to -1 to make room for a new one (or a pulsebar)
|
|
|
|
operationdetail .get_last_child() .get_last_child() .fraction = -1 ;
|
2006-08-08 13:04:29 -06:00
|
|
|
|
|
|
|
//final description
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .get_last_child() .set_description(
|
2006-09-03 08:24:05 -06:00
|
|
|
String::ucompose( _("%1 of %2 copied"), std::abs( done ), length ), FONT_ITALIC ) ;
|
|
|
|
|
2006-08-08 13:04:29 -06:00
|
|
|
if ( ! succes && ! error_message .empty() )
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-08-08 13:04:29 -06:00
|
|
|
OperationDetail( error_message, STATUS_NONE, FONT_ITALIC ) ) ;
|
|
|
|
|
|
|
|
//close and destroy the devices..
|
|
|
|
ped_device_close( lp_device_src ) ;
|
|
|
|
ped_device_destroy( lp_device_src ) ;
|
|
|
|
|
|
|
|
if ( src_device != dst_device )
|
|
|
|
{
|
|
|
|
ped_device_close( lp_device_dst ) ;
|
|
|
|
ped_device_destroy( lp_device_dst ) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
2006-08-08 13:04:29 -06:00
|
|
|
return succes ;
|
|
|
|
}
|
|
|
|
|
2006-06-18 13:27:52 -06:00
|
|
|
bool GParted_Core::copy_block( PedDevice * lp_device_src,
|
|
|
|
PedDevice * lp_device_dst,
|
|
|
|
Sector offset_src,
|
|
|
|
Sector offset_dst,
|
|
|
|
Sector blocksize,
|
|
|
|
Glib::ustring & error_message )
|
|
|
|
{
|
2006-08-31 14:19:38 -06:00
|
|
|
bool succes = false ;
|
2006-06-18 13:27:52 -06:00
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
if ( blocksize < 0 )
|
2006-06-18 13:27:52 -06:00
|
|
|
{
|
2006-09-03 08:24:05 -06:00
|
|
|
blocksize = std::abs( blocksize ) ;
|
|
|
|
offset_src -= ( blocksize -1 ) ;
|
|
|
|
offset_dst -= ( blocksize -1 ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( blocksize != 0 )
|
|
|
|
{
|
|
|
|
char * buf = static_cast<char *>( malloc( blocksize * 512 ) ) ;
|
|
|
|
if ( buf )
|
2006-08-31 14:19:38 -06:00
|
|
|
{
|
2006-09-03 08:24:05 -06:00
|
|
|
if ( ped_device_read( lp_device_src, buf, offset_src, blocksize ) )
|
|
|
|
{
|
|
|
|
if ( ped_device_write( lp_device_dst, buf, offset_dst, blocksize ) )
|
|
|
|
succes = true ;
|
|
|
|
else
|
|
|
|
error_message = String::ucompose( _("Error while writing block at sector %1"), offset_dst ) ;
|
|
|
|
}
|
2006-08-31 14:19:38 -06:00
|
|
|
else
|
2006-09-03 08:24:05 -06:00
|
|
|
error_message = String::ucompose( _("Error while reading block at sector %1"), offset_src ) ;
|
|
|
|
|
|
|
|
free( buf ) ;
|
2006-08-31 14:19:38 -06:00
|
|
|
}
|
|
|
|
else
|
2006-09-03 08:24:05 -06:00
|
|
|
error_message = Glib::strerror( errno ) ;
|
2006-06-18 13:27:52 -06:00
|
|
|
}
|
|
|
|
|
2006-08-31 14:19:38 -06:00
|
|
|
return succes ;
|
2006-06-18 13:27:52 -06:00
|
|
|
}
|
2006-09-03 08:24:05 -06:00
|
|
|
|
|
|
|
bool GParted_Core::calibrate_partition( Partition & partition, OperationDetail & operationdetail )
|
|
|
|
{
|
|
|
|
if ( partition .type == TYPE_PRIMARY || partition .type == TYPE_LOGICAL || partition .type == TYPE_EXTENDED )
|
|
|
|
{
|
|
|
|
operationdetail .add_child( OperationDetail( String::ucompose( _("calibrate %1"), partition .get_path() ) ) ) ;
|
|
|
|
|
|
|
|
bool succes = false ;
|
|
|
|
if ( open_device_and_disk( partition .device_path ) )
|
|
|
|
{
|
|
|
|
if ( partition .type == GParted::TYPE_EXTENDED )
|
|
|
|
lp_partition = ped_disk_extended_partition( lp_disk ) ;
|
|
|
|
else
|
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
|
|
|
|
|
|
|
|
if ( lp_partition )//FIXME: add check to see if lp_partition ->type matches partition .type..
|
|
|
|
{
|
|
|
|
char * lp_path = ped_partition_get_path( lp_partition ) ;
|
|
|
|
partition .add_path( lp_path, true ) ;
|
|
|
|
free( lp_path ) ;
|
|
|
|
|
|
|
|
partition .sector_start = lp_partition ->geom .start ;
|
|
|
|
partition .sector_end = lp_partition ->geom .end ;
|
|
|
|
|
|
|
|
operationdetail .get_last_child() .add_child(
|
|
|
|
OperationDetail(
|
|
|
|
String::ucompose( _("path: %1"), partition .get_path() ) + "\n" +
|
|
|
|
String::ucompose( _("start: %1"), partition .sector_start ) + "\n" +
|
|
|
|
String::ucompose( _("end: %1"), partition .sector_end ) + "\n" +
|
|
|
|
String::ucompose( _("size: %1 (%2)"),
|
|
|
|
partition .get_length(),
|
|
|
|
Utils::format_size( partition .get_length() ) ),
|
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
|
|
|
succes = true ;
|
|
|
|
}
|
|
|
|
|
|
|
|
close_device_and_disk() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
|
|
|
return succes ;
|
|
|
|
}
|
|
|
|
else //nothing to calibrate...
|
|
|
|
return true ;
|
|
|
|
}
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-07-23 03:58:45 -06:00
|
|
|
bool GParted_Core::calculate_exact_geom( const Partition & partition_old,
|
|
|
|
Partition & partition_new,
|
2006-08-27 02:41:25 -06:00
|
|
|
OperationDetail & operationdetail )
|
2006-07-23 03:58:45 -06:00
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .add_child( OperationDetail(
|
2006-07-23 03:58:45 -06:00
|
|
|
String::ucompose( _("calculate new size and position of %1"), partition_new .get_path() ) ) ) ;
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-07-29 02:27:28 -06:00
|
|
|
OperationDetail(
|
2006-07-23 03:58:45 -06:00
|
|
|
String::ucompose( _("requested start: %1"), partition_new .sector_start ) + "\n" +
|
|
|
|
String::ucompose( _("requested end: %1"), partition_new .sector_end ) + "\n" +
|
2006-07-23 12:43:15 -06:00
|
|
|
String::ucompose( _("requested size: %1 (%2)"),
|
|
|
|
partition_new .get_length(),
|
2006-07-29 02:27:28 -06:00
|
|
|
Utils::format_size( partition_new .get_length() ) ),
|
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
|
|
|
|
bool succes = false ;
|
|
|
|
if ( open_device_and_disk( partition_old .device_path ) )
|
|
|
|
{
|
|
|
|
lp_partition = NULL ;
|
|
|
|
|
|
|
|
if ( partition_old .type == GParted::TYPE_EXTENDED )
|
|
|
|
lp_partition = ped_disk_extended_partition( lp_disk ) ;
|
|
|
|
else
|
2006-08-01 06:47:03 -06:00
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition_old .get_sector() ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
|
|
|
|
if ( lp_partition )
|
|
|
|
{
|
|
|
|
PedConstraint *constraint = NULL ;
|
|
|
|
constraint = ped_constraint_any( lp_device ) ;
|
|
|
|
|
|
|
|
if ( constraint )
|
|
|
|
{
|
|
|
|
//FIXME: if we insert a weird partitionnew geom here (e.g. start > end)
|
|
|
|
//ped_disk_set_partition_geom() will still return true (althoug an lp exception is written
|
|
|
|
//to stdout.. see if this also affect create_partition and resize_move_partition
|
2006-07-30 09:13:41 -06:00
|
|
|
//sended a patch to fix this to libparted list. will probably be in 1.7.2
|
2006-07-23 03:58:45 -06:00
|
|
|
if ( ped_disk_set_partition_geom( lp_disk,
|
|
|
|
lp_partition,
|
|
|
|
constraint,
|
|
|
|
partition_new .sector_start,
|
|
|
|
partition_new .sector_end ) )
|
|
|
|
{
|
|
|
|
partition_new .sector_start = lp_partition ->geom .start ;
|
|
|
|
partition_new .sector_end = lp_partition ->geom .end ;
|
|
|
|
succes = true ;
|
|
|
|
}
|
|
|
|
|
|
|
|
ped_constraint_destroy( constraint );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close_device_and_disk() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( succes )
|
|
|
|
{
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .add_child(
|
2006-07-29 02:27:28 -06:00
|
|
|
OperationDetail(
|
2006-07-23 03:58:45 -06:00
|
|
|
String::ucompose( _("new start: %1"), partition_new .sector_start ) + "\n" +
|
|
|
|
String::ucompose( _("new end: %1"), partition_new .sector_end ) + "\n" +
|
2006-07-23 12:43:15 -06:00
|
|
|
String::ucompose( _("new size: %1 (%2)"),
|
|
|
|
partition_new .get_length(),
|
2006-07-29 02:27:28 -06:00
|
|
|
Utils::format_size( partition_new .get_length() ) ),
|
|
|
|
STATUS_NONE,
|
|
|
|
FONT_ITALIC ) ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
}
|
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
return succes ;
|
|
|
|
}
|
|
|
|
|
2006-08-13 07:31:57 -06:00
|
|
|
bool GParted_Core::set_proper_filesystem( const FILESYSTEM & filesystem )
|
2006-06-17 14:52:25 -06:00
|
|
|
{
|
|
|
|
if ( p_filesystem )
|
|
|
|
delete p_filesystem ;
|
|
|
|
|
|
|
|
switch( filesystem )
|
|
|
|
{
|
|
|
|
case FS_EXT2 : p_filesystem = new ext2() ; break ;
|
|
|
|
case FS_EXT3 : p_filesystem = new ext3() ; break ;
|
|
|
|
case FS_LINUX_SWAP : p_filesystem = new linux_swap() ; break ;
|
|
|
|
case FS_FAT16 : p_filesystem = new fat16() ; break ;
|
|
|
|
case FS_FAT32 : p_filesystem = new fat32() ; break ;
|
|
|
|
case FS_NTFS : p_filesystem = new ntfs() ; break ;
|
|
|
|
case FS_REISERFS : p_filesystem = new reiserfs() ; break ;
|
|
|
|
case FS_REISER4 : p_filesystem = new reiser4() ; break ;
|
|
|
|
case FS_XFS : p_filesystem = new xfs() ; break ;
|
|
|
|
case FS_JFS : p_filesystem = new jfs() ; break ;
|
|
|
|
case FS_HFS : p_filesystem = new hfs() ; break ;
|
|
|
|
case FS_HFSPLUS : p_filesystem = new hfsplus() ; break ;
|
|
|
|
case FS_UFS : p_filesystem = new ufs() ; break ;
|
|
|
|
|
|
|
|
default : p_filesystem = NULL ;
|
|
|
|
}
|
2006-08-13 07:31:57 -06:00
|
|
|
|
|
|
|
return p_filesystem ;
|
2006-06-17 14:52:25 -06:00
|
|
|
}
|
2005-11-29 07:50:20 -07:00
|
|
|
|
2006-04-03 12:48:53 -06:00
|
|
|
bool GParted_Core::wait_for_node( const Glib::ustring & node )
|
2005-11-29 07:50:20 -07:00
|
|
|
{
|
|
|
|
//we'll loop for 10 seconds or till 'node' appeares...
|
2006-04-03 12:48:53 -06:00
|
|
|
for( short t = 0 ; t < 50 ; t++ )
|
2005-11-29 07:50:20 -07:00
|
|
|
{
|
2006-04-03 12:48:53 -06:00
|
|
|
//FIXME: find a better way to check if a file exists
|
|
|
|
//the current way is suboptimal (at best)
|
|
|
|
if ( Glib::file_test( node, Glib::FILE_TEST_EXISTS ) )
|
2006-04-02 15:26:27 -06:00
|
|
|
{
|
2006-04-03 12:48:53 -06:00
|
|
|
//same issue
|
|
|
|
sleep( 2 ) ;
|
|
|
|
return true ;
|
2005-11-29 07:50:20 -07:00
|
|
|
}
|
2006-04-03 12:48:53 -06:00
|
|
|
else
|
|
|
|
usleep( 200000 ) ; //200 milliseconds
|
2005-11-29 07:50:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return false ;
|
2005-11-24 08:59:31 -07:00
|
|
|
}
|
|
|
|
|
2005-12-07 15:44:40 -07:00
|
|
|
bool GParted_Core::erase_filesystem_signatures( const Partition & partition )
|
|
|
|
{
|
|
|
|
bool return_value = false ;
|
|
|
|
|
|
|
|
if ( open_device_and_disk( partition .device_path ) )
|
|
|
|
{
|
2006-08-01 06:47:03 -06:00
|
|
|
lp_partition = ped_disk_get_partition_by_sector( lp_disk, partition .get_sector() ) ;
|
2005-12-07 15:44:40 -07:00
|
|
|
|
|
|
|
if ( lp_partition && ped_file_system_clobber( & lp_partition ->geom ) )
|
|
|
|
{
|
|
|
|
//filesystems not yet supported by libparted
|
|
|
|
if ( ped_device_open( lp_device ) )
|
|
|
|
{
|
|
|
|
//reiser4 stores "ReIsEr4" at sector 128
|
|
|
|
return_value = ped_geometry_write( & lp_partition ->geom, "0000000", 128, 1 ) ;
|
|
|
|
|
|
|
|
ped_device_close( lp_device ) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-02-17 14:18:07 -07:00
|
|
|
close_device_and_disk() ;
|
2005-12-07 15:44:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return return_value ;
|
|
|
|
}
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2005-11-26 17:57:11 -07:00
|
|
|
bool GParted_Core::open_device( const Glib::ustring & device_path )
|
|
|
|
{
|
2006-02-17 14:18:07 -07:00
|
|
|
lp_device = ped_device_get( device_path .c_str() );
|
2005-11-26 17:57:11 -07:00
|
|
|
|
|
|
|
return lp_device ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GParted_Core::open_device_and_disk( const Glib::ustring & device_path, bool strict )
|
|
|
|
{
|
2006-03-27 12:21:37 -07:00
|
|
|
lp_device = NULL ;
|
|
|
|
lp_disk = NULL ;
|
|
|
|
|
2005-11-26 17:57:11 -07:00
|
|
|
if ( open_device( device_path ) )
|
2006-03-27 12:21:37 -07:00
|
|
|
{
|
2005-11-26 17:57:11 -07:00
|
|
|
lp_disk = ped_disk_new( lp_device );
|
|
|
|
|
2006-03-27 12:21:37 -07:00
|
|
|
//if ! disk and writeable it's probably a HD without disklabel.
|
|
|
|
//We return true here and deal with them in GParted_Core::get_devices
|
|
|
|
if ( lp_disk || ( ! strict && ! lp_device ->read_only ) )
|
|
|
|
return true ;
|
2005-11-26 17:57:11 -07:00
|
|
|
|
2006-03-27 12:21:37 -07:00
|
|
|
close_device_and_disk() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false ;
|
2005-11-26 17:57:11 -07:00
|
|
|
}
|
|
|
|
|
2006-05-31 14:03:49 -06:00
|
|
|
void GParted_Core::close_disk()
|
|
|
|
{
|
|
|
|
if ( lp_disk )
|
|
|
|
ped_disk_destroy( lp_disk ) ;
|
|
|
|
|
|
|
|
lp_disk = NULL ;
|
|
|
|
}
|
|
|
|
|
2006-02-17 14:18:07 -07:00
|
|
|
void GParted_Core::close_device_and_disk()
|
2005-11-26 17:57:11 -07:00
|
|
|
{
|
2006-05-31 14:03:49 -06:00
|
|
|
close_disk() ;
|
|
|
|
|
2005-11-26 17:57:11 -07:00
|
|
|
if ( lp_device )
|
|
|
|
ped_device_destroy( lp_device ) ;
|
|
|
|
|
|
|
|
lp_device = NULL ;
|
|
|
|
}
|
|
|
|
|
2006-08-20 05:47:17 -06:00
|
|
|
bool GParted_Core::commit( const Glib::ustring & node )
|
2005-11-26 17:57:11 -07:00
|
|
|
{
|
|
|
|
bool return_value = ped_disk_commit_to_dev( lp_disk ) ;
|
|
|
|
|
|
|
|
ped_disk_commit_to_os( lp_disk ) ;
|
2006-08-20 05:47:17 -06:00
|
|
|
|
|
|
|
if ( ! node .empty() && return_value )
|
|
|
|
return_value = wait_for_node( node ) ;
|
|
|
|
|
2005-11-26 17:57:11 -07:00
|
|
|
return return_value ;
|
|
|
|
}
|
2006-02-25 09:30:43 -07:00
|
|
|
|
|
|
|
PedExceptionOption GParted_Core::ped_exception_handler( PedException * e )
|
|
|
|
{
|
|
|
|
std::cout << e ->message << std::endl ;
|
2006-07-30 09:13:41 -06:00
|
|
|
|
|
|
|
libparted_messages .push_back( e->message ) ;
|
|
|
|
|
2006-02-25 09:30:43 -07:00
|
|
|
return PED_EXCEPTION_UNHANDLED ;
|
|
|
|
}
|
2006-03-28 12:01:20 -07:00
|
|
|
|
|
|
|
GParted_Core::~GParted_Core()
|
|
|
|
{
|
2006-03-29 12:21:42 -07:00
|
|
|
if ( p_filesystem )
|
|
|
|
delete p_filesystem ;
|
2006-08-09 13:20:20 -06:00
|
|
|
|
|
|
|
//remove .fdi file..
|
|
|
|
remove( "/usr/share/hal/fdi/policy/gparted-disable-automount.fdi" ) ;
|
2006-03-28 12:01:20 -07:00
|
|
|
}
|
2006-03-14 14:37:47 -07:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
} //GParted
|