From 8a0ed3b6ac66ad6ebb70408bbb82d82c5841c0b8 Mon Sep 17 00:00:00 2001 From: Bart Hakvoort Date: Tue, 14 Dec 2004 22:49:44 +0000 Subject: [PATCH] added support for jfs (create, copy, grow) and hfs (create, copy) fixed a * added support for jfs (create, copy, grow) and hfs (create, copy) * fixed a bug in copying xfs filesystems. * fixed a number of small bugs/annoying issues. --- ChangeLog | 7 +++ include/FileSystem.h | 1 + include/GParted_Core.h | 4 ++ include/Utils.h | 15 +++--- include/hfs.h | 41 +++++++++++++++ include/jfs.h | 41 +++++++++++++++ include/xfs.h | 2 - src/GParted_Core.cc | 20 +++++++- src/Makefile.am | 2 + src/Win_GParted.cc | 42 ++++++++++------ src/hfs.cc | 95 +++++++++++++++++++++++++++++++++++ src/jfs.cc | 111 +++++++++++++++++++++++++++++++++++++++++ src/ntfs.cc | 9 ++-- src/xfs.cc | 17 +++++-- 14 files changed, 374 insertions(+), 33 deletions(-) create mode 100644 include/hfs.h create mode 100644 include/jfs.h create mode 100644 src/hfs.cc create mode 100644 src/jfs.cc diff --git a/ChangeLog b/ChangeLog index 2c0c8bf9..ddc9144b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-12-14 Bart Hakvoort + + * added support for jfs (create, copy, grow) and hfs (create, copy) + * fixed a bug in copying xfs filesystems. + * fixed a number of small bugs/annoying issues. + * I guess this also means gparted now supports more filesystems then any other (OSS) partitionmanager.. (lekker belangrijk ;) ) + 2004-12-13 Bart Hakvoort * Added support for xfs. this means creating and growing xfs filesystems. Shrinking requires some hacking with dump_xfs etc.. diff --git a/include/FileSystem.h b/include/FileSystem.h index e31da2f8..731d17c1 100644 --- a/include/FileSystem.h +++ b/include/FileSystem.h @@ -24,6 +24,7 @@ #include #include +#include //Some functions used by both (sub)Filesystems and GParted_Core------------------------------------------------- inline bool open_device( const Glib::ustring & device_path, PedDevice *& device ) diff --git a/include/GParted_Core.h b/include/GParted_Core.h index a3f51404..a2531a27 100644 --- a/include/GParted_Core.h +++ b/include/GParted_Core.h @@ -27,6 +27,8 @@ #include "../include/reiserfs.h" #include "../include/ntfs.h" #include "../include/xfs.h" +#include "../include/jfs.h" +#include "../include/hfs.h" #include @@ -82,6 +84,8 @@ private: PedPartition *c_partition ; Glib::ustring temp ; Partition partition_temp ; + + FS fs ; }; } //GParted diff --git a/include/Utils.h b/include/Utils.h index d355474f..b77af5be 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -50,12 +50,13 @@ struct FS bool move ; //startpoint and endpoint bool check ; //some checktool available? bool copy ; + bool grow_only ; //xfs,jfs (only used in Parted_Core::set_device_partitions) int MIN ; int MAX ; FS( ) { - read = create = grow = shrink = move = check = copy = false ; + read = create = grow = shrink = move = check = copy = grow_only = false ; MIN = 0 ; MAX = 0 ; } @@ -134,13 +135,15 @@ inline Glib::ustring Get_Color( const Glib::ustring & filesystem ) //purple something.. else if ( filesystem == "reiserfs" ) return "#ADA7C8" ; - + + //darkyellow else if ( filesystem == "xfs" ) return "#EED680" ; - //libparted can only detect these, i decided to "yellow them" :^) - else if ( filesystem == "HFS" ) return "yellow" ; - else if ( filesystem == "JFS" ) return "yellow" ; - else if ( filesystem == "UFS" ) return "yellow" ; + else if ( filesystem == "jfs" ) return "#E0C39E" ; + + else if ( filesystem == "hfs" ) return "#E0B6AF" ; + + else if ( filesystem == "ufs" ) return "#D1940C" ; //darkgrey and ligthblue else if ( filesystem == "---" ) return "darkgrey"; diff --git a/include/hfs.h b/include/hfs.h new file mode 100644 index 00000000..174cb88c --- /dev/null +++ b/include/hfs.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 HFS +#define HFS + +#include "../include/FileSystem.h" + +namespace GParted +{ + +class hfs : public FileSystem +{ +public: + FS get_filesystem_support( ) ; + void Set_Used_Sectors( Partition & partition ) ; + bool Create( const Glib::ustring device_path, const Partition & new_partition ) ; + bool Resize( const Partition & partition_new, bool fill_partition = false ) ; + bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ; + bool Check_Repair( const Partition & partition ) ; + int get_estimated_time( long MB_to_Consider ) ; +}; + +} //GParted + +#endif //HFS diff --git a/include/jfs.h b/include/jfs.h new file mode 100644 index 00000000..cc22f38e --- /dev/null +++ b/include/jfs.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 JFS +#define JFS + +#include "../include/FileSystem.h" + +namespace GParted +{ + +class jfs : public FileSystem +{ +public: + FS get_filesystem_support( ) ; + void Set_Used_Sectors( Partition & partition ) ; + bool Create( const Glib::ustring device_path, const Partition & new_partition ) ; + bool Resize( const Partition & partition_new, bool fill_partition = false ) ; + bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ; + bool Check_Repair( const Partition & partition ) ; + int get_estimated_time( long MB_to_Consider ) ; +}; + +} //GParted + +#endif //JFS diff --git a/include/xfs.h b/include/xfs.h index a01028c6..c1b763de 100644 --- a/include/xfs.h +++ b/include/xfs.h @@ -21,8 +21,6 @@ #include "../include/FileSystem.h" -#include - namespace GParted { diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc index b9722a77..3ca9dd68 100644 --- a/src/GParted_Core.cc +++ b/src/GParted_Core.cc @@ -33,6 +33,12 @@ void GParted_Core::find_supported_filesystems( ) fat32 fs_fat32; FILESYSTEMS .push_back( fs_fat32 .get_filesystem_support( ) ) ; + hfs fs_hfs; + FILESYSTEMS .push_back( fs_hfs .get_filesystem_support( ) ) ; + + jfs fs_jfs; + FILESYSTEMS .push_back( fs_jfs .get_filesystem_support( ) ) ; + linux_swap fs_linux_swap; FILESYSTEMS .push_back( fs_linux_swap .get_filesystem_support( ) ) ; @@ -176,8 +182,14 @@ void GParted_Core::set_device_partitions( Device & device, bool deep_scan ) if ( partition_temp .sectors_used == -1 && partition_temp .error .empty( ) ) { partition_temp .error = _("Unable to read the contents of this filesystem!") ; - partition_temp .error += "\n" ; - partition_temp .error += ("As a result you won't be able to resize this partition.") ; + + fs = Get_FS( partition_temp .filesystem, FILESYSTEMS ) ; + + if ( ! fs .grow_only ) + { + partition_temp .error += "\n" ; + partition_temp .error += ("As a result you won't be able to resize this partition.") ; + } } } @@ -704,6 +716,10 @@ void GParted_Core::set_proper_filesystem( const Glib::ustring & filesystem ) p_filesystem = new fat16( ) ; else if ( filesystem == "fat32" ) p_filesystem = new fat32( ) ; + else if ( filesystem == "hfs" ) + p_filesystem = new hfs( ) ; + else if ( filesystem == "jfs" ) + p_filesystem = new jfs( ) ; else if ( filesystem == "linux-swap" ) p_filesystem = new linux_swap( ) ; else if ( filesystem == "reiserfs" ) diff --git a/src/Makefile.am b/src/Makefile.am index a28e2c8b..9b1390ac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,6 +35,8 @@ gparted_SOURCES = \ ext3.cc\ fat16.cc\ fat32.cc\ + hfs.cc\ + jfs.cc\ linux_swap.cc\ main.cc\ ntfs.cc\ diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc index 9ff2102b..95a3896c 100644 --- a/src/Win_GParted.cc +++ b/src/Win_GParted.cc @@ -602,11 +602,37 @@ void Win_GParted::Set_Valid_Operations() return ; } + //EXTENDED + else if ( selected_partition .type == GParted::EXTENDED ) + { + if ( ! any_logic ) //deletion is only allowed when there are nog logical partitions inside. + allow_delete( true ) ; + + if ( ! devices[ current_device ] .readonly ) + allow_resize( true ); + + return ; + } + + fs = Get_FS( selected_partition .filesystem, gparted_core .get_fs( ) ) ; + + //FIXME too much redundacy here (just not in the mood to fix it now :P ) //if there was an error reading the filesystem we allow delete and convert ( see also Device::Get_Used_Sectors() ) - if ( selected_partition .error != "" ) + //since growing doesn't affect the space already in use, we allow resinzing of 'grow-only' filesystems + if ( ! selected_partition .error .empty( ) ) { allow_delete( true ) ; allow_convert( true ) ; + + if ( fs .grow && ! fs .shrink && ! devices[ current_device ] .readonly ) + { + allow_resize( true ); + + //only allow copying of real partitions + if ( selected_partition .status != GParted::STAT_NEW && selected_partition .status != GParted::STAT_COPY && fs .copy ) + allow_copy( true ) ; + } + return; } @@ -617,7 +643,6 @@ void Win_GParted::Set_Valid_Operations() allow_convert( true ) ; //find out if resizing/moving and copying is possible - fs = Get_FS( selected_partition .filesystem, gparted_core .get_fs( ) ) ; if ( (fs .grow || fs .shrink) && ! devices[ current_device ] .readonly ) { allow_resize( true ) ; @@ -629,18 +654,6 @@ void Win_GParted::Set_Valid_Operations() return ; } - - - //EXTENDED - else if ( selected_partition .type == GParted::EXTENDED ) - { - if ( ! any_logic ) //deletion is only allowed when there are nog logical partitions inside. - allow_delete( true ) ; - - if ( ! devices[ current_device ] .readonly ) - allow_resize( true ); - } - } void Win_GParted::Set_Valid_Convert_Filesystems() @@ -922,6 +935,7 @@ void Win_GParted::activate_paste() if ( ! max_amount_prim_reached( ) ) { Dialog_Partition_Copy dialog( gparted_core .get_fs( ) ) ; + copied_partition .error .clear( ) ; //we don't need the errors of the source partition. dialog .Set_Data( selected_partition, copied_partition ) ; dialog .set_transient_for( *this ); diff --git a/src/hfs.cc b/src/hfs.cc new file mode 100644 index 00000000..c34c8fcf --- /dev/null +++ b/src/hfs.cc @@ -0,0 +1,95 @@ +/* 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/hfs.h" + +namespace GParted +{ + +FS hfs::get_filesystem_support( ) +{ + FS fs ; + + fs .filesystem = "hfs" ; + if ( ! system( "which hfs 1>/dev/null 2>/dev/null" ) ) + fs .read = true ; + + if ( ! system( "which hformat 1>/dev/null 2>/dev/null" ) ) + fs .create = true ; + + if ( ! system( "which dd 1>/dev/null 2>/dev/null" ) ) + fs .copy = true ; + + fs .MAX = 2048 ; + + return fs ; +} + +void hfs::Set_Used_Sectors( Partition & partition ) +{ + char c_buf[ 512 ] ; + FILE *f ; + + Glib::ustring output ; + + //get free bytes.. + f = popen( ( "LANG=C echo 'quit' | hfs " + partition .partition ) .c_str( ), "r" ) ; + while ( fgets( c_buf, 512, f ) ) + { + output = Glib::locale_to_utf8( c_buf ) ; + + if ( output .find( "bytes free" ) < output .length( ) ) + { + output = output .substr( 0, output .find( " bytes free" ) ) ; + + partition .Set_Unused( atoi( (output .substr( output .find_last_of( ' ' ) ) ) .c_str( ) ) / 512 ) ; + break ; + } + } + pclose( f ) ; +} + +bool hfs::Create( const Glib::ustring device_path, const Partition & new_partition ) +{ + return ! Execute_Command( "hformat " + new_partition .partition ) ; +} + +bool hfs::Resize( const Partition & partition_new, bool fill_partition ) +{ + return true ; +} + +bool hfs::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 ) ; +} + +bool hfs::Check_Repair( const Partition & partition ) +{ + return true ; +} + +int hfs::get_estimated_time( long MB_to_Consider ) +{ + return -1 ; +} + + +} //GParted + + diff --git a/src/jfs.cc b/src/jfs.cc new file mode 100644 index 00000000..6a50a8d7 --- /dev/null +++ b/src/jfs.cc @@ -0,0 +1,111 @@ +/* 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/jfs.h" + +namespace GParted +{ + +FS jfs::get_filesystem_support( ) +{ + FS fs ; + + fs .filesystem = "jfs" ; + fs .grow_only = true ; + +// if ( ! system( "which xfs_db 1>/dev/null 2>/dev/null" ) ) +// fs .read = true ; + + if ( ! system( "which mkfs.jfs 1>/dev/null 2>/dev/null" ) ) + fs .create = true ; + + if ( ! system( "which jfs_fsck 1>/dev/null 2>/dev/null" ) ) + fs .check = true ; + + //resizing of jfs requires mount, umount and jfs support in the kernel + if ( ! system( "which mount umount 1>/dev/null 2>/dev/null" ) ) + { + Glib::ustring line ; + std::ifstream input( "/proc/filesystems" ) ; + while ( input >> line ) + if ( line == "jfs" ) + { + fs .grow = true ; + break ; + } + + input .close( ) ; + } + + if ( ! system( "which dd 1>/dev/null 2>/dev/null" ) && fs .grow) + fs .copy = true ; + + fs .MIN = 16 ; + + return fs ; +} + +void jfs::Set_Used_Sectors( Partition & partition ) +{ +} + +bool jfs::Create( const Glib::ustring device_path, const Partition & new_partition ) +{ + return ! Execute_Command( "mkfs.jfs -q " + new_partition .partition ) ; +} + +bool jfs::Resize( const Partition & partition_new, bool fill_partition ) +{ + bool return_value = false ; + + //jfs kan only grow if the partition is mounted.. + system( "mkdir /tmp/gparted_tmp_jfs_mountpoint" ) ; + if ( ! Execute_Command( "mount " + partition_new .partition + " /tmp/gparted_tmp_jfs_mountpoint" ) ) + { + return_value = ! Execute_Command( "mount -o remount,resize /tmp/gparted_tmp_jfs_mountpoint" ) ; + Execute_Command( "umount " + partition_new .partition ) ; + } + system( "rmdir /tmp/gparted_tmp_jfs_mountpoint" ) ; + + return return_value ; +} + +bool jfs::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) +{ + if ( ! Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ) + { + Partition partition ; + partition .partition = dest_part_path ; + return Resize( partition, true ) ; + } +} + +bool jfs::Check_Repair( const Partition & partition ) +{ + return Execute_Command( "jfs_fsck -f " + partition .partition ) <= 1 ; +} + +int jfs::get_estimated_time( long MB_to_Consider ) +{ + return -1 ; +} + + +} //GParted + + diff --git a/src/ntfs.cc b/src/ntfs.cc index 405ac437..471b5ca7 100644 --- a/src/ntfs.cc +++ b/src/ntfs.cc @@ -52,7 +52,6 @@ void ntfs::Set_Used_Sectors( Partition & partition ) FILE *f ; Glib::ustring output ; - Sector free_sectors = -1 ; //get free sectors.. f = popen( ( "LANG=C ntfscluster --force " + partition .partition ) .c_str( ), "r" ) ; @@ -62,12 +61,12 @@ void ntfs::Set_Used_Sectors( Partition & partition ) //free sectors if ( output .find( "sectors of free space" ) < output .length( ) ) - free_sectors = atoi( (output .substr( output .find( ":" ) +1, output .length( ) ) ) .c_str( ) ) ; + { + partition .Set_Unused( atoi( (output .substr( output .find( ":" ) +1, output .length( ) ) ) .c_str( ) ) ) ; + break ; + } } pclose( f ) ; - - if ( free_sectors > -1 ) - partition .Set_Unused( free_sectors ) ; } bool ntfs::Create( const Glib::ustring device_path, const Partition & new_partition ) diff --git a/src/xfs.cc b/src/xfs.cc index 6c0bc30c..88fce1d4 100644 --- a/src/xfs.cc +++ b/src/xfs.cc @@ -26,6 +26,8 @@ FS xfs::get_filesystem_support( ) FS fs ; fs .filesystem = "xfs" ; + fs .grow_only = true ; + if ( ! system( "which xfs_db 1>/dev/null 2>/dev/null" ) ) fs .read = true ; @@ -35,8 +37,8 @@ FS xfs::get_filesystem_support( ) if ( ! system( "which xfs_repair 1>/dev/null 2>/dev/null" ) ) fs .check = true ; - //resizing of xfs requires xfs_db, xfs_growfs, xfs_repair, mount, umount and xfs support in the kernel - if ( ! system( "which xfs_growfs mount umount 1>/dev/null 2>/dev/null" ) && fs .read && fs .check ) + //resizing of xfs requires xfs_growfs, xfs_repair, mount, umount and xfs support in the kernel + if ( ! system( "which xfs_growfs mount umount 1>/dev/null 2>/dev/null" ) && fs .check ) { Glib::ustring line ; std::ifstream input( "/proc/filesystems" ) ; @@ -50,7 +52,7 @@ FS xfs::get_filesystem_support( ) input .close( ) ; } - if ( ! system( "which dd 1>/dev/null 2>/dev/null" ) ) + if ( ! system( "which dd 1>/dev/null 2>/dev/null" ) && fs .grow ) fs .copy = true ; fs .MIN = 32 ;//official minsize = 16MB, but the smallest xfs_repair can handle is 32MB... @@ -110,7 +112,14 @@ bool xfs::Resize( const Partition & partition_new, bool fill_partition ) bool xfs::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 ) ; + if ( ! Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ) + { + Partition partition ; + partition .partition = dest_part_path ; + return Resize( partition, true ) ; + } + + return false ; } bool xfs::Check_Repair( const Partition & partition )