diff --git a/ChangeLog b/ChangeLog index d71d26b2..6d79f84e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-11-17 Bart Hakvoort + + * Rewrote a large part of gparteds internal code. Filesystemssupport is now much more separated from the rest of gparted and + adding support for other filesystems should be a piece of cake now (hope that's true :P) + It still needs a lot of love, but the foundations are laid =) + 2004-11-07 Bart Hakvoort * include/Operation.h, diff --git a/Makefile.am b/Makefile.am index 8e57dde2..714f7d9e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = include src po +SUBDIRS = include src po @INTLTOOL_DESKTOP_RULE@ diff --git a/include/Device.h b/include/Device.h index 028ba80e..7c95e98b 100644 --- a/include/Device.h +++ b/include/Device.h @@ -15,30 +15,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /****************************************************** - This class.... is a mess ;-) - It's does some kind of wrapping around libparted, but it's not very clear and it looks like shit. - The one thing i have to say in favor of it is: IT JUST WORKS :) - - When i've time i will look into it and try to sort things out a bit. - Maybe building a small decent wrapper or so... - ********************************************************/ - #ifndef DEVICE #define DEVICE -#include - #include "../include/Partition.h" -#include -#include -#include -#include -#include - -#include - namespace GParted { @@ -47,45 +28,12 @@ class Device public: Device() ; - Device( const Glib::ustring & device_path, std::vector *filesystems ); ~Device() ; - //this function creates a fresh list with al the partitions and free spaces - void Read_Disk_Layout( bool deep_scan = true ) ; - bool Delete_Partition( const Partition & partition ) ; - bool Create_Partition_With_Filesystem( Partition & new_part, PedTimer *timer) ; - bool Move_Resize_Partition( const Partition & partition_original, const Partition & partition_new, PedTimer *timer) ; - bool Set_Partition_Filesystem( const Partition & new_partition, PedTimer * timer); - bool Copy_Partition( Device *source_device, const Partition & source_partition, PedTimer * timer ) ; - int Create_Empty_Partition( const Partition & new_partition, PedConstraint * constraint = NULL ) ; - bool Commit() ; - - PedPartition * Get_c_partition( int part_num ); - - std::vector Get_Partitions() ; - Sector Get_Length() ; - long Get_Heads() ; - long Get_Sectors() ; - long Get_Cylinders() ; - Glib::ustring Get_Model() ; - Glib::ustring Get_Path() ; - Glib::ustring Get_RealPath() ; - Glib::ustring Get_DiskType() ; - bool Get_any_busy() ; - int Get_Max_Amount_Of_Primary_Partitions() ; + + bool Get_any_busy( ) ; int Get_Highest_Logical_Busy( ) ; - -private: - //make a try to get the amount of used sectors on a filesystem ( see comments in implementation ) - Sector Get_Used_Sectors( PedPartition *c_partition, const Glib::ustring & sym_path ); - - Glib::ustring Get_Flags( PedPartition *c_partition ) ; - bool open_device_and_disk() ; - void close_device_and_disk() ; - bool Resize_Extended( const Partition & partition, PedTimer *timer) ; - std::vector device_partitions ; - std::vector * FILESYSTEMS ; Sector length; long heads ; long sectors ; @@ -94,17 +42,13 @@ private: Glib::ustring path; Glib::ustring realpath; Glib::ustring disktype; - - //private variables - PedDevice *device ; - PedDisk *disk ; - PedPartition *c_partition ; + int max_prims ; - std::vector flags; - Glib::ustring temp, error ; //error may contain an errormessage for an specific partition ( see Get_Used_Sectors() ) - Partition partition_temp ; - }; +private: + + +}; - } //GParted +} //GParted #endif //DEVICE diff --git a/include/Dialog_Base_Partition.h b/include/Dialog_Base_Partition.h index e01b487b..5661fa5f 100644 --- a/include/Dialog_Base_Partition.h +++ b/include/Dialog_Base_Partition.h @@ -77,6 +77,7 @@ protected: void on_signal_resize( int, int, Frame_Resizer_Base::ArrowType ); void on_spinbutton_value_changed( SPINBUTTON ) ; + std::vector FILESYSTEMS ; bool fixed_start, GRIP ; double before_value ; int x_start, x_end ; diff --git a/include/Dialog_Partition_Resize_Move.h b/include/Dialog_Partition_Resize_Move.h index 637809c9..7a065327 100644 --- a/include/Dialog_Partition_Resize_Move.h +++ b/include/Dialog_Partition_Resize_Move.h @@ -26,7 +26,7 @@ namespace GParted class Dialog_Partition_Resize_Move : public Dialog_Base_Partition { public: - Dialog_Partition_Resize_Move( ) ; + Dialog_Partition_Resize_Move( std::vector FILESYSTEMS ) ; void Set_Data( const Partition & selected_partition, const std::vector & partitions ) ; private: diff --git a/include/Dialog_Progress.h b/include/Dialog_Progress.h index 2f32fbf8..0b2d66e0 100644 --- a/include/Dialog_Progress.h +++ b/include/Dialog_Progress.h @@ -25,6 +25,10 @@ #include #include #include +#include +#include +#include +#include namespace GParted { @@ -32,22 +36,30 @@ namespace GParted class Dialog_Progress : public Gtk::Dialog { public: - Dialog_Progress( int, const Glib::ustring & ); + Dialog_Progress( int count_operations, Glib::RefPtr textbuffer ); ~Dialog_Progress( ); - void Set_Next_Operation( ); - void Set_Progress_Current_Operation( ); - + void Set_Operation( ); + Glib::ustring current_operation; - float fraction_current; - int time_left ; - + int TIME_LEFT ; + private: + bool Show_Progress( ) ; + bool Pulse( ) { progressbar_current .pulse( ) ; return true ; } + void tglbtn_details_toggled( ) ; + Gtk::Label label_current ; Gtk::ProgressBar progressbar_all, progressbar_current ; + Gtk::ToggleButton tglbtn_details ; + Gtk::TextView textview_details ; + Gtk::ScrolledWindow scrolledwindow ; - double fraction; + void signal_textbuffer_insert( const Gtk::TextBuffer::iterator & iter, const Glib::ustring & text, int ) ; + + double fraction, fraction_current; int count_operations, current_operation_number; + sigc::connection conn ; }; }//GParted diff --git a/include/FileSystem.h b/include/FileSystem.h new file mode 100644 index 00000000..069fd711 --- /dev/null +++ b/include/FileSystem.h @@ -0,0 +1,106 @@ +/* Copyright (C) 2004 Bart + * + * 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. + */ + + +#ifndef FILESYSTEM +#define FILESYSTEM + +#include "../include/Partition.h" + +#include + +#include + +//Some functions used by both (sub)Filesystems and GParted_Core------------------------------------------------- +inline bool open_device( const Glib::ustring & device_path, PedDevice *& device ) +{ + device = ped_device_get( device_path .c_str( ) ); + + return device ; +} + +inline bool open_device_and_disk( const Glib::ustring & device_path, PedDevice *& device, PedDisk *& disk ) +{ + + if ( open_device( device_path, device ) ) + disk = ped_disk_new( device ); + + if ( ! disk ) + { + ped_device_destroy( device ) ; + device = NULL ; + + return false; + } + + return true ; +} + +inline void close_device_and_disk( PedDevice *& device, PedDisk *& disk ) +{ + if ( device ) + ped_device_destroy( device ) ; + + if ( disk ) + ped_disk_destroy( disk ) ; + + device = NULL ; + disk = NULL ; +} + +inline bool Commit( PedDisk *& disk ) +{ + bool return_value = ped_disk_commit_to_dev( disk ) ; + + ped_disk_commit_to_os( disk ) ; + + return return_value ; +} +//--------------------------------------------------------------------------------------------------------------- + +namespace GParted +{ + +class FileSystem +{ +public: + virtual ~FileSystem( ) { } + + virtual FS get_filesystem_support( ) = 0 ; + virtual bool Create( const Glib::ustring device_path, const Partition & new_partition ) = 0 ; + virtual bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) = 0 ; + virtual bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) = 0 ; + virtual int get_estimated_time( long MB_to_Consider ) = 0 ; + + Glib::RefPtr textbuffer ; + +protected: + bool Execute_Command( Glib::ustring command ) ; + + PedDevice *device ; + PedDisk *disk ; + +private: + void Update_Textview( ) ; + + Glib::ustring output ; + +}; + +} //GParted + +#endif //FILESYSTEM diff --git a/include/GParted_Core.h b/include/GParted_Core.h new file mode 100644 index 00000000..5eab3ff4 --- /dev/null +++ b/include/GParted_Core.h @@ -0,0 +1,81 @@ +/* Copyright (C) 2004 Bart + * + * 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. + */ + +#ifndef GPARTED_CORE +#define GPARTED_CORE + +#include "../include/Operation.h" +#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 +#include + +namespace GParted +{ + +class GParted_Core +{ +public: + GParted_Core( ) ; + void find_supported_filesystems( ) ; + void get_devices( std::vector & devices, bool deep_scan ) ; + void get_partitions( std::vector & partitions, const Glib::ustring & device_path, bool deep_scan = true ) ; + int get_estimated_time( Operation & operation ) ; + + void Apply_Operation_To_Disk( Operation & operation ); + + bool Create( const Glib::ustring & device_path, Partition & new_partition ) ; + bool Convert_FS( const Glib::ustring & device_path, const Partition & partition ) ; + bool Delete( const Glib::ustring & device_path, const Partition & partition ) ; + bool Resize( const Glib::ustring & device_path, const Partition & partition_old, const Partition & partition_new ) ; + bool Copy( const Glib::ustring & dest_device_path, const Glib::ustring & src_part_path, Partition & partition_dest ) ; + + std::vector get_fs( ) ; + Glib::RefPtr get_textbuffer( ) ; + +private: + Glib::ustring get_sym_path( const Glib::ustring & real_path ) ; + Sector Get_Used_Sectors( PedPartition *c_partition, const Glib::ustring & sym_path ); + Glib::ustring Get_Flags( PedPartition *c_partition ) ; + int Create_Empty_Partition( const Glib::ustring & device_path, Partition & new_partition ) ; + bool Resize_Extended( const Glib::ustring & device_path, const Partition & extended ) ; + + void Show_Error( Glib::ustring message ) ; + void set_proper_filesystem( const Glib::ustring & filesystem ) ; + + Glib::RefPtr textbuffer; + + std::vector FILESYSTEMS ; + FileSystem * p_filesystem ; + std::vector flags; + PedDevice *device ; + PedDisk *disk ; + PedPartition *c_partition ; + Glib::ustring temp ; +}; + +} //GParted + + +#endif //GPARTED_CORE diff --git a/include/Operation.h b/include/Operation.h index aa82d68d..ebfa3ec9 100644 --- a/include/Operation.h +++ b/include/Operation.h @@ -39,21 +39,23 @@ class Operation { public: - Operation( Device *device, Device *source_device, const Partition &, const Partition &,OperationType ); + Operation( const Glib::ustring device_path, Sector device_length, const Partition &, const Partition &, OperationType ); //this one can be a little confusing, it *DOES NOT* change any visual representation. It only applies the operation to the list with partitions. //this new list can be used to change the visual representation. For real writing to disk, see Apply_To_Disk() void Apply_Operation_To_Visual( std::vector & partitions ); - void Apply_To_Disk( PedTimer * timer ); - //public variables - Device *device, *source_device; //source_device is only used in copy operations - Glib::ustring device_path, source_device_path ; + Glib::ustring device_path ; + Sector device_length ; OperationType operationtype; + Partition partition_original; //the original situation Partition partition_new; //the new situation ( can be an whole new partition or simply the old one with a new size or.... ) Glib::ustring str_operation ; + Glib::ustring copied_partition_path ; //for copy operation.. + + private: void Insert_Unallocated( std::vector & partitions, Sector start, Sector end ); int Get_Index_Original( std::vector & partitions ) ; @@ -63,10 +65,7 @@ private: void Apply_Resize_Move_To_Visual( std::vector & partitions ); void Apply_Resize_Move_Extended_To_Visual( std::vector & partitions ); - Glib::ustring Get_String(); //only used during in c'tor - void Show_Error( Glib::ustring message ) ; - - Partition partition_original; //the original situation + Glib::ustring Get_String( ); //only used in c'tor }; } //GParted diff --git a/include/Utils.h b/include/Utils.h index 5a04a2c9..c72786ed 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -43,9 +43,14 @@ typedef long long Sector; struct FS { Glib::ustring filesystem ; - bool supported ; //open/resize/copy - bool create ; //create (duh =) ) + bool create ; + bool resize ; //only endpoint + bool move ; //startpoint and endpoint + bool check ; + + FS( ) {create = resize = move = check = false ;} }; + //globally used convenience functions inline long Sector_To_MB( Sector sectors ) @@ -91,13 +96,15 @@ inline Glib::ustring num_to_str( Sector number ) return os .str() ; } -inline bool Supported( const Glib::ustring & filesystem, std::vector *FILESYSTEMS ) +inline FS Get_FS( const Glib::ustring & filesystem, const std::vector & FILESYSTEMS ) { - for (unsigned int t=0 ; t < FILESYSTEMS ->size() ; t++ ) - if ( (*FILESYSTEMS)[ t ] .filesystem == filesystem && (*FILESYSTEMS)[ t ] .supported ) - return true ; + unsigned int t = 0 ; - return false ; + for ( t = 0 ; t < FILESYSTEMS .size( ) ; t++ ) + if ( FILESYSTEMS[ t ] .filesystem == filesystem ) + break ; + + return FILESYSTEMS[ t ] ; } inline Glib::ustring Get_Color( const Glib::ustring & filesystem ) diff --git a/include/Win_GParted.h b/include/Win_GParted.h index e0cf249c..27cc3522 100644 --- a/include/Win_GParted.h +++ b/include/Win_GParted.h @@ -29,6 +29,7 @@ #include "../include/Dialog_Partition_Resize_Move.h" #include "../include/Dialog_About.h" #include "../include/Dialog_Partition_Copy.h" +#include "../include/GParted_Core.h" #include #include @@ -39,7 +40,6 @@ #include #include #include -#include #include #include //should be included by gtkmm headers. but decided to include it anyway after getting some bugreports.. @@ -61,7 +61,6 @@ private: void init_operationslist() ; void init_hpaned_main() ; - void Find_Supported_Filesystems() ; void Find_Devices( bool deep_scan = true ) ; void Refresh_OptionMenu( ) ; void Show_Pulsebar( ) ; @@ -123,9 +122,9 @@ private: void apply_operations_thread(); //private variables - unsigned int current_device, source_device; //source_device is used to store the device the copied_partition is from.... + unsigned int current_device ; Partition selected_partition, copied_partition; - std::vector devices; + std::vector devices; std::vector operations; //gui stuff @@ -176,11 +175,10 @@ private: unsigned short new_count;//new_count keeps track of the new created partitions Glib::ustring str_temp ; //mostly used for constructing dialogmessages - + GParted_Core gparted_core ; GParted::Device *temp_device ; std::vector device_info ; - std::vector FILESYSTEMS ; - + //stuff for progress overview and pulsebar Dialog_Progress *dialog_progress; Glib::Thread *thread ; diff --git a/include/ext2.h b/include/ext2.h new file mode 100644 index 00000000..e630213d --- /dev/null +++ b/include/ext2.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2004 Bart + * + * 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. + */ + + +#ifndef EXT2 +#define EXT2 + +#include "../include/FileSystem.h" + +namespace GParted +{ + +class ext2 : public FileSystem +{ +public: + FS get_filesystem_support( ) ; + bool Create( const Glib::ustring device_path, const Partition & new_partition ) ; + bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ; + bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ; + int get_estimated_time( long MB_to_Consider ) ; +}; + +} //GParted + +#endif //EXT2 diff --git a/include/ext3.h b/include/ext3.h new file mode 100644 index 00000000..ba3c1aec --- /dev/null +++ b/include/ext3.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2004 Bart + * + * 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. + */ + + +#ifndef EXT3 +#define EXT3 + +#include "../include/FileSystem.h" + +namespace GParted +{ + +class ext3 : public FileSystem +{ +public: + FS get_filesystem_support( ) ; + bool Create( const Glib::ustring device_path, const Partition & new_partition ) ; + bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ; + bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ; + int get_estimated_time( long MB_to_Consider ) ; +}; + + +} //GParted + +#endif //EXT3 diff --git a/include/fat16.h b/include/fat16.h new file mode 100644 index 00000000..eb2d45f3 --- /dev/null +++ b/include/fat16.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2004 Bart + * + * 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. + */ + + +#ifndef FAT16 +#define FAT16 + +#include "../include/FileSystem.h" + +namespace GParted +{ + +class fat16 : public FileSystem +{ +public: + FS get_filesystem_support( ) ; + bool Create( const Glib::ustring device_path, const Partition & new_partition ) ; + bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ; + bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ; + int get_estimated_time( long MB_to_Consider ) ; + +}; + +} //GParted + +#endif //FAT16 diff --git a/include/fat32.h b/include/fat32.h new file mode 100644 index 00000000..5e5ff400 --- /dev/null +++ b/include/fat32.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2004 Bart + * + * 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. + */ + + +#ifndef FAT32 +#define FAT32 + +#include "../include/FileSystem.h" + +namespace GParted +{ + +class fat32 : public FileSystem +{ +public: + FS get_filesystem_support( ); + bool Create( const Glib::ustring device_path, const Partition & new_partition ) ; + bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ; + bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ; + int get_estimated_time( long MB_to_Consider ) ; +}; + +} //GParted + +#endif //FAT32 diff --git a/include/linux_swap.h b/include/linux_swap.h new file mode 100644 index 00000000..a54f0200 --- /dev/null +++ b/include/linux_swap.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2004 Bart + * + * 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. + */ + + +#ifndef LINUX_SWAP +#define LINUX_SWAP + +#include "../include/FileSystem.h" + +namespace GParted +{ + +class linux_swap : public FileSystem +{ +public: + FS get_filesystem_support( ) ; + bool Create( const Glib::ustring device_path, const Partition & new_partition ) ; + bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ; + bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ; + int get_estimated_time( long MB_to_Consider ) ; +}; + +} //GParted + +#endif //LINUX_SWAP diff --git a/include/reiserfs.h b/include/reiserfs.h new file mode 100644 index 00000000..28cd0384 --- /dev/null +++ b/include/reiserfs.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2004 Bart + * + * 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. + */ + + +#ifndef REISERFS +#define REISERFS + +#include "../include/FileSystem.h" + +#include + +namespace GParted +{ + +class reiserfs : public FileSystem +{ +public: + FS get_filesystem_support( ) ; + bool Create( const Glib::ustring device_path, const Partition & new_partition ) ; + bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ; + bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ; + int get_estimated_time( long MB_to_Consider ) ; +}; + +} //GParted + +#endif //REISERFS diff --git a/src/Device.cc b/src/Device.cc index f7d86ed0..c951c015 100644 --- a/src/Device.cc +++ b/src/Device.cc @@ -20,441 +20,11 @@ namespace GParted { -/* - * This is ridiculous!, if i use this one as a member function realpath starts complaining and won't compile :-S - */ -Glib::ustring get_sym_path( const Glib::ustring & real_path ) -{ - int major,minor,size; - char temp[4096], device_name[4096],short_path[4096] ; - - FILE* proc_part_file = fopen ("/proc/partitions", "r"); - if (!proc_part_file) - return real_path; - - //skip first 2 useless rules of /proc/partitions - fgets (temp, 256, proc_part_file);fgets (temp, 256, proc_part_file); - - while (fgets (temp, 4096, proc_part_file) && sscanf (temp, "%d %d %d %255s", &major, &minor, &size, device_name) == 4) - { - strcpy(short_path, "/dev/"); strcat( short_path, device_name ); - realpath( short_path, device_name ); - - if ( real_path == device_name ) { - fclose (proc_part_file); - return (Glib::ustring(short_path)); - } - - } - - //paranoia modus :) - fclose (proc_part_file); - return real_path; -} - -//AFAIK it's not possible to use a C++ memberfunction as a callback for a C libary function (if you know otherwise, PLEASE contact me) -Glib::ustring error_message; -PedExceptionOption PedException_Handler (PedException* ex) -{ - error_message = Glib::locale_to_utf8( ex ->message ) ; - - std::cout << error_message << "\n---------------------------\n" ; - - return PED_EXCEPTION_UNHANDLED ; -} - -//--------------Device---------------------------------------------- -Device::Device() +Device::Device( ) { } - -Device::Device( const Glib::ustring & device_path, std::vector *filesystems ) -{ - ped_exception_set_handler( PedException_Handler ) ; - - this ->FILESYSTEMS = filesystems ; - - this ->realpath = device_path ; //this one is used by open_device_and_disk - - this ->length = 0;//lazy check.. if something goes wrong while reading the device, length will stay zero and i will know it ( see Win_GParted::Find_Devices ) - - if ( ! open_device_and_disk() ) - return ; - - this ->model = device ->model ; - this ->path = get_sym_path( device ->path ) ; - this ->disktype = disk ->type ->name ; - this ->heads = device ->bios_geom.heads ; - this ->sectors = device ->bios_geom.sectors ; - this ->cylinders= device ->bios_geom.cylinders ; - this ->length = heads * sectors * cylinders ; - - //get valid flags for this device - for ( PedPartitionFlag flag = ped_partition_flag_next ( (PedPartitionFlag) 0 ) ; flag ; flag = ped_partition_flag_next ( flag ) ) - flags .push_back( flag ) ; - -} -void Device::Read_Disk_Layout( bool deep_scan ) -{ - Glib::ustring part_path ; - int EXT_INDEX = -1 ; - - //clear partitions - this ->device_partitions .clear( ) ; - - c_partition = ped_disk_next_partition( disk, NULL ) ; - while ( c_partition ) - { - partition_temp .Reset( ) ; - part_path = this ->path + num_to_str( c_partition ->num ) ; - - switch ( c_partition ->type ) - { - case PED_PARTITION_NORMAL: - case PED_PARTITION_LOGICAL: - if ( c_partition ->fs_type ) - temp = c_partition ->fs_type ->name ; - else - { - temp = "unknown" ; - this ->error = _( "Unable to detect filesystem! Possible reasons are:" ) ; - this ->error += "\n-"; - this ->error += _( "The filesystem is damaged" ) ; - this ->error += "\n-" ; - this ->error += _( "The filesystem is unknown to libparted" ) ; - this ->error += "\n-"; - this ->error += _( "There is no filesystem available (unformatted)" ) ; - - } - partition_temp.Set( part_path, - c_partition ->num, - c_partition ->type == 0 ? GParted::PRIMARY : GParted::LOGICAL , - temp, c_partition ->geom .start, - c_partition ->geom .end, - c_partition ->type, - ped_partition_is_busy( c_partition ) ); - - if ( deep_scan ) - partition_temp .Set_Used( Get_Used_Sectors( c_partition, part_path ) ) ; - - partition_temp .flags = Get_Flags( c_partition ) ; - partition_temp .error = this ->error ;//most likely useless, but paranoia me leaves it here.. =) - - break ; - - - case PED_PARTITION_EXTENDED: - partition_temp.Set( part_path , - c_partition ->num , - GParted::EXTENDED , - "extended" , - c_partition ->geom .start , - c_partition ->geom .end , - false , - ped_partition_is_busy( c_partition ) ); - - partition_temp .flags = Get_Flags( c_partition ) ; - EXT_INDEX = device_partitions .size ( ) ; - break ; - - - case PED_PARTITION_FREESPACE: - case 5: //freespace inside extended (there's no enumvalue for that..) - partition_temp.Set_Unallocated( c_partition ->geom .start, c_partition ->geom .end, c_partition ->type == 4 ? false : true ); - break ; - - case PED_PARTITION_METADATA: - if ( device_partitions .size( ) && device_partitions .back( ) .type == GParted::UNALLOCATED ) - device_partitions .back( ) .sector_end = c_partition ->geom .end ; - - break ; - - case 9: //metadata inside extended (there's no enumvalue for that..) - if ( device_partitions[ EXT_INDEX ] .logicals .size( ) && device_partitions[ EXT_INDEX ] .logicals .back( ) .type == GParted::UNALLOCATED ) - device_partitions[ EXT_INDEX ] .logicals .back( ) .sector_end = c_partition ->geom .end ; - - break ; - - default: break; - } - - if ( partition_temp .Get_Length_MB( ) >= 1 ) // check for unallocated < 1MB, and metadatasituations (see PED_PARTITION_METADATA and 9 ) - { - if ( ! partition_temp .inside_extended ) - device_partitions.push_back( partition_temp ); - else - device_partitions[ EXT_INDEX ] .logicals .push_back( partition_temp ) ; - } - - //reset stuff.. - this ->error = error_message = "" ; - - //next partition (if any) - c_partition = ped_disk_next_partition ( disk, c_partition ) ; - } - -} - -bool Device::Delete_Partition( const Partition & partition ) -{ - if ( partition .type == GParted::EXTENDED ) - c_partition = ped_disk_extended_partition( disk ) ; - else - c_partition = ped_disk_get_partition_by_sector( disk, (partition .sector_end + partition .sector_start) / 2 ) ; - - if ( ! ped_disk_delete_partition( disk, c_partition ) ) - return false; - - return Commit() ; -} - -int Device::Create_Empty_Partition( const Partition & new_partition, PedConstraint * constraint ) -{ - PedPartitionType type; - PedPartition *c_part = NULL ; - - //create new partition - switch ( new_partition .type ) - { - case 0 : type = PED_PARTITION_NORMAL; break; - case 1 : type = PED_PARTITION_LOGICAL; break; - case 2 : type = PED_PARTITION_EXTENDED; break; - default : type = PED_PARTITION_FREESPACE; break ; //will never happen ;) - } - c_part = ped_partition_new ( disk, type, NULL, new_partition .sector_start, new_partition .sector_end ) ; - - //create constraint - if ( ! constraint ) - constraint = ped_constraint_any ( device); - - //and add the whole thingy to disk.. - if ( ! constraint || ! ped_disk_add_partition (disk, c_part, constraint) || ! Commit() ) - return 0 ; - - ped_constraint_destroy (constraint); - return c_part ->num; -} - -bool Device::Create_Partition_With_Filesystem( Partition & new_part, PedTimer * timer) -{ - //no need to create a filesystem on an extended partition - if ( new_part .type == GParted::EXTENDED ) - return Create_Empty_Partition( new_part ) ; - else - { - new_part .partition_number = Create_Empty_Partition( new_part ) ; - return Set_Partition_Filesystem( new_part, timer ) ; - } - -} - -bool Device::Move_Resize_Partition( const Partition & partition_original, const Partition & partition_new , PedTimer *timer ) -{ - PedPartition *c_part = NULL ; - PedFileSystem *fs = NULL ; - PedConstraint *constraint = NULL ; - - //since resizing extended is a bit different i handle it elsewhere.. - if ( partition_new.type == GParted::EXTENDED ) - return Resize_Extended( partition_new, timer ) ; - - //normal partitions.... - c_part = ped_disk_get_partition_by_sector( disk, (partition_original .sector_end + partition_original .sector_start) / 2 ) ; - if ( ! c_part ) - return false; - - fs = ped_file_system_open (& c_part->geom ); - if ( ! fs ) - return false ; - - constraint = ped_file_system_get_resize_constraint (fs); - if ( ! constraint ) - { - ped_file_system_close (fs); - return false; - } - - if ( ! ped_disk_set_partition_geom (disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) ) - { - ped_constraint_destroy (constraint); - ped_file_system_close (fs); - return false ; - } - - if ( ! ped_file_system_resize (fs, & c_part->geom, timer) ) - { - ped_constraint_destroy (constraint); - ped_file_system_close (fs); - return false ; - } - - ped_constraint_destroy (constraint); - ped_file_system_close (fs); - - return Commit() ; -} - -bool Device::Set_Partition_Filesystem( const Partition & new_partition, PedTimer * timer) -{ - if ( new_partition .partition_number <= 0 ) - return false ; - - PedPartition *c_part = NULL ; - PedFileSystemType *fs_type = NULL ; - PedFileSystem *fs = NULL ; - - c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ; - if ( ! c_part ) - return false; - - fs_type = ped_file_system_type_get ( new_partition .filesystem .c_str() ) ; - if ( ! fs_type ) - return false; - - fs = ped_file_system_create ( & c_part ->geom, fs_type, timer); - if ( ! fs ) - return false; - - ped_file_system_close (fs); - - if ( ! ped_partition_set_system (c_part, fs_type ) ) - return false; - - return Commit() ; -} - -bool Device::Copy_Partition( Device *source_device, const Partition & source_partition, PedTimer * timer) -{ - PedPartition *c_part_src = NULL; - PedFileSystem *src_fs = NULL; - PedPartition *c_part = NULL; - PedFileSystem *dst_fs = NULL; - PedFileSystemType *dst_fs_type = NULL; - - //prepare source for reading - if ( source_device ->Get_Path() == this ->path ) - c_part_src = ped_disk_get_partition( disk, source_partition .partition_number ) ; - else - c_part_src = source_device ->Get_c_partition( source_partition .partition_number ) ; - - if ( ! c_part_src ) - return false; - - src_fs = ped_file_system_open ( &c_part_src ->geom ); - if ( ! src_fs ) - return false ; - - //create new empty partition - c_part = ped_disk_get_partition( disk,Create_Empty_Partition( source_partition, ped_file_system_get_copy_constraint ( src_fs, device ) ) ) ; - if ( ! c_part ) - return false ; - - //and do the copy - dst_fs = ped_file_system_copy (src_fs, &c_part ->geom, timer); - if ( ! dst_fs ) - { - ped_file_system_close (src_fs); - return false ; - } - - dst_fs_type = dst_fs ->type; // may be different to src_fs->type - - ped_file_system_close (src_fs); - ped_file_system_close (dst_fs); - - if ( !ped_partition_set_system (c_part, dst_fs_type) ) - return false ; - - return Commit() ; -} - -bool Device::Resize_Extended( const Partition & partition , PedTimer *timer) -{ - PedPartition *c_part = NULL ; - PedConstraint *constraint = NULL ; - - c_part = ped_disk_extended_partition( disk ) ; - if ( ! c_part ) - return false; - - constraint = ped_constraint_any ( device ); - if ( ! constraint ) - return false; - - if ( ! ped_disk_set_partition_geom ( disk, c_part, constraint, partition.sector_start, partition.sector_end ) ) - { - ped_constraint_destroy (constraint); - return false ; - } - - ped_partition_set_system ( c_part, NULL); - - ped_constraint_destroy (constraint); - - return Commit() ; -} - -bool Device::Commit() -{ - bool return_value = ped_disk_commit_to_dev( disk ) ; - - ped_disk_commit_to_os( disk ) ; - - return return_value ; -} - -PedPartition * Device::Get_c_partition( int part_num ) -{ - return ped_disk_get_partition( disk, part_num ) ; -} - -std::vector Device::Get_Partitions() -{ - return device_partitions; -} - -Sector Device::Get_Length() -{ - return length ; -} - -long Device::Get_Heads() -{ - return heads ; -} - -long Device::Get_Sectors() -{ - return sectors ; -} - -long Device:: Get_Cylinders() -{ - return cylinders ; -} - -Glib::ustring Device::Get_Model() -{ - return model ; -} - -Glib::ustring Device::Get_Path() -{ - return path ; -} - -Glib::ustring Device::Get_RealPath() -{ - return realpath ; -} - -Glib::ustring Device::Get_DiskType() -{ - return disktype ; -} - -bool Device::Get_any_busy() +bool Device::Get_any_busy( ) { for ( unsigned int t=0;t ) - * - if this fails the filesystem on the partition is ( more or less ) unknown to the operating system and therefore the unused sectors cannot be calcualted - * - as soon as i have my internetconnection back i should ask people with more experience on this stuff for advice ! - */ - - //check if there is a (known) filesystem - if ( ! c_partition ->fs_type ) - return -1; - - //used sectors are not relevant for swapspace - if ( (Glib::ustring) c_partition ->fs_type ->name == "linux-swap" ) - return -1; - - //METHOD #1 - //the getused method doesn't work on mounted partitions and for some filesystems ( i *guess* this is called check by andrew ) - if ( ! ped_partition_is_busy( c_partition ) && Supported( c_partition ->fs_type ->name, FILESYSTEMS ) ) - { - PedFileSystem *fs = NULL; - PedConstraint *constraint = NULL; - - fs = ped_file_system_open( & c_partition ->geom ); - - if ( fs ) - { - constraint = ped_file_system_get_resize_constraint (fs); - ped_file_system_close (fs); - if ( constraint && constraint->min_size != -1 ) - return constraint->min_size ; - } - else - this ->error = error_message ; - - } - - //METHOD #2 - //this ony works for mounted ( and therefore known to the OS ) filesystems. My method is quite crude, keep in mind it's only temporary ;-) - if ( ped_partition_is_busy( c_partition ) ) - { - Glib::ustring buf; - system( ("df -k --sync " + sym_path + " | grep " + sym_path + " > /tmp/.tmp_gparted").c_str() ); - std::ifstream file_input( "/tmp/.tmp_gparted" ); - - file_input >> buf; //skip first value - file_input >> buf; - if ( buf != "0" && ! buf.empty() ) - { - file_input >> buf; - file_input.close(); system( "rm -f /tmp/.tmp_gparted" ); - return atoi( buf.c_str() ) * 1024/512 ; - } - file_input.close(); system( "rm -f /tmp/.tmp_gparted" ); - } - - - return -1 ; //all methods were unsuccesfull - -} - -Glib::ustring Device::Get_Flags( PedPartition *c_partition ) -{ - temp = ""; - - for ( unsigned short t = 0; t < flags.size() ; t++ ) - if ( ped_partition_get_flag ( c_partition, flags[ t ] ) ) - temp += (Glib::ustring) ped_partition_flag_get_name ( flags[ t ] ) + " "; - - return temp ; -} - -bool Device::open_device_and_disk() -{ - device = ped_device_get( this->realpath .c_str() ); - if ( device ) - disk = ped_disk_new( device ); - - if ( ! device || ! disk ) - { - if ( device ) - { ped_device_destroy( device ) ; device = NULL ; } - - return false; - } - - return true ; -} - -void Device::close_device_and_disk() -{ - if ( device ) - { - ped_device_destroy( device ) ; - device = NULL ; - } - - if ( disk ) - { - ped_disk_destroy( disk ) ; - disk = NULL ; - } -} - Device::~Device() { - close_device_and_disk() ; } diff --git a/src/Dialog_About.cc b/src/Dialog_About.cc index b9c82085..54da34f3 100644 --- a/src/Dialog_About.cc +++ b/src/Dialog_About.cc @@ -37,7 +37,7 @@ Dialog_About::Dialog_About() button_credits.add_pixlabel( "/usr/share/icons/hicolor/16x16/stock/generic/stock_about.png", "Credits", 0, 0.5 ) ; button_credits.signal_clicked() .connect( sigc::mem_fun( this, &Dialog_About::Show_Credits ) ) ; - this ->get_action_area() ->set_layout( Gtk::BUTTONBOX_EDGE ) ; + this ->get_action_area() ->set_layout( Gtk::BUTTONBOX_EDGE ) ; this ->get_action_area() ->pack_start( button_credits ) ; this ->add_button( Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE ); diff --git a/src/Dialog_Base_Partition.cc b/src/Dialog_Base_Partition.cc index 9bd69658..bc7ebde4 100644 --- a/src/Dialog_Base_Partition.cc +++ b/src/Dialog_Base_Partition.cc @@ -145,12 +145,9 @@ void Dialog_Base_Partition::Set_Confirm_Button( CONFIRMBUTTON button_type ) { switch( button_type ) { - case NEW : this->add_button( Gtk::Stock::ADD,Gtk::RESPONSE_OK ); + case NEW : this->add_button( Gtk::Stock::ADD, Gtk::RESPONSE_OK ); break ; - case RESIZE_MOVE: if ( selected_partition.filesystem == "ext2" || selected_partition.filesystem == "ext3" || selected_partition.filesystem == "reiserfs") - str_temp = _("Resize") ; - else - str_temp = _("Resize/Move") ; + case RESIZE_MOVE: str_temp = fixed_start ? _("Resize") : _("Resize/Move") ; image_temp = manage( new Gtk::Image( Gtk::Stock::GOTO_LAST, Gtk::ICON_SIZE_BUTTON ) ); hbox_resize_move .pack_start( *image_temp, Gtk::PACK_EXPAND_PADDING ) ; @@ -158,7 +155,7 @@ void Dialog_Base_Partition::Set_Confirm_Button( CONFIRMBUTTON button_type ) button_resize_move .add( hbox_resize_move ) ; this ->add_action_widget ( button_resize_move,Gtk::RESPONSE_OK ) ; - button_resize_move .set_sensitive( false ) ; + button_resize_move .set_sensitive( false ) ; break ; case PASTE : this->add_button( Gtk::Stock::PASTE,Gtk::RESPONSE_OK ); @@ -273,7 +270,6 @@ void Dialog_Base_Partition::on_spinbutton_value_changed( SPINBUTTON spinbutton ) { if ( ! GRIP ) { - //i expect libparted soon to be able to move startpoint of ext2/3 as well, so everything is ready for it. Till then this rudimentary check fixed_start ? before_value = 0 : before_value = spinbutton_before .get_value() ; //Balance the spinbuttons diff --git a/src/Dialog_Partition_New.cc b/src/Dialog_Partition_New.cc index 9078437f..7bffce23 100644 --- a/src/Dialog_Partition_New.cc +++ b/src/Dialog_Partition_New.cc @@ -119,15 +119,15 @@ Partition Dialog_Partition_New::Get_New_Partition() PartitionType part_type = GParted::UNALLOCATED; //paranoia ;P Sector new_start, new_end; - switch ( optionmenu_type.get_history() ) + switch ( optionmenu_type .get_history( ) ) { case 0: part_type = GParted::PRIMARY; break; case 1: part_type = GParted::LOGICAL; break; case 2: part_type = GParted::EXTENDED; break; } - new_start = START + (Sector) (spinbutton_before .get_value() * MEGABYTE) ; - new_end = new_start + (Sector) (spinbutton_size .get_value() * MEGABYTE) ; + new_start = START + (Sector) (spinbutton_before .get_value( ) * MEGABYTE) ; + new_end = new_start + (Sector) (spinbutton_size .get_value( ) * MEGABYTE) ; //due to loss of precision during calcs from Sector -> MB and back, it is possible the new partition thinks it's bigger then it can be. Here we try to solve this. if ( new_start < selected_partition.sector_start ) @@ -136,7 +136,11 @@ Partition Dialog_Partition_New::Get_New_Partition() new_end = selected_partition.sector_end ; part_temp .status = GParted::STAT_NEW ; - part_temp .Set( String::ucompose( _("New Partition #%1"), new_count ), new_count, part_type , FILESYSTEMS[ optionmenu_filesystem.get_history() ] .filesystem, new_start, new_end, selected_partition.inside_extended, false) ; + part_temp .Set( String::ucompose( _("New Partition #%1"), new_count ), + new_count, part_type, + FILESYSTEMS[ optionmenu_filesystem .get_history( ) ] .filesystem, + new_start, new_end, + selected_partition .inside_extended, false) ; //grow new partition a bit if freespaces are < 1 MB if ( (part_temp.sector_start - selected_partition.sector_start) < MEGABYTE ) diff --git a/src/Dialog_Partition_Resize_Move.cc b/src/Dialog_Partition_Resize_Move.cc index c9c3dac0..004b2e56 100644 --- a/src/Dialog_Partition_Resize_Move.cc +++ b/src/Dialog_Partition_Resize_Move.cc @@ -20,8 +20,9 @@ namespace GParted { -Dialog_Partition_Resize_Move::Dialog_Partition_Resize_Move( ) +Dialog_Partition_Resize_Move::Dialog_Partition_Resize_Move( std::vector FILESYSTEMS ) { + this ->FILESYSTEMS = FILESYSTEMS ; BUF = 5 ; } @@ -63,18 +64,18 @@ void Dialog_Partition_Resize_Move::Set_Data( const Partition & selected_partitio void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vector & partitions ) { //see if we need a fixed_start - if ( selected_partition.filesystem == "ext2" || selected_partition.filesystem == "ext3" || selected_partition.filesystem == "reiserfs" ) + if ( Get_FS( selected_partition .filesystem, FILESYSTEMS ) .move ) + { + this ->set_title( String::ucompose( _("Resize/Move %1"), selected_partition .partition ) ) ; + frame_resizer_base ->set_fixed_start( false ) ; + } + else { this ->set_title( String::ucompose( _("Resize %1"), selected_partition .partition) ) ; this ->fixed_start = true; frame_resizer_base ->set_fixed_start( true ) ; spinbutton_before .set_sensitive( false ) ; } - else - { - this ->set_title( String::ucompose( _("Resize/Move %1"), selected_partition .partition ) ) ; - frame_resizer_base ->set_fixed_start( false ) ; - } //calculate total size in MB's of previous, current and next partition //first find index of partition @@ -85,11 +86,8 @@ void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vector = 1 && partitions[t -1].type == GParted::UNALLOCATED && - selected_partition.filesystem != "ext2" && - selected_partition.filesystem != "ext3" && - selected_partition.filesystem != "reiserfs" ) + //also check the partitions filesystem ( if this is a 'resize-only' then previous should be 0 ) + if ( t >= 1 && partitions[t -1].type == GParted::UNALLOCATED && ! this ->fixed_start ) { previous = partitions[t -1] .sector_end - partitions[t -1] .sector_start ; START = partitions[t -1] .sector_start ; diff --git a/src/Dialog_Progress.cc b/src/Dialog_Progress.cc index 2655b715..71079a76 100644 --- a/src/Dialog_Progress.cc +++ b/src/Dialog_Progress.cc @@ -20,7 +20,7 @@ namespace GParted { -Dialog_Progress::Dialog_Progress( int count_operations, const Glib::ustring & first_operation ) +Dialog_Progress::Dialog_Progress( int count_operations, Glib::RefPtr textbuffer ) { this ->set_size_request( 600, 275 ) ; this ->set_resizable( false ) ; @@ -28,11 +28,9 @@ Dialog_Progress::Dialog_Progress( int count_operations, const Glib::ustring & fi this ->set_title( _("Applying pending operations") ) ; this ->count_operations = count_operations ; - current_operation_number = 0; - + current_operation_number = 0 ; fraction = (double) 1 / count_operations ; - fraction -= 1E-8 ; //minus 1E-8 is to prevent fraction from ever reaching >=1, it needs to be 0.0 < fraction < 1.0 - + Glib::ustring str_temp = "" ; str_temp += _( "Applying pending operations" ) ; str_temp += "\n\n" ; @@ -40,51 +38,110 @@ Dialog_Progress::Dialog_Progress( int count_operations, const Glib::ustring & fi str_temp += "\n"; str_temp += _("Clicking Cancel will prevent the next operations from being applied.") ; str_temp += "\n"; - this->get_vbox() ->pack_start( * mk_label( str_temp ), Gtk::PACK_SHRINK ); + this ->get_vbox( ) ->pack_start( * mk_label( str_temp ), Gtk::PACK_SHRINK ); - progressbar_current.set_text( _("initializing...") ); - this->get_vbox() ->pack_start( progressbar_current , Gtk::PACK_SHRINK); + progressbar_current .set_pulse_step( 0.01 ) ; + this->get_vbox( ) ->pack_start( progressbar_current, Gtk::PACK_SHRINK ); - label_current.set_alignment( Gtk::ALIGN_LEFT ); - label_current.set_markup( "" + first_operation + "" ) ; - this->get_vbox() ->pack_start( label_current, Gtk::PACK_SHRINK ); + label_current .set_alignment( Gtk::ALIGN_LEFT ); + this ->get_vbox( ) ->pack_start( label_current, Gtk::PACK_SHRINK ); + + textview_details .set_sensitive( false ) ; + textview_details .set_size_request( -1, 100 ) ; + textview_details .set_wrap_mode( Gtk::WRAP_WORD ) ; + + textbuffer ->signal_insert( ) .connect( sigc::mem_fun( this, &Dialog_Progress::signal_textbuffer_insert ) ) ; + textview_details .set_buffer( textbuffer ) ; - this->get_vbox() ->pack_start( * mk_label( "\n" + (Glib::ustring) _( "Completed Operations" ) + ":" ), Gtk::PACK_SHRINK ); + scrolledwindow .set_shadow_type( Gtk::SHADOW_ETCHED_IN ) ; + scrolledwindow .set_policy( Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC ) ; + scrolledwindow .add( textview_details ) ; - progressbar_all.set_text( String::ucompose( _("%1 of %2 operations completed"), 0, count_operations ) ) ; - - this->get_vbox() ->pack_start( progressbar_all, Gtk::PACK_SHRINK ); + this ->get_vbox( ) ->pack_start( scrolledwindow, Gtk::PACK_SHRINK ); + + this ->get_vbox( ) ->pack_start( * mk_label( "\n" + (Glib::ustring) _( "Completed Operations" ) + ":" ), Gtk::PACK_SHRINK ); + this ->get_vbox( ) ->pack_start( progressbar_all, Gtk::PACK_SHRINK ); - this->get_vbox() ->set_spacing( 5 ) ; - this->get_vbox() ->set_border_width( 15 ) ; + this ->get_vbox( ) ->set_spacing( 5 ) ; + this ->get_vbox( ) ->set_border_width( 15 ) ; - this->add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL ); - this->show_all_children() ; + tglbtn_details .set_label( _("Details") ) ; + tglbtn_details .signal_toggled( ) .connect( sigc::mem_fun( this, &Dialog_Progress::tglbtn_details_toggled ) ) ; + + this ->get_action_area( ) ->set_layout( Gtk::BUTTONBOX_EDGE ) ; + this ->get_action_area( ) ->pack_start( tglbtn_details ) ; + this ->add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL ); + + this ->show_all_children( ) ; + scrolledwindow .hide( ) ; } -void Dialog_Progress::Set_Next_Operation( ) -{ - progressbar_all.set_fraction( progressbar_all.get_fraction() + fraction ); - - progressbar_all.set_text( String::ucompose( _("%1 of %2 operations completed"), ++current_operation_number, count_operations ) ) ; - - label_current.set_markup( "" + current_operation + "" ) ; - progressbar_current.set_fraction( 0 ); - progressbar_current.set_text( "initializing..." ); -} - -void Dialog_Progress::Set_Progress_Current_Operation( ) +void Dialog_Progress::Set_Operation( ) { - progressbar_current.set_fraction( fraction_current ); + //all operations + if ( current_operation_number && (progressbar_all .get_fraction( ) + fraction) <= 1.0 ) + progressbar_all .set_fraction( progressbar_all .get_fraction( ) + fraction ); + + progressbar_all .set_text( String::ucompose( _("%1 of %2 operations completed"), current_operation_number++, count_operations ) ) ; - if ( time_left > 59 && time_left < 120 ) - progressbar_current.set_text( String::ucompose( _("about %1 minute and %2 seconds left"), time_left/60, time_left % 60 ) ) ; + //new operation + conn .disconnect( ) ; + + label_current .set_markup( "" + current_operation + "" ) ; + + progressbar_current .set_fraction( 0 ); + progressbar_current .set_text( "initializing..." ); + + if ( TIME_LEFT > 0 ) + { + fraction_current = (double) 1 / TIME_LEFT ; + conn = Glib::signal_timeout( ) .connect( sigc::mem_fun( *this, &Dialog_Progress::Show_Progress ), 1000 ); + } else - progressbar_current.set_text( String::ucompose( _("about %1 minutes and %2 seconds left"), time_left/60, time_left % 60 ) ) ; + conn = Glib::signal_timeout( ) .connect( sigc::mem_fun( *this, &Dialog_Progress::Pulse ), 10 ); } +bool Dialog_Progress::Show_Progress( ) +{ + if ( (progressbar_current .get_fraction( ) + fraction_current) <= 1.0 ) + { + progressbar_current .set_fraction( progressbar_current .get_fraction( ) + fraction_current ); + + if ( TIME_LEFT > 59 && TIME_LEFT < 120 ) + progressbar_current .set_text( String::ucompose( _("about %1 minute and %2 seconds left"), TIME_LEFT/60, TIME_LEFT % 60 ) ) ; + else + progressbar_current .set_text( String::ucompose( _("about %1 minutes and %2 seconds left"), TIME_LEFT/60, TIME_LEFT % 60 ) ) ; + + TIME_LEFT-- ; + } + + return true ; +} + +void Dialog_Progress::tglbtn_details_toggled( ) +{ + if ( tglbtn_details .get_active( ) ) + { + scrolledwindow .show( ) ; + this ->set_size_request( 600, 375 ) ; + } + else + { + scrolledwindow .hide( ) ; + this ->set_size_request( 600, 275 ) ; + } +} + +void Dialog_Progress::signal_textbuffer_insert( const Gtk::TextBuffer::iterator & iter, const Glib::ustring & text, int ) +{ + Gtk::TextBuffer::iterator temp = iter ; + textview_details .scroll_to( temp, 0 ) ; +} + + Dialog_Progress::~Dialog_Progress() { + conn .disconnect( ) ; } diff --git a/src/FileSystem.cc b/src/FileSystem.cc new file mode 100644 index 00000000..219e120e --- /dev/null +++ b/src/FileSystem.cc @@ -0,0 +1,60 @@ +/* Copyright (C) 2004 Bart + * + * 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/FileSystem.h" + +namespace GParted +{ + +bool FileSystem::Execute_Command( Glib::ustring command ) +{ + Glib::Dispatcher dispatcher; + sigc::connection conn = dispatcher .connect( sigc::mem_fun(*this, &FileSystem::Update_Textview) ); + + //stderr to stdout + command += " 2>&1" ; + + output = command + "\n\n" ; + dispatcher ( ) ; + + char c_buf[ 512 ] ; + FILE *f = popen( command .c_str( ), "r" ) ; + + while ( fgets( c_buf, 512, f ) ) + { + //output = Glib::locale_to_utf8( c_buf ) ; + //std::cout << output << std::endl ; + //dispatcher ( ) ;disabled for the moment. Hier moet ik nog eens fris naar kijken. (anjuta had zo'n ingebouwde terminal, hoe deed die dat?? !!! + } + + pclose( f ) ; + + output = "" ; + dispatcher ( ) ; + + return true ; +} + +void FileSystem::Update_Textview( ) +{ + //std::cout << output << std::endl; + textbuffer ->set_text( output ) ; + //textbuffer ->insert( textbuffer ->end( ), output ) ; +} + +} //GParted diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc new file mode 100644 index 00000000..097baadf --- /dev/null +++ b/src/GParted_Core.cc @@ -0,0 +1,562 @@ +#include "../include/GParted_Core.h" + +namespace GParted +{ + +//AFAIK it's not possible to use a C++ memberfunction as a callback for a C libary function (if you know otherwise, PLEASE contact me) +Glib::ustring error_message; +PedExceptionOption PedException_Handler (PedException* ex) +{ + error_message = Glib::locale_to_utf8( ex ->message ) ; + + std::cout << "\nLIBPARTED MESSAGE ----------------------\n" << error_message << "\n---------------------------\n"; + + return PED_EXCEPTION_UNHANDLED ; +} + + + +GParted_Core::GParted_Core( ) +{ + device = NULL ; + disk = NULL ; + c_partition = NULL ; + ped_exception_set_handler( PedException_Handler ) ; + + p_filesystem = NULL ; + textbuffer = Gtk::TextBuffer::create( ) ; + + //get valid flags ... + for ( PedPartitionFlag flag = ped_partition_flag_next ( (PedPartitionFlag) 0 ) ; flag ; flag = ped_partition_flag_next ( flag ) ) + flags .push_back( flag ) ; +} + +void GParted_Core::find_supported_filesystems( ) +{ + FILESYSTEMS .clear( ) ; + + ext2 fs_ext2; + FILESYSTEMS .push_back( fs_ext2 .get_filesystem_support( ) ) ; + + ext3 fs_ext3; + FILESYSTEMS .push_back( fs_ext3 .get_filesystem_support( ) ) ; + + fat16 fs_fat16; + FILESYSTEMS .push_back( fs_fat16 .get_filesystem_support( ) ) ; + + fat32 fs_fat32; + FILESYSTEMS .push_back( fs_fat32 .get_filesystem_support( ) ) ; + + linux_swap fs_linux_swap; + FILESYSTEMS .push_back( fs_linux_swap .get_filesystem_support( ) ) ; + + reiserfs fs_reiserfs; + FILESYSTEMS .push_back( fs_reiserfs .get_filesystem_support( ) ) ; +} + +void GParted_Core::get_devices( std::vector & devices, bool deep_scan ) +{ + devices .clear( ) ; + + //try to find all available devices and put these in a list + ped_device_probe_all( ); + + Device temp_device ; + std::vector device_paths ; + + device = ped_device_get_next ( NULL ); + + //in certain cases (e.g. when there's a cd in the cdrom-drive) ped_device_probe_all will find a 'ghost' device that has no name or contains + //random garbage. Those 2 checks try to prevent such a ghostdevice from being initialized.. (tested over a 1000 times with and without cd) + while ( device && strlen( device ->path ) > 6 && ( (Glib::ustring) device ->path ). is_ascii( ) ) + { + if ( open_device( device ->path, device ) ) + device_paths .push_back( get_sym_path( device ->path ) ) ; + + device = ped_device_get_next ( device ) ; + } + close_device_and_disk( device, disk ) ; + + //and sort the devices on name.. (this prevents some very weird errors ;) ) + sort( device_paths .begin( ), device_paths .end( ) ) ; + + + for ( unsigned int t = 0 ; t < device_paths .size( ) ; t++ ) + { + if ( open_device_and_disk( device_paths[ t ], device, disk ) ) + { + temp_device .path = device_paths[ t ] ; + temp_device .realpath = device ->path ; + temp_device .model = device ->model ; + temp_device .disktype = disk ->type ->name ; + temp_device .heads = device ->bios_geom .heads ; + temp_device .sectors = device ->bios_geom .sectors ; + temp_device .cylinders = device ->bios_geom .cylinders ; + temp_device .length = temp_device .heads * temp_device .sectors * temp_device .cylinders ; + temp_device .max_prims = ped_disk_get_max_primary_partition_count( disk ) ; + + get_partitions( temp_device .device_partitions, temp_device .path, deep_scan ) ; + + devices .push_back( temp_device ) ; + + close_device_and_disk( device, disk ) ; + } + } + +} + +void GParted_Core::get_partitions( std::vector & partitions, const Glib::ustring & device_path, bool deep_scan ) +{ + Partition partition_temp ; + Glib::ustring part_path, error ; + int EXT_INDEX = -1 ; + + //clear partitions + partitions .clear( ) ; + + c_partition = ped_disk_next_partition( disk, NULL ) ; + while ( c_partition ) + { + partition_temp .Reset( ) ; + part_path = device_path + num_to_str( c_partition ->num ) ; + + switch ( c_partition ->type ) + { + case PED_PARTITION_NORMAL: + case PED_PARTITION_LOGICAL: + if ( c_partition ->fs_type ) + temp = c_partition ->fs_type ->name ; + else + { + temp = "unknown" ; + error = _( "Unable to detect filesystem! Possible reasons are:" ) ; + error += "\n-"; + error += _( "The filesystem is damaged" ) ; + error += "\n-" ; + error += _( "The filesystem is unknown to libparted" ) ; + error += "\n-"; + error += _( "There is no filesystem available (unformatted)" ) ; + + } + partition_temp.Set( part_path, + c_partition ->num, + c_partition ->type == 0 ? GParted::PRIMARY : GParted::LOGICAL , + temp, c_partition ->geom .start, + c_partition ->geom .end, + c_partition ->type, + ped_partition_is_busy( c_partition ) ); + + if ( deep_scan ) + partition_temp .Set_Used( Get_Used_Sectors( c_partition, part_path ) ) ; + + partition_temp .flags = Get_Flags( c_partition ) ; + partition_temp .error = error .empty( ) ? error_message : error ; + + break ; + + + case PED_PARTITION_EXTENDED: + partition_temp.Set( part_path , + c_partition ->num , + GParted::EXTENDED , + "extended" , + c_partition ->geom .start , + c_partition ->geom .end , + false , + ped_partition_is_busy( c_partition ) ); + + partition_temp .flags = Get_Flags( c_partition ) ; + EXT_INDEX = partitions .size ( ) ; + break ; + + + case PED_PARTITION_FREESPACE: + case 5: //freespace inside extended (there's no enumvalue for that..) + partition_temp.Set_Unallocated( c_partition ->geom .start, c_partition ->geom .end, c_partition ->type == 4 ? false : true ); + break ; + + case PED_PARTITION_METADATA: + if ( partitions .size( ) && partitions .back( ) .type == GParted::UNALLOCATED ) + partitions .back( ) .sector_end = c_partition ->geom .end ; + + break ; + + case 9: //metadata inside extended (there's no enumvalue for that..) + if ( partitions[ EXT_INDEX ] .logicals .size( ) && partitions[ EXT_INDEX ] .logicals .back( ) .type == GParted::UNALLOCATED ) + partitions[ EXT_INDEX ] .logicals .back( ) .sector_end = c_partition ->geom .end ; + + break ; + + default: break; + } + + if ( partition_temp .Get_Length_MB( ) >= 1 ) // check for unallocated < 1MB, and metadatasituations (see PED_PARTITION_METADATA and 9 ) + { + if ( ! partition_temp .inside_extended ) + partitions.push_back( partition_temp ); + else + partitions[ EXT_INDEX ] .logicals .push_back( partition_temp ) ; + } + + //reset stuff.. + error = error_message = "" ; + + //next partition (if any) + c_partition = ped_disk_next_partition ( disk, c_partition ) ; + } + +} + +int GParted_Core::get_estimated_time( Operation & operation ) +{ + switch ( operation .operationtype ) + { + case GParted::DELETE: + return 2 ; //i guess it'll never take more then 2 secs to delete a partition ;) + + case GParted::CREATE: + case GParted::CONVERT: + set_proper_filesystem( operation .partition_new .filesystem ) ; + if ( p_filesystem ) + return p_filesystem ->get_estimated_time( operation .partition_new .Get_Length_MB( ) ) ; + + break ; + + case GParted::RESIZE_MOVE: + set_proper_filesystem( operation .partition_new .filesystem ) ; + if ( p_filesystem ) + return p_filesystem ->get_estimated_time( Abs( operation .partition_original .Get_Length_MB( ) - operation .partition_new .Get_Length_MB( ) ) ) ; + + break ; + + case GParted::COPY: + //lets take 10MB/s for the moment.. + return operation .partition_new .Get_Length_MB( ) / 10 ; + } + + return -1 ; //pulsing +} + +void GParted_Core::Apply_Operation_To_Disk( Operation & operation ) +{ + switch ( operation .operationtype ) + { + case DELETE: + if ( ! Delete( operation .device_path, operation .partition_original ) ) + Show_Error( String::ucompose( _("Error while deleting %1"), operation .partition_original .partition ) ) ; + + break; + case CREATE: + if ( ! Create( operation .device_path, operation .partition_new ) ) + Show_Error( String::ucompose( _("Error while creating %1"), operation .partition_new .partition ) ); + + break; + case RESIZE_MOVE: + if ( ! Resize( operation .device_path, operation .partition_original, operation .partition_new ) ) + Show_Error( String::ucompose( _("Error while resizing/moving %1"), operation .partition_new .partition ) ) ; + + break; + case CONVERT: + if ( ! Convert_FS( operation .device_path, operation .partition_new ) ) + Show_Error( String::ucompose( _("Error while converting filesystem of %1"), operation .partition_new .partition ) ) ; + + break; + case COPY: + if ( ! Copy( operation .device_path, operation .copied_partition_path, operation .partition_new ) ) + Show_Error( String::ucompose( _("Error while copying %1"), operation .partition_new .partition ) ) ; + + } + + +} + + +bool GParted_Core::Create( const Glib::ustring & device_path, Partition & new_partition ) +{ + if ( new_partition .type == GParted::EXTENDED ) + return Create_Empty_Partition( device_path, new_partition ) ; + + else if ( Create_Empty_Partition( device_path, new_partition ) > 0 ) + { + set_proper_filesystem( new_partition .filesystem ) ; + + return p_filesystem ->Create( device_path, new_partition ) ; + } + + return false ; +} + +bool GParted_Core::Convert_FS( const Glib::ustring & device_path, const Partition & partition ) +{ + set_proper_filesystem( partition .filesystem ) ; + + return p_filesystem ->Create( device_path, partition ) ; +} + +bool GParted_Core::Delete( const Glib::ustring & device_path, const Partition & partition ) +{ + bool return_value = false ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + if ( partition .type == GParted::EXTENDED ) + c_partition = ped_disk_extended_partition( disk ) ; + else + c_partition = ped_disk_get_partition_by_sector( disk, (partition .sector_end + partition .sector_start) / 2 ) ; + + return_value = ( ped_disk_delete_partition( disk, c_partition ) && Commit( disk ) ) ; + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +bool GParted_Core::Resize(const Glib::ustring & device_path, const Partition & partition_old, const Partition & partition_new ) +{ + if ( partition_old .type == GParted::EXTENDED ) + return Resize_Extended( device_path, partition_new ) ; + + else + { + set_proper_filesystem( partition_new .filesystem ) ; + + return p_filesystem ->Resize( device_path, partition_old, partition_new ) ; + } + + return false ; +} + +bool GParted_Core::Copy( const Glib::ustring & dest_device_path, const Glib::ustring & src_part_path, Partition & partition_dest ) +{ + if ( Create_Empty_Partition( dest_device_path, partition_dest ) > 0 ) + { + set_proper_filesystem( partition_dest .filesystem ) ; + + return p_filesystem ->Copy( src_part_path, partition_dest .partition ) ; + } + + return false ; +} + +std::vector GParted_Core::get_fs( ) +{ + return FILESYSTEMS ; +} + +Glib::RefPtr GParted_Core::get_textbuffer( ) +{ + return textbuffer ; +} + +Glib::ustring GParted_Core::get_sym_path( const Glib::ustring & real_path ) +{ + int major, minor, size; + char temp[4096], device_name[4096], short_path[4096] ; + + FILE* proc_part_file = fopen ( "/proc/partitions", "r" ); + if ( ! proc_part_file ) + return real_path; + + //skip first 2 useless rules of /proc/partitions + fgets( temp, 256, proc_part_file ); fgets( temp, 256, proc_part_file ); + + while ( fgets( temp, 4096, proc_part_file ) && sscanf(temp, "%d %d %d %255s", &major, &minor, &size, device_name ) == 4 ) + { + strcpy( short_path, "/dev/" ); strcat( short_path, device_name ); + realpath( short_path, device_name ); + + if ( real_path == device_name ) { + fclose ( proc_part_file ); + return ( Glib::ustring( short_path ) ); + } + + } + + //paranoia modus :) + fclose ( proc_part_file ); + return real_path; +} + + +Sector GParted_Core::Get_Used_Sectors( PedPartition *c_partition, const Glib::ustring & sym_path) +{ + /* This is quite an unreliable process, atm i try two different methods, but since both are far from perfect the results are + * questionable. + * - first i try geometry.get_used() in libpartedpp, i implemented this function to check the minimal size when resizing a partition. Disadvantage + * of this method is the fact it won't work on mounted filesystems. Besides that, its SLOW + * - if the former method fails ( result is -1 ) i'll try to read the output from the df command ( df -k --sync ) + * - if this fails the filesystem on the partition is ( more or less ) unknown to the operating system and therefore the unused sectors cannot be calcualted + * - as soon as i have my internetconnection back i should ask people with more experience on this stuff for advice ! + */ + + //check if there is a (known) filesystem + if ( ! c_partition ->fs_type ) + return -1; + + //used sectors are not relevant for swapspace + if ( (Glib::ustring) c_partition ->fs_type ->name == "linux-swap" ) + return -1; + + //METHOD #1 + //the getused method doesn't work on mounted partitions and for some filesystems ( i *guess* this is called check by andrew ) + if ( ! ped_partition_is_busy( c_partition ) && Get_FS( c_partition ->fs_type ->name, FILESYSTEMS ) .create ) + { + PedFileSystem *fs = NULL; + PedConstraint *constraint = NULL; + + fs = ped_file_system_open( & c_partition ->geom ); + + if ( fs ) + { + constraint = ped_file_system_get_resize_constraint (fs); + ped_file_system_close (fs); + if ( constraint && constraint->min_size != -1 ) + return constraint->min_size ; + } + } + + //METHOD #2 + //this ony works for mounted ( and therefore known to the OS ) filesystems. My method is quite crude, keep in mind it's only temporary ;-) + if ( ped_partition_is_busy( c_partition ) ) + { + Glib::ustring buf; + system( ("df -k --sync " + sym_path + " | grep " + sym_path + " > /tmp/.tmp_gparted") .c_str( ) ); + std::ifstream file_input( "/tmp/.tmp_gparted" ); + + file_input >> buf; //skip first value + file_input >> buf; + if ( buf != "0" && ! buf .empty( ) ) + { + file_input >> buf; + file_input .close( ); system( "rm -f /tmp/.tmp_gparted" ); + return atoi( buf .c_str( ) ) * 1024/512 ; + } + file_input .close( ); system( "rm -f /tmp/.tmp_gparted" ); + } + + + return -1 ; //all methods were unsuccesfull +} + +int GParted_Core::Create_Empty_Partition( const Glib::ustring & device_path, Partition & new_partition ) +{ + new_partition .partition_number = 0 ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + PedPartitionType type; + PedPartition *c_part = NULL ; + PedConstraint *constraint = NULL ; + + //create new partition + switch ( new_partition .type ) + { + case 0 : type = PED_PARTITION_NORMAL; break ; + case 1 : type = PED_PARTITION_LOGICAL; break ; + case 2 : type = PED_PARTITION_EXTENDED; break ; + default : type = PED_PARTITION_FREESPACE; break ; //will never happen ;) + } + + c_part = ped_partition_new ( disk, type, NULL, new_partition .sector_start, new_partition .sector_end ) ; + if ( c_part ) + { + constraint = ped_constraint_any ( device ); + if ( constraint ) + { + if ( ped_disk_add_partition ( disk, c_part, constraint ) && Commit( disk ) ) + { + sleep( 1 ) ;//the OS needs some time to create the devicenode in /dev + new_partition .partition = ped_partition_get_path( c_part ) ; + new_partition .partition_number = c_part ->num ; + } + + ped_constraint_destroy ( constraint ); + } + } + + close_device_and_disk( device, disk ) ; + } + + return new_partition .partition_number ; +} + +bool GParted_Core::Resize_Extended( const Glib::ustring & device_path, const Partition & extended ) +{ + bool return_value = false ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + PedPartition *c_part = NULL ; + PedConstraint *constraint = NULL ; + + c_part = ped_disk_extended_partition( disk ) ; + if ( c_part ) + { + constraint = ped_constraint_any ( device ); + if ( constraint ) + { + if ( ped_disk_set_partition_geom ( disk, c_part, constraint, extended .sector_start, extended .sector_end ) ) + { + ped_partition_set_system ( c_part, NULL ); + return_value = Commit( disk ) ; + } + + ped_constraint_destroy (constraint); + } + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +Glib::ustring GParted_Core::Get_Flags( PedPartition *c_partition ) +{ + temp = ""; + + for ( unsigned short t = 0; t < flags .size( ) ; t++ ) + if ( ped_partition_get_flag ( c_partition, flags[ t ] ) ) + temp += (Glib::ustring) ped_partition_flag_get_name ( flags[ t ] ) + " "; + + return temp ; +} + +void GParted_Core::Show_Error( Glib::ustring message ) +{ + message = "" + message + "\n\n" ; + message += _( "Be aware that the failure to apply this operation could affect other operations on the list." ) ; + Gtk::MessageDialog dialog( message ,true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true ); + + gdk_threads_enter( ); + dialog .run( ); + gdk_threads_leave( ); +} + +void GParted_Core::set_proper_filesystem( const Glib::ustring & filesystem ) +{ + //ugly, stupid, *aaargh* :-) + + if ( ! p_filesystem ) + delete p_filesystem ; + + if ( filesystem == "ext2" ) + p_filesystem = new ext2( ) ; + else if ( filesystem == "ext3" ) + p_filesystem = new ext3( ) ; + else if ( filesystem == "fat16" ) + p_filesystem = new fat16( ) ; + else if ( filesystem == "fat32" ) + p_filesystem = new fat32( ) ; + else if ( filesystem == "linux-swap" ) + p_filesystem = new linux_swap( ) ; + else if ( filesystem == "reiserfs" ) + p_filesystem = new reiserfs( ) ; + else + p_filesystem = NULL ; + + if ( p_filesystem ) + p_filesystem ->textbuffer = textbuffer ; +} + +} //GParted diff --git a/src/Makefile.am b/src/Makefile.am index a925dd0d..673db80a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,8 +28,16 @@ gparted_SOURCES = \ Dialog_About.cc\ Frame_Resizer_Base.cc\ Frame_Resizer_Extended.cc\ - Dialog_Base_Partition.cc - + Dialog_Base_Partition.cc\ + GParted_Core.cc\ + FileSystem.cc\ + ext2.cc\ + ext3.cc\ + fat16.cc\ + fat32.cc\ + linux_swap.cc\ + reiserfs.cc + gparted_LDFLAGS = -lparted -lgthread-2.0 gparted_LDADD = \ diff --git a/src/Operation.cc b/src/Operation.cc index f8f13f4d..611e4ea7 100644 --- a/src/Operation.cc +++ b/src/Operation.cc @@ -19,14 +19,10 @@ namespace GParted { -Operation::Operation( Device *device, Device *source_device, const Partition & partition_original, const Partition & partition_new, OperationType operationtype ) +Operation::Operation( const Glib::ustring device_path, Sector device_length, const Partition & partition_original, const Partition & partition_new, OperationType operationtype ) { - this ->device = device; - this ->device_path = device ->Get_Path( ) ; - - //this is only used when operationtype == COPY - this ->source_device = source_device; - this ->source_device_path = source_device ->Get_Path( ) ; + this ->device_path = device_path ; + this ->device_length = device_length ; this ->partition_original = partition_original; this ->partition_new = partition_new; @@ -34,10 +30,11 @@ Operation::Operation( Device *device, Device *source_device, const Partition & p str_operation = Get_String( ) ; - //not the nicest place to put this, but definetly the most efficient :) if ( operationtype == COPY ) + { + copied_partition_path = partition_new .partition ; this ->partition_new .partition = String::ucompose( _("copy of %1"), this ->partition_new .partition ); - + } } @@ -54,7 +51,7 @@ Glib::ustring Operation::Get_String( ) temp = partition_original .partition ; /*TO TRANSLATORS: looks like Delete /dev/hda2 (ntfs, 2345 MB) from /dev/hda */ - return String::ucompose( _("Delete %1 (%2, %3 MB) from %4"), temp, partition_original .filesystem, partition_original .Get_Length_MB(), device ->Get_Path() ) ; + return String::ucompose( _("Delete %1 (%2, %3 MB) from %4"), temp, partition_original .filesystem, partition_original .Get_Length_MB( ), device_path ) ; case CREATE : switch( partition_new.type ) { @@ -64,7 +61,7 @@ Glib::ustring Operation::Get_String( ) default : break; } /*TO TRANSLATORS: looks like Create Logical Partition #1 (ntfs, 2345 MB) on /dev/hda */ - return String::ucompose( _("Create %1 #%2 (%3, %4 MB) on %5"), temp, partition_new.partition_number, partition_new.filesystem , partition_new .Get_Length_MB(), device ->Get_Path() ) ; + return String::ucompose( _("Create %1 #%2 (%3, %4 MB) on %5"), temp, partition_new.partition_number, partition_new.filesystem , partition_new .Get_Length_MB( ), device_path ) ; case RESIZE_MOVE: //if startsector has changed >= 1 MB we consider it a move diff = Abs( partition_new .sector_start - partition_original .sector_start ) ; if ( diff >= MEGABYTE ) @@ -92,7 +89,7 @@ Glib::ustring Operation::Get_String( ) case CONVERT : /*TO TRANSLATORS: looks like Convert /dev/hda4 from ntfs to linux-swap */ return String::ucompose( _( "Convert %1 from %2 to %3"), partition_original .partition, partition_original .filesystem, partition_new .filesystem ) ; case COPY : /*TO TRANSLATORS: looks like Copy /dev/hda4 to /dev/hdd (start at 2500 MB) */ - return String::ucompose( _("Copy %1 to %2 (start at %3 MB)"), partition_new .partition, device ->Get_Path( ), Sector_To_MB( partition_new .sector_start ) ) ; + return String::ucompose( _("Copy %1 to %2 (start at %3 MB)"), partition_new .partition, device_path, Sector_To_MB( partition_new .sector_start ) ) ; default : return ""; } @@ -111,42 +108,6 @@ void Operation::Apply_Operation_To_Visual( std::vector & partitions ) } } -void Operation::Apply_To_Disk( PedTimer * timer ) -{ - Glib::ustring buf; - bool result; //for some weird reason it won't work otherwise .. ( this one really beats me :-S ) - - switch ( operationtype ) - { - case DELETE : result = device ->Delete_Partition( partition_original ) ; - if ( ! result ) - Show_Error( String::ucompose( _("Error while deleting %1"), partition_original.partition ) ) ; - - break; - case CREATE : result = device ->Create_Partition_With_Filesystem( partition_new, timer ) ; - if ( ! result ) - Show_Error( String::ucompose( _("Error while creating %1"), partition_new.partition ) ); - - break; - case RESIZE_MOVE: result = device ->Move_Resize_Partition( partition_original, partition_new, timer ) ; - if ( ! result ) - Show_Error( String::ucompose( _("Error while resizing/moving %1"), partition_new.partition ) ) ; - - break; - case CONVERT : result = device ->Set_Partition_Filesystem( partition_new, timer ) ; - if ( ! result ) - Show_Error( String::ucompose( _("Error while converting filesystem of %1"), partition_new.partition ) ) ; - - break; - case COPY : result = device ->Copy_Partition( source_device, partition_new, timer ) ; - if ( ! result ) - Show_Error( String::ucompose( _("Error while copying %1"), partition_new .partition ) ) ; - - break; - } - -} - void Operation::Insert_Unallocated( std::vector & partitions, Sector start, Sector end ) { Partition UNALLOCATED ; @@ -217,7 +178,7 @@ void Operation::Apply_Delete_To_Visual( std::vector & partitions ) { partitions .erase( partitions .begin( ) + Get_Index_Original( partitions ) ); - Insert_Unallocated( partitions, 0, device ->Get_Length( ) -1 ) ; + Insert_Unallocated( partitions, 0, device_length -1 ) ; } else { @@ -244,7 +205,7 @@ void Operation::Apply_Create_To_Visual( std::vector & partitions ) { partitions[ Get_Index_Original( partitions ) ] = partition_new ; - Insert_Unallocated( partitions, 0, device ->Get_Length( ) -1 ) ; + Insert_Unallocated( partitions, 0, device_length -1 ) ; } else { @@ -271,7 +232,7 @@ void Operation::Apply_Resize_Move_Extended_To_Visual( std::vector & p partitions[ ext ] .sector_start = partition_new .sector_start ; partitions[ ext ] .sector_end = partition_new .sector_end ; - Insert_Unallocated( partitions, 0, device ->Get_Length( ) -1 ) ; + Insert_Unallocated( partitions, 0, device_length -1 ) ; //stuff INSIDE extended partition ext = 0 ; @@ -286,16 +247,4 @@ void Operation::Apply_Resize_Move_Extended_To_Visual( std::vector & p Insert_Unallocated( partitions[ ext ] .logicals, partitions[ ext ] .sector_start, partitions[ ext ] .sector_end ) ; } -void Operation::Show_Error( Glib::ustring message ) -{ - message = "" + message + "\n\n" ; - message += _( "Be aware that the failure to apply this operation could affect other operations on the list." ) ; - Gtk::MessageDialog dialog( message ,true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true ); - - gdk_threads_enter( ); - dialog .run( ); - gdk_threads_leave( ); -} - - } //GParted diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc index a4d166ad..356a1b65 100644 --- a/src/Win_GParted.cc +++ b/src/Win_GParted.cc @@ -24,13 +24,13 @@ Win_GParted::Win_GParted( ) { copied_partition .partition = "NONE" ; new_count = 1; - current_device = source_device = 0 ; + current_device = 0 ; vbox_visual_disk = NULL; pulse = false ; //store filesystems in vector and find out if their respective libs are installed - Find_Supported_Filesystems() ; - + gparted_core .find_supported_filesystems( ) ; + //locate all available devices and store them in devices vector Find_Devices( false ) ; Refresh_OptionMenu( ) ; @@ -86,7 +86,7 @@ Win_GParted::Win_GParted( ) close_operationslist( ) ; conn = dispatcher .connect( sigc::mem_fun( *this, &Win_GParted::menu_gparted_refresh_devices ) ); - dispatcher ( ) ; + dispatcher( ) ; } void Win_GParted::init_menubar() @@ -184,9 +184,9 @@ void Win_GParted::init_popupmenu() void Win_GParted::init_convert_menu() { - for ( unsigned int t=0; t < FILESYSTEMS .size() ; t++ ) + for ( unsigned int t=0; t < gparted_core .get_fs( ) .size() ; t++ ) { - color .set( Get_Color( FILESYSTEMS[ t ] .filesystem ) ); + color .set( Get_Color( gparted_core .get_fs( )[ t ] .filesystem ) ); hbox = manage( new Gtk::HBox() ); //the colored square @@ -197,11 +197,11 @@ void Win_GParted::init_convert_menu() hbox ->pack_start( *entry, Gtk::PACK_SHRINK ); //the label... - hbox ->pack_start( * mk_label( " " + FILESYSTEMS[ t ] .filesystem ), Gtk::PACK_SHRINK ); + hbox ->pack_start( * mk_label( " " + gparted_core .get_fs( )[ t ] .filesystem ), Gtk::PACK_SHRINK ); menu_item = manage( new Gtk::MenuItem( *hbox ) ) ; menu_convert.items().push_back( *menu_item); - menu_convert.items() .back() .signal_activate() .connect( sigc::bind(sigc::mem_fun(*this, &Win_GParted::activate_convert), FILESYSTEMS[ t ] .filesystem ) ) ; + menu_convert.items() .back() .signal_activate() .connect( sigc::bind(sigc::mem_fun(*this, &Win_GParted::activate_convert), gparted_core .get_fs( )[ t ] .filesystem ) ) ; } menu_convert.show_all_children() ; @@ -235,7 +235,7 @@ void Win_GParted::init_device_info() table ->attach( * device_info .back(), 1,2, top++, bottom++, Gtk::FILL); //only show realpath if it's different from the short path - if ( devices[ current_device ] ->Get_Path() != devices[ current_device ] ->Get_RealPath() ) + if ( devices[ current_device ] .path != devices[ current_device ] .realpath ) { table ->attach( * mk_label( " " + (Glib::ustring) _( "Real Path:" ) + "" ) , 0,1,top, bottom ,Gtk::FILL); device_info .push_back( mk_label( "" ) ) ; @@ -343,59 +343,22 @@ void Win_GParted::init_hpaned_main() hpaned_main.pack2( *scrollwindow, true,true ); } -void Win_GParted::Find_Supported_Filesystems() -{ - FS fs; - static void * test_handle = NULL ; - - //built-in filesystems - fs .supported = true ; - fs .create = true ; - - fs .filesystem = "ext2" ; FILESYSTEMS .push_back( fs ) ; - fs .filesystem = "ext3" ; FILESYSTEMS .push_back( fs ) ; FILESYSTEMS .back() .create = false ; - fs .filesystem = "fat16" ; FILESYSTEMS .push_back( fs ) ; - fs .filesystem = "fat32" ; FILESYSTEMS .push_back( fs ) ; - fs .filesystem = "linux-swap" ; FILESYSTEMS .push_back( fs ) ; - - //optional filesystems (depends if fitting libary is installed) - fs .supported = fs .create = false ; - - fs .filesystem = "reiserfs" ; FILESYSTEMS .push_back( fs ) ; - if ( (test_handle = dlopen("libreiserfs.so", RTLD_NOW)) ) - { - FILESYSTEMS .back() .supported = FILESYSTEMS .back() .create = true ; - dlclose( test_handle ) ; - test_handle = NULL ; - } -} - void Win_GParted::Find_Devices( bool deep_scan ) { - for ( unsigned int t = 0 ; t < devices .size( ) ; t++ ) - delete devices[ t ] ; + gparted_core .get_devices( devices, deep_scan ) ; - devices .clear( ) ; - - //try to find all available devices and put these in a list - ped_device_probe_all( ); - - PedDevice *device = ped_device_get_next ( NULL ); - - //in certain cases (e.g. when there's a cd in the cdrom-drive) ped_device_probe_all will find a 'ghost' device that has no name or contains - //random garbage. Those 2 checks try to prevent such a ghostdevice from being initialized.. (tested over a 1000 times with and without cd) - while ( device && strlen( device ->path ) > 6 && ( (Glib::ustring) device ->path ). is_ascii( ) ) - { - temp_device = new GParted::Device( device ->path, &FILESYSTEMS ); - if ( temp_device ->Get_Length() > 0 ) - { - temp_device ->Read_Disk_Layout( deep_scan ) ; - devices .push_back( temp_device ) ; - } - else - delete temp_device ; + //paranoia check.. :) <---NOT threadsave.. + if ( devices .empty( ) ) + { + str_temp = "" ; + str_temp += _("No devices were detected") ; + str_temp += "\n\n" ; + str_temp += _( "You have probably encountered a bug. GParted will quit now.") ; + + Gtk::MessageDialog dialog( *this, str_temp, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true ) ; + dialog .run( ) ; - device = ped_device_get_next ( device ) ; + exit( 0 ) ; } } @@ -412,7 +375,7 @@ void Win_GParted::Refresh_OptionMenu( ) hbox ->pack_start( *image, Gtk::PACK_SHRINK ); //the label... - hbox ->pack_start( *mk_label( " " + devices[i] ->Get_Path() + "\t(" + String::ucompose( _("%1 MB"), Sector_To_MB( devices[i] ->Get_Length() ) ) + ")" ), Gtk::PACK_SHRINK ); + hbox ->pack_start( *mk_label( " " + devices[i] .path + "\t(" + String::ucompose( _("%1 MB"), Sector_To_MB( devices[i] .length ) ) + ")" ), Gtk::PACK_SHRINK ); menu_item = manage( new Gtk::MenuItem( *hbox ) ) ; menu_devices .items().push_back( *menu_item ); @@ -459,20 +422,20 @@ void Win_GParted::Fill_Label_Device_Info( ) short t=0; //global info... - device_info[ t++ ] ->set_text( devices[ current_device ] ->Get_Model() ) ; - device_info[ t++ ] ->set_text( String::ucompose( _("%1 MB"), Sector_To_MB( devices[ current_device ] ->Get_Length() ) ) ) ; - device_info[ t++ ] ->set_text( devices[ current_device ] ->Get_Path() ) ; + device_info[ t++ ] ->set_text( devices[ current_device ] .model ) ; + device_info[ t++ ] ->set_text( String::ucompose( _("%1 MB"), Sector_To_MB( devices[ current_device ] .length ) ) ) ; + device_info[ t++ ] ->set_text( devices[ current_device ] .path ) ; //only show realpath if it's diffent from the short path... - if ( devices[ current_device ] ->Get_Path() != devices[ current_device ] ->Get_RealPath() ) - device_info[ t++ ] ->set_text( devices[ current_device ] ->Get_RealPath() ) ; + if ( devices[ current_device ] .path != devices[ current_device ] .realpath ) + device_info[ t++ ] ->set_text( devices[ current_device ] .realpath ) ; //detailed info - device_info[ t++ ] ->set_text( devices[ current_device ] ->Get_DiskType() ) ; - device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] ->Get_Heads() ) ); - device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] ->Get_Sectors() ) ); - device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] ->Get_Cylinders() ) ); - device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] ->Get_Length() ) ); + device_info[ t++ ] ->set_text( devices[ current_device ] .disktype ) ; + device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] .heads ) ); + device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] .sectors ) ); + device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] .cylinders ) ); + device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] .length ) ); } bool Win_GParted::on_delete_event(GdkEventAny *event) @@ -482,8 +445,8 @@ bool Win_GParted::on_delete_event(GdkEventAny *event) void Win_GParted::Add_Operation( OperationType operationtype, const Partition & new_partition) { - Operation operation( devices[ current_device ], devices[ source_device ], selected_partition, new_partition, operationtype ); - + Operation operation( devices[ current_device ] .path, devices[ current_device ] .length, selected_partition, new_partition, operationtype ); + operations.push_back( operation ); allow_undo( true ); @@ -502,13 +465,13 @@ void Win_GParted::Add_Operation( OperationType operationtype, const Partition & void Win_GParted::Refresh_Visual( ) { - std::vector partitions = devices[current_device] ->Get_Partitions() ; + std::vector partitions = devices[current_device] .device_partitions ; liststore_operations ->clear(); //make all operations visible for ( unsigned int t = 0 ; t < operations .size( ); t++ ) { - if ( operations[ t ] .device ->Get_Path( ) == devices[ current_device ] ->Get_Path( ) ) + if ( operations[ t ] .device_path == devices[ current_device ] .path ) operations[ t ] .Apply_Operation_To_Visual( partitions ) ; treerow = *(liststore_operations ->append( )); @@ -570,7 +533,7 @@ void Win_GParted::Refresh_Visual( ) delete ( vbox_visual_disk ); } - vbox_visual_disk = new VBox_VisualDisk ( partitions, devices[ current_device ] ->Get_Length( ) ) ; + vbox_visual_disk = new VBox_VisualDisk ( partitions, devices[ current_device ] .length ) ; vbox_visual_disk ->signal_mouse_click.connect( sigc::mem_fun( this, &Win_GParted::mouse_click ) ) ; hbox_visual .pack_start( *vbox_visual_disk, Gtk::PACK_EXPAND_PADDING ) ; hbox_visual .show_all_children( ) ; @@ -643,7 +606,7 @@ void Win_GParted::Set_Valid_Operations() allow_convert( true ) ; //find out if resizing/moving and copying is possible - if ( Supported( selected_partition .filesystem, &FILESYSTEMS ) ) + if ( Get_FS( selected_partition .filesystem, gparted_core .get_fs( ) ) .resize ) { allow_resize( true ) ; @@ -670,9 +633,9 @@ void Win_GParted::Set_Valid_Operations() void Win_GParted::Set_Valid_Convert_Filesystems() { //disable conversion to the same filesystem - for ( unsigned int t=0;tGet_Path() ) - operations[t] .device = devices[ i ] ; - if ( operations[t] .source_device_path == devices[ i ] ->Get_Path() ) - operations[t] .source_device = devices[ i ] ; - } - //check if current_device is still available (think about hotpluggable shit like usbdevices) if ( current_device >= devices .size() ) current_device = 0 ; @@ -834,10 +787,10 @@ void Win_GParted::mouse_click( GdkEventButton *event, const Partition & partitio bool Win_GParted::max_amount_prim_reached( ) { //Display error if user tries to create more primary partitions than the partition table can hold. - if ( ! selected_partition .inside_extended && primary_count >= devices[ current_device ] ->Get_Max_Amount_Of_Primary_Partitions( ) ) + if ( ! selected_partition .inside_extended && primary_count >= devices[ current_device ] .max_prims ) { str_temp = "" ; - str_temp += String::ucompose( _("It is not possible to create more than %1 primary partitions"), devices[ current_device ] ->Get_Max_Amount_Of_Primary_Partitions( ) ) ; + str_temp += String::ucompose( _("It is not possible to create more than %1 primary partitions"), devices[ current_device ] .max_prims ) ; str_temp += "\n\n" ; str_temp += _( "If you want more partitions you should first create an extended partition. Such a partition can contain other partitions.") ; @@ -878,15 +831,15 @@ void Win_GParted::activate_resize() } - std::vector partitions = devices[ current_device ] ->Get_Partitions( ) ; + std::vector partitions = devices[ current_device ] .device_partitions ; if ( operations.size() ) for (unsigned int t=0;tGet_Path( ) == devices[ current_device ] ->Get_Path( ) ) + if ( operations[t]. device_path == devices[ current_device ] .path ) operations[ t ] .Apply_Operation_To_Visual( partitions ) ; - Dialog_Partition_Resize_Move dialog; + Dialog_Partition_Resize_Move dialog( gparted_core .get_fs( ) ) ; if ( selected_partition .type == GParted::LOGICAL ) { @@ -929,7 +882,6 @@ void Win_GParted::activate_resize() void Win_GParted::activate_copy() { copied_partition = selected_partition ; - source_device = current_device ; } void Win_GParted::activate_paste() @@ -953,7 +905,7 @@ void Win_GParted::activate_new() if ( ! max_amount_prim_reached( ) ) { Dialog_Partition_New dialog; - dialog .Set_Data( selected_partition, any_extended, new_count, FILESYSTEMS ) ; + dialog .Set_Data( selected_partition, any_extended, new_count, gparted_core .get_fs( ) ) ; dialog .set_transient_for( *this ); if ( dialog.run() == Gtk::RESPONSE_OK ) @@ -973,7 +925,7 @@ void Win_GParted::activate_delete() //it seems best to check for this and prohibit deletion with some explanation to the user. if ( selected_partition .type == GParted::LOGICAL && selected_partition .status != GParted::STAT_NEW && - selected_partition .partition_number < devices [ current_device ] -> Get_Highest_Logical_Busy( ) ) + selected_partition .partition_number < devices [ current_device ] .Get_Highest_Logical_Busy( ) ) { str_temp = "" ; str_temp += _( "Unable to delete partition!") ; @@ -1005,11 +957,8 @@ void Win_GParted::activate_delete() //if deleted partition was on the clipboard we erase it... if ( selected_partition .partition == copied_partition .partition ) - { copied_partition .partition = "NONE" ; - source_device = current_device ; - } - + //if deleted one is NEW, it doesn't make sense to add it to the operationslist, we erase its creation //and possible modifications like resize etc.. from the operationslist. Calling Refresh_Visual will wipe every memory of its existence ;-) if ( selected_partition .status == GParted::STAT_NEW ) @@ -1155,22 +1104,6 @@ void Win_GParted::activate_undo() } - -//-------AFAIK it's not possible to use a C++ memberfunction as a callback for a C libary function (if you know otherwise, PLEASE contact me)------------ -Dialog_Progress *dp; -Glib::Dispatcher dispatcher_set_progress; - -void progress_callback( PedTimer * timer, void *context ) -{ - if ( time(NULL) - timer ->start > 0 ) - { - dp ->time_left = timer ->predicted_end - time(NULL) ; - dp ->fraction_current = timer ->frac ; - dispatcher_set_progress() ; - } -} -//--------------------------------------------------------------------------------------- - void Win_GParted::activate_apply() { str_temp = "" ; @@ -1179,22 +1112,21 @@ void Win_GParted::activate_apply() str_temp += _( "It is recommended to backup valueable data before proceeding.") ; Gtk::MessageDialog dialog( *this, str_temp, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); - dialog.set_title( _( "Apply operations to harddisk" ) ); + dialog .set_title( _( "Apply operations to harddisk" ) ); - dialog.add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL ); - dialog.add_button( Gtk::Stock::APPLY, Gtk::RESPONSE_OK ); + dialog .add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL ); + dialog .add_button( Gtk::Stock::APPLY, Gtk::RESPONSE_OK ); - dialog.show_all_children( ) ; - if ( dialog.run() == Gtk::RESPONSE_OK ) + dialog .show_all_children( ) ; + if ( dialog.run( ) == Gtk::RESPONSE_OK ) { - dialog.hide() ; //hide confirmationdialog + dialog .hide( ) ; //hide confirmationdialog apply = true; - dialog_progress = new Dialog_Progress ( operations.size(), operations.front() .str_operation ) ; - dp = dialog_progress ; - conn = dispatcher .connect( sigc::mem_fun(*dialog_progress, &Dialog_Progress::Set_Next_Operation) ); - dispatcher_set_progress .connect( sigc::mem_fun( *dialog_progress, &Dialog_Progress::Set_Progress_Current_Operation ) ); + dialog_progress = new Dialog_Progress ( operations .size( ), gparted_core .get_textbuffer( ) ) ; + conn = dispatcher .connect( sigc::mem_fun(*dialog_progress, &Dialog_Progress::Set_Operation) ); + thread = Glib::Thread::create(SigC::slot_class(*this, &Win_GParted::apply_operations_thread), true); dialog_progress ->set_transient_for( *this ); @@ -1208,32 +1140,36 @@ void Win_GParted::activate_apply() //make list of involved devices which have at least one busy partition.. std::vector devicenames ; - for (unsigned int t=0; tGet_Path() ) == devicenames .end() && - operations[ t ] .device ->Get_any_busy() - ) - devicenames .push_back( operations[ t ] .device ->Get_Path() ) ; - + for ( unsigned int t = 0; t < devices .size( ); t++ ) + if ( devices[ t ] .Get_any_busy( ) ) + for (unsigned int i = 0; i < operations .size( ); i++ ) + if ( operations[ i ] .device_path == devices[ t ] .path ) + { + devicenames .push_back( devices[ t ] .path ) ; + break ; + } + + //show warning if necessary - if ( devicenames .size() ) + if ( devicenames .size( ) ) { str_temp = "" ; /*TO TRANSLATORS: after the colon (:) a list of devices will be shown */ str_temp += _("The kernel was unable to re-read the partition table on:") ; str_temp += "\n"; - for (unsigned int t=0; t 1 ) + if ( devicenames .size( ) > 1 ) str_temp += _( "You should reboot your computer before doing anything with these devices.") ; else str_temp += _( "You should reboot your computer before doing anything with this device.") ; - Gtk::MessageDialog dialog( *this, str_temp, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true); - dialog.run() ; + Gtk::MessageDialog dialog( *this, str_temp, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true ); + dialog .run( ) ; } @@ -1247,22 +1183,18 @@ void Win_GParted::activate_apply() //reread devices and their layouts... menu_gparted_refresh_devices( ) ; - } - } void Win_GParted::apply_operations_thread( ) { - for ( unsigned int t=0;tcurrent_operation = operations[ t ] .str_operation ; + dialog_progress ->TIME_LEFT = gparted_core .get_estimated_time( operations[ t ] ) ; + dispatcher( ) ; - if ( t < operations .size() -1 ) - { - dialog_progress ->current_operation = operations[ t +1 ] .str_operation ; - dispatcher( ) ; - } + gparted_core .Apply_Operation_To_Disk( operations[ t ] ); } dialog_progress ->response( Gtk::RESPONSE_OK ); diff --git a/src/ext2.cc b/src/ext2.cc new file mode 100644 index 00000000..da043c38 --- /dev/null +++ b/src/ext2.cc @@ -0,0 +1,117 @@ +/* Copyright (C) 2004 Bart + * + * 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/ext2.h" + +namespace GParted +{ + +FS ext2::get_filesystem_support( ) +{ + FS fs ; + + fs .filesystem = "ext2" ; + fs .create = true ; + fs .resize = true ; + + return fs ; +} + +bool ext2::Create( const Glib::ustring device_path, const Partition & new_partition ) +{ + bool return_value = false ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + PedPartition *c_part = NULL ; + PedFileSystemType *fs_type = NULL ; + PedFileSystem *fs = NULL ; + + c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ; + if ( c_part ) + { + fs_type = ped_file_system_type_get( "ext2" ) ; + if ( fs_type ) + { + fs = ped_file_system_create( & c_part ->geom, fs_type, NULL ); + if ( fs ) + { + if ( ped_partition_set_system( c_part, fs_type ) ) + return_value = Commit( disk ) ; + + ped_file_system_close( fs ); + } + } + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +bool ext2::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) +{ + bool return_value = false ; + + PedPartition *c_part = NULL ; + PedFileSystem *fs = NULL ; + PedConstraint *constraint = NULL ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ; + if ( c_part ) + { + fs = ped_file_system_open ( & c_part->geom ); + if ( fs ) + { + constraint = ped_file_system_get_resize_constraint ( fs ); + if ( constraint ) + { + if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) && + ped_file_system_resize ( fs, & c_part->geom, NULL ) ) + return_value = Commit( disk ) ; + + ped_constraint_destroy ( constraint ); + } + + ped_file_system_close ( fs ); + } + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +bool ext2::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) +{ + return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ; +} + +int ext2::get_estimated_time( long MB_to_Consider ) +{ + return 1 + MB_to_Consider / 500 ; +} + + +} //GParted + + diff --git a/src/ext3.cc b/src/ext3.cc new file mode 100644 index 00000000..70e08ce3 --- /dev/null +++ b/src/ext3.cc @@ -0,0 +1,125 @@ +/* Copyright (C) 2004 Bart + * + * 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/ext3.h" + +namespace GParted +{ + +FS ext3::get_filesystem_support( ) +{ + FS fs ; + + fs .filesystem = "ext3" ; + + if ( ! system( "which tune2fs 1>/dev/null 2>/dev/null" ) ) ; + fs .create = true ; + + fs .resize = true ; + + return fs ; +} + +bool ext3::Create( const Glib::ustring device_path, const Partition & new_partition ) +{ + bool return_value = false ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + PedPartition *c_part = NULL ; + PedFileSystemType *fs_type = NULL ; + PedFileSystem *fs = NULL ; + + c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ; + if ( c_part ) + { + fs_type = ped_file_system_type_get( "ext2" ) ; + if ( fs_type ) + { + fs = ped_file_system_create( & c_part ->geom, fs_type, NULL ); + if ( fs ) + { + if ( ped_partition_set_system(c_part, fs_type ) ) + { + return_value = Commit( disk ) ; + + sleep( 1 ) ; + //system( ("tune2fs -j " + new_partition .partition) .c_str( ) ) ; + Execute_Command( "tune2fs -j " + new_partition .partition ) ; + + } + + ped_file_system_close( fs ); + } + } + } + + close_device_and_disk( device, disk) ; + } + + return return_value ; +} + +bool ext3::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) +{ + bool return_value = false ; + + PedPartition *c_part = NULL ; + PedFileSystem *fs = NULL ; + PedConstraint *constraint = NULL ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ; + if ( c_part ) + { + fs = ped_file_system_open ( & c_part->geom ); + if ( fs ) + { + constraint = ped_file_system_get_resize_constraint ( fs ); + if ( constraint ) + { + if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) && + ped_file_system_resize ( fs, & c_part->geom, NULL ) ) + return_value = Commit( disk ) ; + + ped_constraint_destroy ( constraint ); + } + + ped_file_system_close ( fs ); + } + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +bool ext3::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) +{ + return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ; +} + +int ext3::get_estimated_time( long MB_to_Consider ) +{ + return 1 + MB_to_Consider / 400 ; +} + +} //GParted + diff --git a/src/fat16.cc b/src/fat16.cc new file mode 100644 index 00000000..e0e9659b --- /dev/null +++ b/src/fat16.cc @@ -0,0 +1,117 @@ +/* Copyright (C) 2004 Bart + * + * 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/fat16.h" + +namespace GParted +{ + +FS fat16::get_filesystem_support( ) +{ + FS fs ; + + fs .filesystem = "fat16" ; + fs .create = true ; + fs .resize = true ; + fs .move = true ; + + return fs ; +} + +bool fat16::Create( const Glib::ustring device_path, const Partition & new_partition ) +{ + bool return_value = false ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + PedPartition *c_part = NULL ; + PedFileSystemType *fs_type = NULL ; + PedFileSystem *fs = NULL ; + + c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ; + if ( c_part ) + { + fs_type = ped_file_system_type_get( "fat16" ) ; + if ( fs_type ) + { + fs = ped_file_system_create( & c_part ->geom, fs_type, NULL ); + if ( fs ) + { + if ( ped_partition_set_system(c_part, fs_type ) ) + return_value = Commit( disk ) ; + + ped_file_system_close( fs ); + } + } + } + + close_device_and_disk( device, disk) ; + } + + return return_value ; +} + +bool fat16::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) +{ + bool return_value = false ; + + PedPartition *c_part = NULL ; + PedFileSystem *fs = NULL ; + PedConstraint *constraint = NULL ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ; + if ( c_part ) + { + fs = ped_file_system_open ( & c_part->geom ); + if ( fs ) + { + constraint = ped_file_system_get_resize_constraint ( fs ); + if ( constraint ) + { + if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) && + ped_file_system_resize ( fs, & c_part->geom, NULL ) ) + return_value = Commit( disk ) ; + + ped_constraint_destroy ( constraint ); + } + + ped_file_system_close ( fs ); + } + } + + close_device_and_disk( device, disk) ; + } + + return return_value ; +} + +bool fat16::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) +{ + return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ; +} + +int fat16::get_estimated_time( long MB_to_Consider ) +{ + return 1 ; +} + +} //GParted + + diff --git a/src/fat32.cc b/src/fat32.cc new file mode 100644 index 00000000..928ef87c --- /dev/null +++ b/src/fat32.cc @@ -0,0 +1,118 @@ +/* Copyright (C) 2004 Bart + * + * 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/fat32.h" + +namespace GParted +{ + +FS fat32::get_filesystem_support( ) +{ + FS fs ; + + fs .filesystem = "fat32" ; + fs .create = true ; + fs .resize = true ; + fs .move = true ; + + return fs ; +} + +bool fat32::Create( const Glib::ustring device_path, const Partition & new_partition ) +{ + bool return_value = false ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + PedPartition *c_part = NULL ; + PedFileSystemType *fs_type = NULL ; + PedFileSystem *fs = NULL ; + + c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ; + if ( c_part ) + { + fs_type = ped_file_system_type_get( "fat32" ) ; + if ( fs_type ) + { + fs = ped_file_system_create( & c_part ->geom, fs_type, NULL ); + if ( fs ) + { + if ( ped_partition_set_system(c_part, fs_type ) ) + return_value = Commit( disk ) ; + + ped_file_system_close( fs ); + } + } + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +bool fat32::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) +{ + bool return_value = false ; + + PedPartition *c_part = NULL ; + PedFileSystem *fs = NULL ; + PedConstraint *constraint = NULL ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ; + if ( c_part ) + { + fs = ped_file_system_open ( & c_part->geom ); + if ( fs ) + { + constraint = ped_file_system_get_resize_constraint ( fs ); + if ( constraint ) + { + if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) && + ped_file_system_resize ( fs, & c_part->geom, NULL ) ) + return_value = Commit( disk ) ; + + ped_constraint_destroy ( constraint ); + } + + ped_file_system_close ( fs ); + } + } + + close_device_and_disk( device, disk) ; + } + + return return_value ; +} + +bool fat32::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) +{ + return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ; +} + +int fat32::get_estimated_time( long MB_to_Consider ) +{ + return 1 + MB_to_Consider / 5000 ; +} + + + + +} //GParted diff --git a/src/linux_swap.cc b/src/linux_swap.cc new file mode 100644 index 00000000..4856b330 --- /dev/null +++ b/src/linux_swap.cc @@ -0,0 +1,116 @@ +/* Copyright (C) 2004 Bart + * + * 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/linux_swap.h" + +namespace GParted +{ + +FS linux_swap::get_filesystem_support( ) +{ + FS fs ; + + fs .filesystem = "linux-swap" ; + fs .create = true ; + fs .resize = true ; + fs .move = true ; + + return fs ; +} + +bool linux_swap::Create( const Glib::ustring device_path, const Partition & new_partition ) +{ + bool return_value = false ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + PedPartition *c_part = NULL ; + PedFileSystemType *fs_type = NULL ; + PedFileSystem *fs = NULL ; + + c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ; + if ( c_part ) + { + fs_type = ped_file_system_type_get( "linux-swap" ) ; + if ( fs_type ) + { + fs = ped_file_system_create( & c_part ->geom, fs_type, NULL ); + if ( fs ) + { + if ( ped_partition_set_system(c_part, fs_type ) ) + return_value = Commit( disk ) ; + + ped_file_system_close( fs ); + } + } + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +bool linux_swap::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) +{ + bool return_value = false ; + + PedPartition *c_part = NULL ; + PedFileSystem *fs = NULL ; + PedConstraint *constraint = NULL ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ; + if ( c_part ) + { + fs = ped_file_system_open ( & c_part->geom ); + if ( fs ) + { + constraint = ped_file_system_get_resize_constraint ( fs ); + if ( constraint ) + { + if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) && + ped_file_system_resize ( fs, & c_part->geom, NULL ) ) + return_value = Commit( disk ) ; + + ped_constraint_destroy ( constraint ); + } + + ped_file_system_close ( fs ); + } + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +bool linux_swap::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) +{ + return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ; +} + +int linux_swap::get_estimated_time( long MB_to_Consider ) +{ + return 1 + MB_to_Consider / 5000 ; +} + + +} //GParted diff --git a/src/reiserfs.cc b/src/reiserfs.cc new file mode 100644 index 00000000..75c38985 --- /dev/null +++ b/src/reiserfs.cc @@ -0,0 +1,124 @@ +/* Copyright (C) 2004 Bart + * + * 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/reiserfs.h" + +namespace GParted +{ + +FS reiserfs::get_filesystem_support( ) +{ + FS fs ; + + fs .filesystem = "reiserfs" ; + + static void * test_handle = NULL ; + if ( (test_handle = dlopen("libreiserfs.so", RTLD_NOW)) ) + { + fs .create = true ; + fs .resize = true ; + + dlclose( test_handle ) ; + test_handle = NULL ; + } + + return fs ; +} + +bool reiserfs::Create( const Glib::ustring device_path, const Partition & new_partition ) +{ + bool return_value = false ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + PedPartition *c_part = NULL ; + PedFileSystemType *fs_type = NULL ; + PedFileSystem *fs = NULL ; + + c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ; + if ( c_part ) + { + fs_type = ped_file_system_type_get( "reiserfs" ) ; + if ( fs_type ) + { + fs = ped_file_system_create( & c_part ->geom, fs_type, NULL ); + if ( fs ) + { + if ( ped_partition_set_system(c_part, fs_type ) ) + return_value = Commit( disk ) ; + + ped_file_system_close( fs ); + } + } + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +bool reiserfs::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) +{ + bool return_value = false ; + + PedPartition *c_part = NULL ; + PedFileSystem *fs = NULL ; + PedConstraint *constraint = NULL ; + + if ( open_device_and_disk( device_path, device, disk ) ) + { + c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ; + if ( c_part ) + { + fs = ped_file_system_open ( & c_part->geom ); + if ( fs ) + { + constraint = ped_file_system_get_resize_constraint ( fs ); + if ( constraint ) + { + if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) && + ped_file_system_resize ( fs, & c_part->geom, NULL ) ) + return_value = Commit( disk ) ; + + ped_constraint_destroy ( constraint ); + } + + ped_file_system_close ( fs ); + } + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + +bool reiserfs::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) +{ + return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ; +} + +int reiserfs::get_estimated_time( long MB_to_Consider ) +{ + return 1 + MB_to_Consider / 1000 ; +} + + + +} //GParted