diff options
Diffstat (limited to 'perl-install/diskdrake')
| -rw-r--r-- | perl-install/diskdrake/dav.pm | 23 | ||||
| -rw-r--r-- | perl-install/diskdrake/diskdrake.html | 139 | ||||
| -rw-r--r-- | perl-install/diskdrake/hd_gtk.pm | 234 | ||||
| -rw-r--r-- | perl-install/diskdrake/interactive.pm | 446 | ||||
| -rw-r--r-- | perl-install/diskdrake/removable.pm | 2 | ||||
| -rw-r--r-- | perl-install/diskdrake/resize_ext2.pm | 2 | ||||
| -rw-r--r-- | perl-install/diskdrake/resize_ntfs.pm | 10 | ||||
| -rw-r--r-- | perl-install/diskdrake/smbnfs_gtk.pm | 36 |
8 files changed, 493 insertions, 399 deletions
diff --git a/perl-install/diskdrake/dav.pm b/perl-install/diskdrake/dav.pm index 4950b2bb0..9036596b3 100644 --- a/perl-install/diskdrake/dav.pm +++ b/perl-install/diskdrake/dav.pm @@ -1,4 +1,4 @@ -package diskdrake::dav; # $Id$ +package diskdrake::dav; use diagnostics; use strict; @@ -33,10 +33,11 @@ points, select \"New\".")) }, sub create { my ($in, $all_hds) = @_; - my $dav = { fs_type => 'davfs2' }; + my $dav = { fs_type => 'davfs2', mntpoint => 'none' }; ask_server($in, $dav, $all_hds) or return; push @{$all_hds->{davs}}, $dav; config($in, $dav, $all_hds); + return; } sub config { @@ -45,11 +46,12 @@ sub config { my $dav = { %$dav_ }; #- working on a local copy so that "Cancel" works my $action; - while ($action ne 'Done') { + my $exit; + while (!$exit && $action ne 'Done') { my %actions = my @actions = actions($dav); $action = $in->ask_from_list_('', format_dav_info($dav), [ map { $_->[0] } group_by2 @actions ], 'Done') or return; - $actions{$action}->($in, $dav, $all_hds); + $exit = $actions{$action}->($in, $dav, $all_hds); } %$dav_ = %$dav; #- applying } @@ -63,6 +65,7 @@ sub actions { N_("Server") => \&ask_server, N_("Mount point") => \&mount_point, N_("Options") => \&options, + N_("Remove") => \&remove, N_("Done") => sub {}, ); } @@ -95,11 +98,23 @@ sub ask_server { sub options { my ($in, $dav, $all_hds) = @_; diskdrake::interactive::Options($in, {}, $dav, $all_hds); + return; } + +sub remove { + my ($in, $dav, $all_hds) = @_; + if ($in->ask_yesorno(N("Warning"), N("Are you sure you want to delete this mount point?"))) { + @{$all_hds->{davs}} = grep { $_->{mntpoint} ne $dav->{mntpoint} } @{$all_hds->{davs}}; + return 1; + } + return; +} + sub mount_point { my ($in, $dav, $all_hds) = @_; my $proposition = $dav->{device} =~ /(\w+)/ ? "/mnt/$1" : "/mnt/dav"; diskdrake::interactive::Mount_point_raw_hd($in, $dav, $all_hds, $proposition); + return; } sub format_dav_info { diff --git a/perl-install/diskdrake/diskdrake.html b/perl-install/diskdrake/diskdrake.html deleted file mode 100644 index cba732084..000000000 --- a/perl-install/diskdrake/diskdrake.html +++ /dev/null @@ -1,139 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> - <head> - <title>DiskDrake</title> - </head> - <body bgcolor="#ffffff"> - -<center> -<table width=80% border=0 cellpadding=10 cellspacing=10> -<tr> -<td bgcolor=#ffffff> - - <p> - <img src="images/diskdrake1-def.jpg" alt="diskdrake logo" width=400 height=100> - <p> - - <H2>I- What's it?</H2> - - The purpose of the DiskDrake project is to make easier the hard disk - partitionning. It is graphical, simple and powerful. The license is - the GPL (General Public License). - <BR> - Different skill levels will be available (newbie, advanced user, expert). - <BR> - It's written entirely in Perl and Perl/Gtk. It uses resize_fat which is - a perl rewrite of the work of Andrew Clausen (libresize). - <P> - DiskDrake is a project from Mandrakesoft, the company behind the popular - <a href="http://www.linux-mandrake.com">Linux-Mandrake</a> - operating-system. - <P> - A <A href="http://www.eatel.net/~john/diskdrake/faq.html">FAQ</A> is in construction. - - <H2>II - What's available now</H2> - - DiskDrake should be usable now... - - it can: - <UL> - <LI> create partitions - <LI> delete partitions - <LI> change type of partition - <LI> format partitions - <LI> assign a mount point (<IMG SRC="/images/updated.gif" ALT="updated"><SMALL>(21/07/99)</SMALL> propose a list - of classic mount points and verify the mount point is valid) - <LI> mount partitions - <LI> resize fat partitions - <LI> resize partitions (when not caring loosing its data) - <LI> clear partition table - <LI> auto allocation (usefull for install) - <LI> write fstab - </UL> - -with nice contextual menu (shortcuts available, but dangerous as all actions are -available, whereas with the contextual menu these actions are hidden. This will -change) - - <P><IMG SRC="/images/updated.gif" ALT="updated"><SMALL>(25/07/99)</SMALL> - A new Expert button appear now. It toggles between - expert and normal mode. Some changes in information displayed: - <UL> - <LI> when you click (or focus) the drive tab (eg: hda), you get - information about your drive: size, geometry - (cylinders/sectors/heads number), type (eg: IBM DDRS-39130D), and bus/id. - In normal mode you have only the size. - <LI> the windows drive letter (eg: C: D: ...) - <LI> the `start sector' information from normal mode, it still appears in - expert mode - <LI> the start&end cylinder of each partition is now displayed in expert - mode - <LI> the type is displayed numerically in expert mode - </UL> - - <P><IMG SRC="/images/updated.gif" ALT="updated"><SMALL>(25/07/99)</SMALL> - The mount point in the `Create' window and `Change type' window is now a - combo box. It lets you choose between classical mount points (/ /usr /var - ...) but with already allocated mount points removed. - - <H2>III - Actual developpment</H2> - - We need people!!! - - <UL> - <LI><B>Tests</B> and remove bugs (no known yet :) - <LI>integrate ext2resize (which has been release in version 1.0.0 <IMG - SRC="/images/updated.gif" ALT="updated"><SMALL>(26/07/99)</SMALL>) - <LI>add possibility to move partition without loosing data (by copying all - data) <IMG SRC="/images/updated.gif" ALT="updated"> - <LI>Improve the look - <LI>Add a text-only version - <LI>Help text, tutorial... - <LI>Internationalization - <LI>Add some features... - <LI>Packaging (rpm, deb, slp...) - </UL> - - <H2>IV- ScreenShot</H2> - - Warning: features was the main focus, so don't be too hard :) - - <P> - <CENTER><IMG SRC="1.gif"></IMG></CENTER> - <CENTER>DiskDrake main interface</CENTER> - - <BR> - <CENTER><IMG SRC="3.gif"></IMG></CENTER> - <CENTER>create dialog box</CENTER> - - <H2>V - Contacts</H2> - - A Mailing List has been created to allow developpers to discuss about DiskDrake.<BR> - - <P> - Send a mail to: <A HREF="mailto:sympa@linux-mandrake.com">sympa@linux-mandrake.com</A> - - <BR>Put in the subject: subscribe diskdrake - <BR>When you're subscribed, send your messages to: <A HREF="mailto:diskdrake@linux-mandrake.com">diskdrake@linux-mandrake.com</A> - - <P>Otherwise you can contact directly the <A HREF="mailto:pixel@linux-mandrake.com">project leader</A>. - - <H2>VI - Download</H2> - - Warning: You must have <a href="http://www.perl.com/CPAN/modules/by-module/Gtk/Gtk-Perl-0.5121.tar.gz">Gtk-Perl</a>. - You can get the rpm from the <a href="http://linux-mandrake.com/cooker/">Cooker</a> distribution. - - <P>You also need perl version 5.00503 or better - - <P> Here you can find the plain tgz or a rpm: - <a href="ftp://ftp.phys.ttu.edu/pub/mandrake-devel/contrib/others/diskdrake/">diskdrake</a> (Other mirrors in <a href="http://linux-mandrake.com/cooker/">Cooker</a>) - -</td> -</tr> -</table> -<p> -<a href="/en/fpowerpack.php3"><img src="/images/mandrake6.0-loop.gif" width=468 height=60 alt="Mandrake 6.0 PowerPack"></a> -</center> - </body> - <address><a href="mailto:pixel@linux-mandrake.com"></a></address> -</html> diff --git a/perl-install/diskdrake/hd_gtk.pm b/perl-install/diskdrake/hd_gtk.pm index b52d3f98f..ed3955ea7 100644 --- a/perl-install/diskdrake/hd_gtk.pm +++ b/perl-install/diskdrake/hd_gtk.pm @@ -1,11 +1,11 @@ -package diskdrake::hd_gtk; # $Id$ +package diskdrake::hd_gtk; use diagnostics; use strict; use common; -use mygtk2 qw(gtknew); -use ugtk2 qw(:helpers :wrappers :create); +use mygtk3 qw(gtknew); +use ugtk3 qw(:helpers :wrappers :create); use partition_table; use fs::type; use detect_devices; @@ -16,21 +16,19 @@ use log; use fsedit; use feature qw(state); -my ($width, $height, $minwidth) = (400, 50, 5); +my ($width, $height, $minwidth) = (400, 50, 16); my ($all_hds, $in, $do_force_reload, $current_kind, $current_entry, $update_all); my ($w, @notebook, $done_button); -=begin - =head1 SYNOPSYS -struct { + struct { string name # which is displayed in tab of the notebook bool no_auto # wether the kind can disappear after creation - string type # one of { 'hd', 'raid', 'lvm', 'loopback', 'removable', 'nfs', 'smb' } + string type # one of { 'hd', 'raid', 'lvm', 'loopback', 'removable', 'nfs', 'smb', 'dmcrypt' } hd | hd_lvm | part_raid[] | part_dmcrypt[] | part_loopback[] | raw_hd[] val - + # widget main_box widget display_box @@ -38,12 +36,21 @@ struct { widget info_box } current_kind -part current_entry + part current_entry -notebook current_kind[] + notebook current_kind[] =cut +sub load_theme() { + my $css = "/usr/share/libDrakX/diskdrake.css"; + -r $css or $css = dirname(__FILE__) . "/../diskdrake.css"; + -r $css or $css = dirname(__FILE__) . "/../share/diskdrake.css"; + my $pl = Gtk3::CssProvider->new; + $pl->load_from_path($css); + Gtk3::StyleContext::add_provider_for_screen(Gtk3::Gdk::Screen::get_default(), $pl, Gtk3::STYLE_PROVIDER_PRIORITY_APPLICATION); +} + sub main { ($in, $all_hds, $do_force_reload) = @_; @@ -51,33 +58,32 @@ sub main { local $in->{grab} = 1; - $w = ugtk2->new(N("Partitioning")); - $::main_window = $w->{real_window} if !$::isEmbedded && !$::isInstall; - my $rc = "/usr/share/libDrakX/diskdrake.rc"; - -r $rc or $rc = dirname(__FILE__) . "/../diskdrake.rc"; - -r $rc or $rc = dirname(__FILE__) . "/../share/diskdrake.rc"; - Gtk2::Rc->parse($rc); + $w = ugtk3->new(N("Partitioning")); + mygtk3::register_main_window($w->{real_window}) if !$::isEmbedded && !$::isInstall; + + load_theme(); + $w->{window}->signal_connect('style-updated' => \&load_theme); # TODO # is_empty_array_ref($all_hds->{raids}) or raid::stopAll; # updateLoopback(); gtkadd($w->{window}, - gtkpack_(Gtk2::VBox->new(0,7), + gtkpack_(Gtk3::VBox->new(0,7), 0, gtknew(($::isInstall ? ('Title1', 'label') : ('Label_Left', 'text')) => N("Click on a partition, choose a filesystem type then choose an action"), # workaround infamous 6 years old gnome bug #101968: - width => mygtk2::get_label_width() + width => mygtk3::get_label_width() ), - 1, (my $notebook_widget = Gtk2::Notebook->new), + 1, (my $notebook_widget = Gtk3::Notebook->new), 0, (my $per_kind_action_box = gtknew('HButtonBox', layout => 'edge')), - 0, (my $per_kind_action_box2 = gtknew('HButtonBox', layout => 'end')), - 0, Gtk2::HSeparator->new, + 0, Gtk3::HSeparator->new, 0, (my $general_action_box = gtknew('HBox', spacing => 5)), ), ); my ($lock, $initializing) = (undef, 1); $update_all = sub { + my ($o_refresh_gui) = @_; state $not_first; return if $initializing && $not_first; $not_first = 1; @@ -86,10 +92,15 @@ sub main { partition_table::assign_device_numbers($_) foreach fs::get::hds($all_hds); create_automatic_notebooks($notebook_widget); general_action_box($general_action_box); - per_kind_action_box($per_kind_action_box, $per_kind_action_box2, $current_kind); + per_kind_action_box($per_kind_action_box, $current_kind); current_kind_changed($in, $current_kind); current_entry_changed($current_kind, $current_entry); $lock = 0; + if ($o_refresh_gui) { + my $new_page = $o_refresh_gui > 1 ? $notebook_widget->get_current_page : 0; + $notebook_widget->set_current_page(-1); + $notebook_widget->set_current_page($new_page); + } }; create_automatic_notebooks($notebook_widget); @@ -98,15 +109,33 @@ sub main { $current_entry = ''; $update_all->(); }); - # ensure partitions bar is properlyz size on first display: + # ensure partitions bar is properly sized on first display: $notebook_widget->signal_connect(realize => $update_all); $w->sync; + # add a bogus tab so that gtk+ displayed everything when there's only one disk: + $notebook_widget->prepend_page(Gtk3::Label->new, Gtk3::Label->new); + $notebook_widget->set_current_page(0); + # there's always at least one child (at least a button for create a new part on empty discs): + my @children = $current_kind->{display_box} ? $current_kind->{display_box}->get_children : (); + # workaround for $notebook_widget being realized too early: + if (!@children ||!$done_button) { + $notebook_widget->set_current_page(-1); + $notebook_widget->set_current_page(0); + undef $initializing; + $update_all->(2); + } + undef $initializing; + # remove bogus tab we added just to be sure gtk+ displayed everything: + $notebook_widget->remove_page(0); + # restore position when there's several disks: + $notebook_widget->set_current_page(0); $done_button->grab_focus; - $in->ask_from_list_(N("Read carefully"), N("Please make a backup of your data first"), - [ N_("Exit"), N_("Continue") ], N_("Continue")) eq N_("Continue") or return - if $::isStandalone; + if (!$::testing) { + $in->ask_from_list_(N("Read carefully"), N("Please make a backup of your data first"), + [ N_("Exit"), N_("Continue") ], N_("Continue")) eq N_("Continue") or return + if $::isStandalone; + } - undef $initializing; $w->main; } @@ -118,18 +147,29 @@ sub try { sub try_ { my ($name, $f, @args) = @_; + my $dm_active_before = ($current_entry && $current_entry->{dm_active} && $current_entry->{dm_name}); my $v = eval { $f->($in, @args, $all_hds) }; if (my $err = $@) { + warn $err, "\n", backtrace() if $in->isa('interactive::gtk'); $in->ask_warn(N("Error"), formatError($err)); } + my $refresh = 0; if ($v eq 'force_reload') { $all_hds = $do_force_reload->(); + $refresh = 1; } - $current_entry = '' if !diskdrake::interactive::is_part_existing($current_entry, $all_hds); - $update_all->(); + if (!diskdrake::interactive::is_part_existing($current_entry, $all_hds)) { + $current_entry = ''; + } elsif (!$dm_active_before && $current_entry->{dm_active} && $current_entry->{dm_name}) { + if (my $mapped_part = fs::get::device2part("mapper/$current_entry->{dm_name}", $all_hds->{dmcrypts})) { + $current_entry = $mapped_part; + $refresh = 2; + } + } + $update_all->($refresh); - Gtk2->main_quit if $v && member($name, 'Done'); + Gtk3->main_quit if $v && member($name, 'Done'); } sub get_action_box_size() { @@ -143,27 +183,26 @@ sub add_kind2notebook { my ($notebook_widget, $kind) = @_; die if $kind->{main_box}; - $kind->{display_box} = gtkset_size_request(Gtk2::HBox->new(0,0), $width, $height); - $kind->{action_box} = gtkset_size_request(Gtk2::VBox->new(), get_action_box_size()); - $kind->{info_box} = Gtk2::VBox->new(0,0); + $kind->{display_box} = gtkset_size_request(Gtk3::HBox->new(0,0), $width, $height); + $kind->{action_box} = gtkset_size_request(Gtk3::VBox->new, get_action_box_size()); + $kind->{info_box} = Gtk3::VBox->new(0,0); my $box = - gtkpack_(Gtk2::VBox->new(0,7), - 0, $kind->{display_box}, + gtkpack_(Gtk3::VBox->new(0,7), + 0, create_scrolled_window($kind->{display_box}, [ 'automatic', 'never' ]), 0, filesystems_button_box(), 1, $kind->{info_box}); $kind->{main_box} = gtknew('HBox', spacing => 5, children => [ 1, $box, 0, $kind->{action_box}, ]); - ugtk2::add2notebook($notebook_widget, $kind->{name}, $kind->{main_box}); + ugtk3::add2notebook($notebook_widget, $kind->{name}, $kind->{main_box}); push @notebook, $kind; $kind; } sub interactive_help() { if ($::isInstall) { - my $func = $in->interactive_help_sub_display_id('diskdrake'); - $func and $func->(); + $in->display_help({ interactive_help_id => 'diskdrake' }); } else { require run_program; run_program::raw({ detach => 1 }, 'drakhelp', '--id', 'diskdrake'); @@ -183,28 +222,25 @@ sub general_action_box { N_("Done")); my $box_end = gtknew('HButtonBox', layout => 'end', spacing => 5); foreach my $s (@actions) { - my $button = Gtk2::Button->new(translate($s)); + my $button = Gtk3::Button->new(translate($s)); $done_button = $button if $s eq 'Done'; gtkadd($box_end, gtksignal_connect($button, clicked => sub { try($s) })); } gtkadd($box, $box_start, $box_end); } sub per_kind_action_box { - my ($box, $box2, $kind) = @_; - $_->destroy foreach $box->get_children, $box2->get_children; - - $kind->{type} =~ /hd|lvm/ or return; + my ($box, $kind) = @_; + $_->destroy foreach $box->get_children; - foreach my $s (diskdrake::interactive::hd_possible_actions_base($in, kind2hd($kind), $all_hds)) { + my @actions = (if_($kind->{type} =~ /hd|lvm/, diskdrake::interactive::hd_possible_actions_base($in)), + diskdrake::interactive::hd_possible_actions_extra($in)); + foreach my $s (@actions) { gtkadd($box, - gtksignal_connect(Gtk2::Button->new(translate($s)), - clicked => sub { try($s, kind2hd($kind)) })); - } - foreach my $s (diskdrake::interactive::hd_possible_actions_extra($in, kind2hd($kind), $all_hds)) { - gtkadd($box2, - gtksignal_connect(Gtk2::Button->new(translate($s)), + gtksignal_connect(Gtk3::Button->new(translate($s)), clicked => sub { try($s, kind2hd($kind)) })); } + # make sure a big translations window to resize (as by default all buttons have the same size): + $box->set_child_non_homogeneous($_, Glib::TRUE), "\n" foreach $box->get_children; } sub per_entry_action_box { my ($box, $kind, $entry) = @_; @@ -213,18 +249,18 @@ sub per_entry_action_box { if ($entry) { my @buttons = map { my $s = $_; - my $w = Gtk2::Button->new(translate($s)); + my $w = Gtk3::Button->new(translate($s)); $w->signal_connect(clicked => sub { try($s, kind2hd($kind), $entry) }); $w; } diskdrake::interactive::part_possible_actions($in, kind2hd($kind), $entry, $all_hds); - gtkadd($box, create_scrolled_window(gtkpack__(Gtk2::VBox->new(), @buttons), undef, 'none')) if @buttons; + gtkadd($box, create_scrolled_window(gtkpack__(Gtk3::VBox->new, @buttons), undef, 'none')) if @buttons; } else { my $txt = !$::isStandalone && fsedit::is_one_big_fat_or_NT($all_hds->{hds}) ? N("You have one big Microsoft Windows partition. I suggest you first resize that partition (click on it, then click on \"Resize\")") : N("Please click on a partition"); - gtkpack($box, gtktext_insert(Gtk2::TextView->new, $txt)); + gtkpack($box, gtktext_insert(Gtk3::TextView->new, $txt)); } } @@ -239,21 +275,16 @@ sub per_entry_info_box { } gtkpack($box, gtkadd(gtkcreate_frame(N("Details")), gtknew('HBox', border_width => 5, children_loose => [ - gtkset_alignment(gtkset_justify(Gtk2::Label->new($info), 'left'), 0, 0) ]))); + gtkset_alignment(gtkset_justify(gtknew('Label', selectable => 1, text => $info), 'left'), 0, 0) ]))); } sub current_kind_changed { my ($_in, $kind) = @_; + return if !$kind->{display_box}; $_->destroy foreach $kind->{display_box}->get_children; - - my $v = $kind->{val}; - my @parts = - $kind->{type} eq 'raid' ? grep { $_ } @$v : - $kind->{type} eq 'dmcrypt' ? @$v : - $kind->{type} eq 'loopback' ? @$v : fs::get::hds_fstab_and_holes($v); - my $totalsectors = - $kind->{type} =~ /raid|dmcrypt|loopback/ ? sum(map { $_->{size} } @parts) : $v->{totalsectors}; + my @parts = kind2parts($kind); + my $totalsectors = kind2sectors($kind, @parts); create_buttons4partitions($kind, $totalsectors, @parts); } @@ -280,26 +311,39 @@ sub create_automatic_notebooks { $may_add->(hd2kind($_)) foreach @{$all_hds->{hds}}; $may_add->(lvm2kind($_)) foreach @{$all_hds->{lvms}}; $may_add->(raid2kind()) if @{$all_hds->{raids}}; - $may_add->(dmcrypt2kind()) if @{$all_hds->{dmcrypts}}; $may_add->(loopback2kind()) if @{$all_hds->{loopbacks}}; - @notebook = grep_index { - my $b = $_->{marked} or $notebook_widget->remove_page($::i); - $b; + my $i = 0; + @notebook = grep { + if ($_->{marked}) { + $i++; + 1; + } else { + $notebook_widget->remove_page($i); + 0; + } } @notebook; - @notebook or $in->ask_warn(N("Error"), N("No hard drives found")), $in->exit(1); + @notebook or $in->ask_warn(N("Error"), N("No hard disk drives found")), $in->exit(1); } ################################################################################ # parts: helpers ################################################################################ sub create_buttons4partitions { - my ($kind, $totalsectors, @parts) = @_; + my ($kind, $totalsectors, @all_parts) = @_; + + if ($w->{window}->get_window) { + my $windowwidth = $w->{window}->get_allocated_width; + $windowwidth = $::real_windowwidth if $windowwidth <= 1; + $width = $windowwidth - first(get_action_box_size()) - 25; + } - $width = first($w->{window}->window->get_size) - first(get_action_box_size()) - 25 if $w->{window}->window; + my @parts = grep { $_->{size} > MB(2) || !isEmpty($_) } @all_parts; my $ratio = $totalsectors ? ($width - @parts * $minwidth) / $totalsectors : 1; - while (1) { + my $i = 1; + while ($i < 30) { + $i++; my $totalwidth = sum(map { $_->{size} * $ratio + $minwidth } @parts); $totalwidth <= $width and last; $ratio /= $totalwidth / $width * 1.1; @@ -313,9 +357,15 @@ sub create_buttons4partitions { }; foreach my $entry (@parts) { - my $info = $entry->{mntpoint}; + if (isRawLUKS($entry) && $entry->{dm_active}) { + my $p = find { $entry->{dm_name} eq $_->{dmcrypt_name} } @{$all_hds->{dmcrypts}}; + $entry = $p if $p; + } + my $info = $entry->{mntpoint} || $entry->{device_LABEL} || ''; $info .= "\n" . ($entry->{size} ? formatXiB($entry->{size}, 512) : N("Unknown")) if $info; - my $w = Gtk2::ToggleButton->new_with_label($info) or internal_error('new_with_label'); + my $w = ($info ? Gtk3::ToggleButton->new_with_label($info) : Gtk3::ToggleButton->new) or internal_error('new_with_label'); + $info and $w->get_child->set_ellipsize('end'); + $w->set_tooltip_text($info); $w->signal_connect(clicked => sub { $current_button != $w or return; current_entry_changed($kind, $entry); @@ -339,12 +389,15 @@ sub create_buttons4partitions { last; } }); - my @colorized_fs_types = qw(ext3 ext4 xfs swap vfat ntfs ntfs-3g); + if (isLUKS($entry) || isRawLUKS($entry)) { + $w->set_image(gtknew("Image", file => "security-strong")); + } + my @colorized_fs_types = qw(ext3 ext4 xfs swap vfat ntfs ntfs-3g exfat); $w->set_name("PART_" . (isEmpty($entry) ? 'empty' : $entry->{fs_type} && member($entry->{fs_type}, @colorized_fs_types) ? $entry->{fs_type} : 'other')); $w->set_size_request($entry->{size} * $ratio + $minwidth, 0); - gtkpack__($kind->{display_box}, $w); + gtkpack($kind->{display_box}, $w); if ($current_entry && fsedit::are_same_partitions($current_entry, $entry)) { $set_current_button->($w); $w->grab_focus; @@ -357,7 +410,7 @@ sub create_buttons4partitions { # disks: helpers ################################################################################ sub current_hd() { - $current_kind->{type} eq 'hd' or die 'current_hd called but $current_kind is not an hd ('.$current_kind->{type}.')'; + $current_kind->{type} =~ /hd|lvm/ or die 'current_hd called but $current_kind is not an hd (' . $current_kind->{type} . ')'; $current_kind->{val}; } sub current_part() { @@ -376,17 +429,17 @@ sub hd2kind { } sub filesystems_button_box() { - my @types = (N_("Ext3"), N_("XFS"), N_("Swap"), arch() =~ /sparc/ ? N_("SunOS") : arch() eq "ppc" ? N_("HFS") : N_("Windows"), + my @types = (N_("Ext4"), N_("XFS"), N_("Swap"), N_("Windows"), N_("Other"), N_("Empty")); my %name2fs_type = (Ext3 => 'ext3', Ext4 => 'ext4', 'XFS' => 'xfs', Swap => 'swap', Other => 'other', "Windows" => 'vfat', HFS => 'hfs'); - gtkpack(Gtk2::HBox->new(), + gtkpack(Gtk3::HBox->new, map { my $t = $name2fs_type{$_}; my $w = gtknew('Button', text => translate($_), widget_name => 'PART_' . ($t || 'empty'), tip => N("Filesystem types:"), clicked => sub { try_('', \&createOrChangeType, $t, current_hd(), current_part()) }); - $w->can_focus(0); + $w->set_can_focus(0); $w; } @types); } @@ -418,6 +471,21 @@ sub createOrChangeType { } } +sub kind2parts { + my ($kind) = @_; + my $v = $kind->{val}; + my @parts = + $kind->{type} eq 'raid' ? grep { $_ } @$v : + $kind->{type} eq 'loopback' ? @$v : fs::get::hds_fstab_and_holes($v); + @parts; +} + +sub kind2sectors { + my ($kind, @parts) = @_; + my $v = $kind->{val}; + $kind->{type} =~ /raid|loopback/ ? sum(map { $_->{size} } @parts) : $v->{totalsectors}; +} + ################################################################################ # lvms: helpers ################################################################################ @@ -433,11 +501,9 @@ sub raid2kind() { { type => 'raid', name => 'raid', val => $all_hds->{raids} }; } -################################################################################ -# loopbacks: helpers -################################################################################ -sub dmcrypt2kind() { - { type => 'dmcrypt', name => 'dmcrypt', val => $all_hds->{dmcrypts} }; +sub raid2real_kind { + my ($raid) = @_; + { type => 'raid', name => 'raid', val => $raid }; } ################################################################################ diff --git a/perl-install/diskdrake/interactive.pm b/perl-install/diskdrake/interactive.pm index b899a2038..59e79782c 100644 --- a/perl-install/diskdrake/interactive.pm +++ b/perl-install/diskdrake/interactive.pm @@ -1,9 +1,11 @@ -package diskdrake::interactive; # $Id$ +package diskdrake::interactive; use diagnostics; use strict; use utf8; +use lib qw(/usr/lib/libDrakX); # for perl_checker +use MDK::Common; # for perl_checker use common; use fs::type; use fs::loopback; @@ -20,19 +22,16 @@ use raid; use any; use log; - -=begin - =head1 SYNOPSYS -struct part { + struct part { int active # one of { 0 | 0x80 } x86 only, primary only int start # in sectors int size # in sectors int pt_type # 0x82, 0x83, 0x6 ... string fs_type # 'ext2', 'nfs', ... string type_name # 'Linux RAID', 'Linux Logical Volume Manager', ... - + int part_number # 1 for hda1... string device # 'hda5', 'sdc1' ... string device_LABEL # volume label. LABEL=xxx or /dev/disk/by-label/xxx can be used in fstab instead of the device @@ -42,7 +41,7 @@ struct part { bool prefer_device # should the {device} be used in fstab bool faked_device # false if {device} is a real device, true for nfs/smb/dav/none devices. If the field does not exist, we do not know bool device_LABEL_changed # true if device_LABEL is different from the one on the disk - + string rootDevice # 'sda', 'hdc' ... (can also be a VG_name) string real_mntpoint # directly on real /, '/tmp/hdimage' ... string mntpoint # '/', '/usr' ... @@ -51,32 +50,32 @@ struct part { string encrypt_key # [0-9A-Za-z./]{20,} string comment # comment to have in fstab string volume_label # - + bool is_removable # is the partition on a removable drive bool isMounted - + bool isFormatted bool notFormatted # isFormatted means the device is formatted # !isFormatted && notFormatted means the device is not formatted # !isFormatted && !notFormatted means we do not know which state we're in - + string raid # for partitions of type isRawRAID and which isPartOfRAID, the raid device string lvm # partition used as a PV for the VG with {lvm} as VG_name #-# loopback loopback[] # loopback living on this partition - + string dmcrypt_key string dm_name bool dm_active - + # internal string real_device # '/dev/loop0', '/dev/loop1' ... (used for encrypted loopback) - + # internal CHS (Cylinder/Head/Sector) int start_cyl, start_head, start_sec, end_cyl, end_head, end_sec, } -struct part_allocate inherits part { + struct part_allocate inherits part { int maxsize # in sectors (alike "size") int min_hd_size # in sectors (do not allocate if the drive is smaller than the given size) int ratio # @@ -84,44 +83,44 @@ struct part_allocate inherits part { string parts # for creating raid partitions. eg: 'foo bar' where 'foo' and 'bar' are mntpoint } -struct part_raid inherits part { + struct part_raid inherits part { string chunk-size # in KiB, usually '64' string level # one of { 0, 1, 4, 5, 'linear' } string UUID - + part disks[] - + # invalid: active, start, rootDevice, device_windobe?, CHS } -struct part_dmcrypt inherits part { + struct part_dmcrypt inherits part { string dmcrypt_name - + # rootDevice is special here: it is the device hosting the dm } -struct part_loopback inherits part { + struct part_loopback inherits part { string loopback_file # absolute file name which is relative to the partition part loopback_device # where the loopback file live - + # device is special here: it is the absolute filename of the loopback file. - + # invalid: active, start, rootDevice, device_windobe, CHS } -struct part_lvm inherits part { + struct part_lvm inherits part { # invalid: active, start, device_windobe, CHS string lv_name } -struct partition_table_elem { + struct partition_table_elem { part normal[] # part extended # the main/next extended part raw[4] # primary partitions } -struct geom { + struct geom { int heads int sectors int cylinders @@ -129,14 +128,14 @@ struct geom { int start # always 0, forget it } -struct hd { + struct hd { int totalsectors # size in sectors string device # 'hda', 'sdc' ... string device_alias # 'cdrom', 'floppy' ... string media_type # one of { 'hd', 'cdrom', 'fd', 'tape' } string capacity # contain of the strings of { 'burner', 'DVD' } string info # name of the hd, eg: 'QUANTUM ATLAS IV 9 WLS' - + bool readonly # is it allowed to modify the partition table bool getting_rid_of_readonly_allowed # is it forbidden to write because the partition table is badly handled, or is it because we MUST not change the partition table bool isDirty # does it need to be written to the disk @@ -147,37 +146,37 @@ struct hd { # - add an extended partition which is the first extended partition list allPartitionsRenumbered # used to update bootloader configuration int bus, id - + bool is_removable # is it a removable drive - + partition_table_elem primary partition_table_elem extended[] - + geom geom - + # internal string prefix # for some RAID arrays device=>c0d0 and prefix=>c0d0p string file # '/dev/hda' ... } -struct hd_lvm inherits hd { + struct hd_lvm inherits hd { int PE_size # block size (granularity, similar to cylinder size on x86) string VG_name # VG name - + part_lvm disks[] - + # invalid: bus, id, extended, geom } -struct raw_hd inherits hd { + struct raw_hd inherits hd { string fs_type # 'ext2', 'nfs', ... string mntpoint # '/', '/usr' ... string options # 'defaults', 'noauto' - + # invalid: isDirty, will_tell_kernel, rebootNeeded, primary, extended } -struct all_hds { + struct all_hds { hd hds[] hd_lvm lvms[] part_raid raids[] @@ -188,7 +187,7 @@ struct all_hds { raw_hd smbs[] raw_hd davs[] raw_hd special[] - + # internal: if fstab_to_string($all_hds) eq current_fstab then no need to save string current_fstab } @@ -286,16 +285,19 @@ sub Done { $in->ask_yesorno(N("Quit without saving"), N("Quit without writing the partition table?"), 1) or return; } } + foreach (@{$all_hds->{raids}}) { + raid::make($all_hds->{raids}, $_); + } if (!$::isInstall) { my $new = fs::fstab_to_string($all_hds); - if ($new ne $all_hds->{current_fstab} && $in->ask_yesorno(N("Confirmation"), N("Do you want to save /etc/fstab modifications"), 1)) { + if ($new ne $all_hds->{current_fstab} && $in->ask_yesorno(N("Confirmation"), N("Do you want to save the /etc/fstab modifications?"), 1)) { $all_hds->{current_fstab} = $new; fs::write_fstab($all_hds); } update_bootloader_for_renumbered_partitions($in, $all_hds); if (any { $_->{rebootNeeded} } @{$all_hds->{hds}}) { - $in->ask_warn(N("Partitioning"), N("You need to reboot for the partition table modifications to take place")); + $in->ask_warn(N("Partitioning"), N("You need to reboot for the partition table modifications to take effect")); tell_wm_and_reboot(); } } @@ -320,7 +322,7 @@ sub hd_possible_actions_base { sub hd_possible_actions_extra { my ($_hd) = @_; - $::expert ? N_("Toggle to normal mode") : N_("Toggle to expert mode"); + $::expert ? N_("Normal mode") : N_("Expert mode"); } @@ -332,7 +334,7 @@ sub hd_possible_actions { sub hd_possible_actions_interactive { my ($_in, $_hd, $_all_hds) = @_; - &hd_possible_actions, N_("Hard drive information"); + &hd_possible_actions, N_("Hard disk drive information"); } sub Clear_all { @@ -351,22 +353,23 @@ sub Clear_all { $hd->{getting_rid_of_readonly_allowed} = 0; #- we don't need this flag anymore fsedit::partition_table_clear_and_initialize($all_hds->{lvms}, $hd, $in); } + fsedit::init_mntpnt_suggestions($all_hds, $hd, 1); } sub Auto_allocate { my ($in, $hd, $all_hds) = @_; - my $suggestions = partitions_suggestions($in) or return; + my $suggestions = partitions_suggestions($in, $all_hds, $hd) or return; my %all_hds_ = %$all_hds; $all_hds_{hds} = [ sort { $a == $hd ? -1 : 1 } fs::get::hds($all_hds) ]; - eval { fsedit::auto_allocate(\%all_hds_, $suggestions) }; + eval { fsedit::auto_allocate(\%all_hds_, $suggestions, $hd) }; if ($@) { $@ =~ /partition table already full/ or die; $in->ask_warn("", [ N("All primary partitions are used"), - N("I can not add any more partitions"), + N("I cannot add any more partitions"), N("To have more partitions, please delete one to be able to create an extended partition"), ]); } @@ -392,6 +395,10 @@ sub Hd_info { # per-part actions ################################################################################ +sub is_LVM_resizable { + my ($part) = @_; + member($part->{fs_type}, qw(btrfs ext3 ext4 nilfs2 reiserfs xfs)); +} sub part_possible_actions { my ($_in, $hd, $part, $all_hds) = @_; $part or return; @@ -402,8 +409,8 @@ sub part_possible_actions { N_("Type") => '!isBusy && $::expert && (!readonly || $part->{pt_type} == 0x83)', N_("Options") => '!isSwap($part) && !isNonMountable && $::expert', N_("Label") => '!isNonMountable && $::expert && fs::format::canEditLabel($part)', - N_("Resize") => '!isBusy && !readonly && !isSpecial || isLVM($hd) && LVM_resizable', - N_("Format") => '!isBusy && !isRawLVM && !isPartOfLVM && (!readonly && ($::expert || $::isStandalone) || fs::type::isRawLUKS($part))', + N_("Resize") => '!isBusy && !readonly && !isSpecial || isLVM($hd) && is_LVM_resizable', + N_("Format") => '!isBusy && isFormatable && (!readonly && ($::expert || $::isStandalone) || fs::type::isRawLUKS($part))', N_("Mount") => '!isBusy && (hasMntpoint || isSwap) && maybeFormatted && ($::expert || $::isStandalone)', N_("Add to RAID") => '!isBusy && isRawRAID && (!isSpecial || isRAID)', N_("Add to LVM") => '!isBusy && isRawLVM', @@ -421,7 +428,6 @@ sub part_possible_actions { my %macros = ( readonly => '$hd->{readonly}', hasMntpoint => '$part->{mntpoint}', - LVM_resizable => 'member($part->{fs_type}, qw(reiserfs xfs ext3 ext4))', canModifyRAID => 'isPartOfRAID($part) && !isMounted(fs::get::device2part($part->{raid}, $all_hds->{raids}))', ); if (isEmpty($part)) { @@ -436,15 +442,23 @@ sub part_possible_actions { $cond =~ s/$k/qq(($v))/e; } $cond =~ s/(^|[^:\$]) \b ([a-z]\w{3,}) \b ($|[\s&\)])/$1 . $2 . '($part)' . $3/exg; - eval $cond; + my $res = eval $cond; + if (my $err = $@) { + warn "ERROR: Bogus condition for '$actions{$_}': $err\n"; + } + $res; } @$actions_names; } } sub View { - my ($in, $hd, $part, $all_hds) = @_; + my ($in, $_hd, $part, $_all_hds) = @_; my $handle = any::inspect($part, $::prefix); - $in->ask_directory({'directory'=>$handle->{dir}}); + if ($handle) { + $in->ask_directory({ 'directory' => $handle->{dir} }); + } else { + $in->ask_warn(N("Error"), N("Failed to mount partition")); + } } #- in case someone use diskdrake only to create partitions, @@ -461,7 +475,7 @@ sub Create { $part->{mntpoint} = '' if !$do_suggest_mount_point; } else { $part->{size} = $part->{maxsize}; - fs::type::suggest_fs_type($part, 'ext3'); + fs::type::suggest_fs_type($part, defaultFS()); } if (isLVM($hd)) { lvm::suggest_lv_name($hd, $part); @@ -474,6 +488,8 @@ sub Create { my $type_name = fs::type::part2type_name($part); my $mb_size = to_Mb($part->{size}); my $has_startsector = ($::expert || arch() !~ /i.86/) && !isLVM($hd); + my $use_dmcrypt; + my $requested_type; $in->ask_from(N("Create a new partition"), '', [ @@ -487,22 +503,43 @@ sub Create { { label => N("Filesystem type: "), val => \$type_name, list => [ fs::type::type_names($::expert, $hd) ], sort => 0, if_($::expert, gtk => { wrap_width => 2 }, do_not_ellipsize => 1) }, { label => N("Mount point: "), val => \$part->{mntpoint}, list => [ fsedit::suggestions_mntpoint($all_hds), '' ], + if_(isLVM($hd), changed => sub { + undef $part->{lv_name}; + lvm::suggest_lv_name($hd, $part); + }), type => 'combo', not_edit => 0, disabled => sub { my $p = fs::type::type_name2subpart($type_name); isSwap($p) || isNonMountable($p) }, type => 'combo', not_edit => 0, }, if_($::expert && $hd->hasExtended, { label => N("Preference: "), val => \$primaryOrExtended, list => [ '', "Extended", "Primary", if_($::expert, "Extended_0x85") ] }, ), - if_($::expert && isLVM($hd), + if_(isLVM($hd), { label => N("Logical volume name "), val => \$part->{lv_name}, list => [ qw(root swap usr home var), '' ], sort => 0, not_edit => 0 }, ), + { label => N("Encrypt partition"), type => 'bool', val => \$use_dmcrypt, disabled => sub { $part->{mntpoint} eq "/boot" } }, + { label => N("Encryption key "), val => \$part->{dmcrypt_key}, disabled => sub { !$use_dmcrypt }, hidden => 1, weakness_check => 1 }, + { label => N("Encryption key (again)"), val => \$part->{dmcrypt_key2}, disabled => sub { !$use_dmcrypt }, hidden => 1 }, ], complete => sub { $part->{size} = from_Mb($mb_size, min_partition_size($hd), $max - $part->{start}); #- need this to be able to get back the approximation of using MB - put_in_hash($part, fs::type::type_name2subpart($type_name)); $do_suggest_mount_point = 0 if !$part->{mntpoint}; + put_in_hash($part, fs::type::type_name2subpart($type_name)); $part->{mntpoint} = '' if isNonMountable($part); $part->{mntpoint} = 'swap' if isSwap($part); fs::mount_options::set_default($part, ignore_is_removable => 1); + # if user asked to encrypt the partition, use dm-crypt and create requested fs inside + if ($use_dmcrypt) { + my $err; + $err = N("The encryption keys do not match") unless $part->{dmcrypt_key} eq $part->{dmcrypt_key2}; + $err = N("Missing encryption key") unless $part->{dmcrypt_key}; + if ($err) { + $in->ask_warn(N("Error"), $err); + return 1; + } + $requested_type = $type_name; + $type_name = 'Encrypted'; + } + + put_in_hash($part, fs::type::type_name2subpart($type_name)); check($in, $hd, $part, $all_hds) or return 1; $migrate_files = need_migration($in, $part->{mntpoint}) or return 1; @@ -513,7 +550,7 @@ sub Create { }; if (my $err = $@) { if ($err =~ /raw_add/ && $hd->hasExtended && !$hd->{primary}{extended}) { - $in->ask_warn(N("Error"), N("You can not create a new partition + $in->ask_warn(N("Error"), N("You cannot create a new partition (since you reached the maximal number of primary partitions). First remove a primary partition and create an extended partition.")); return 0; @@ -526,9 +563,26 @@ First remove a primary partition and create an extended partition.")); }, ) or return; + if ($use_dmcrypt) { + write_partitions($in, $hd) or return; + # Initialize it and format it + dmcrypt_format($in, $hd, $part, $all_hds); + my $p = find { $part->{dm_name} eq $_->{dmcrypt_name} } @{$all_hds->{dmcrypts}}; + my $p2 = fs::type::type_name2subpart($requested_type); + $p->{fs_type} = $p2->{fs_type}; + $p->{type_name} = $requested_type; + $p->{mntpoint} = $part->{mntpoint}; + $part->{mntpoint} = ''; + if ($::isStandalone) { + fs::format::check_package_is_installed_format($in->do_pkgs, $p->{fs_type}) or log::l("Missing package"); + } + _format_raw($in, $p, $all_hds, isRawLVM($p)); + } + warn_if_renumbered($in, $hd); if ($migrate_files eq 'migrate') { + # FIXME check encrypt case format_($in, $hd, $part, $all_hds) or return; migrate_files($in, $hd, $part); fs::mount::part($part); @@ -537,6 +591,11 @@ First remove a primary partition and create an extended partition.")); sub Delete { my ($in, $hd, $part, $all_hds) = @_; + if (fs::type::isLUKS($part)) { + my $p = find { $_->{dm_name} eq $part->{dmcrypt_name} } partition_table::get_normal_parts($hd); + RemoveFromDm($in, $hd, $p, $all_hds); + $part = $p; + } if (isRAID($part)) { raid::delete($all_hds->{raids}, $part); } elsif (isLVM($hd)) { @@ -551,9 +610,6 @@ sub Delete { delete $part->{loopback_device}{loopback} if @$l == 0; fsedit::recompute_loopbacks($all_hds); } else { - if (arch() =~ /ppc/) { - undef $partition_table::mac::bootstrap_part if isAppleBootstrap($part) && ($part->{device} = $partition_table::mac::bootstrap_part); - } partition_table::remove($hd, $part); warn_if_renumbered($in, $hd); } @@ -565,11 +621,15 @@ sub Type { my $warned; my $warn = sub { $warned = 1; - ask_alldatawillbelost($in, $part, N_("After changing type of partition %s, all data on this partition will be lost")); + if (maybeFormatted($part)) { + ask_alldatawillbelost($in, $part, N_("After changing type of partition %s, all data on this partition will be lost")); + } else { + 1; + } }; - #- for ext2, warn after choosing as ext2->ext3 can be achieved without loosing any data :) - $part->{fs_type} eq 'ext2' || $part->{fs_type} =~ /ntfs/ or $warn->() or return; + #- for ext2/ext3, warn after choosing as ext2->ext3 and ext*->ext4 can be achieved without loosing any data :) + member($part->{fs_type}, qw(ext2 ext3)) || $part->{fs_type} =~ /ntfs/ or $warn->() or return; my @types = fs::type::type_names($::expert, $hd); @@ -586,7 +646,7 @@ sub Type { my $type = $type_name && fs::type::type_name2subpart($type_name); - if (member($type->{fs_type}, qw(ext2 ext3 ext4))) { + if ($part->{fs_type} eq 'ext2' && $type->{fs_type} eq 'ext3') { my $_w = $in->wait_message(N("Please wait"), N("Switching from %s to %s", 'ext2', $type->{fs_type})); if (run_program::run("tune2fs", "-j", devices::make($part->{device}))) { put_in_hash($part, $type); @@ -596,8 +656,13 @@ sub Type { fs::format::disable_forced_fsck($part->{device}); return; } + } elsif (member($part->{fs_type}, qw(ext2 ext3)) && $type->{fs_type} eq 'ext4') { + # FIXME enable some nice flags + put_in_hash($part, $type); + return; } elsif ($type->{fs_type} =~ /ntfs/ && $part->{fs_type} =~ /ntfs/) { if ($type->{fs_type} eq 'ntfs-3g') { + local $::prefix = ''; # For draklive-install $in->do_pkgs->ensure_binary_is_installed('ntfs-3g', 'mount.ntfs-3g') or return; } put_in_hash($part, $type); @@ -612,19 +677,24 @@ sub Type { } sub Label { - my ($in, $_hd, $part) = @_; + my ($in, $hd, $part) = @_; my $new_label = $part->{device_LABEL} || ""; - $in->ask_from(N("Set volume label"), N("Beware, this will be written to disk as soon as you validate!"), - [ + write_partitions($in, $hd) or return; + + $in->ask_from(N("Set volume label"), + maybeFormatted($part) ? + N("Beware, this will be written to disk as soon as you validate!") + : N("Beware, this will be written to disk only after formatting!"), + [ { label => N("Which volume label?"), title => 1 }, { label => N("Label:"), val => \$new_label } ]) or return; fs::format::check_package_is_installed_label($in->do_pkgs, $part->{fs_type}) or return; + $part->{prefer_device_LABEL} = to_bool($part->{device_LABEL}) && !isLVM($part); return if $new_label eq $part->{device_LABEL}; $part->{device_LABEL} = $new_label; $part->{device_LABEL_changed} = 1; - $part->{prefer_device_LABEL} = to_bool($part->{device_LABEL}) && !isLVM($part); fs::format::clean_label($part); fs::format::write_label($part); } @@ -645,7 +715,7 @@ sub Mount_point { callbacks => { complete => sub { !isPartOfLoopback($part) || $mntpoint or $in->ask_warn(N("Error"), -N("Can not unset mount point as this partition is used for loop back. +N("Cannot unset mount point as this partition is used for loop back. Remove the loopback first")), return 1; $part->{mntpoint} eq $mntpoint || check_mntpoint($in, $mntpoint, $part, $all_hds) or return 1; $migrate_files = need_migration($in, $mntpoint) or return 1; @@ -687,10 +757,36 @@ sub Mount_point_raw_hd { $part->{mntpoint} = $mntpoint; } +#- side-effects: mounts the fs +sub _get_dir_for_online_resize { + my ($part) = @_; + my $dir = "/tmp/tmp_resize_" . $part->{fs_type} . ".$$"; + if ($part->{isMounted}) { + $dir = ($::prefix || '') . $part->{mntpoint}; + } else { + mkdir_p($dir); + fs::mount::mount(devices::make($part->{device}), $dir, $part->{fs_type}); + } + return $dir; +} + +sub _set_min_size_from_avail_space { + my ($part, $min) = @_; + if (defined(my $free = fs::df($part))) { + $$min = max($$min, $part->{size} - $free); + } +} + sub Resize { my ($in, $hd, $part) = @_; - my (%nice_resize); - my ($min, $max) = (min_partition_size($hd), max_partition_resize($hd, $part)); + my (%nice_resize, $online_resize); + my $low_part = $part; + + if (isLUKS($part)) { + $low_part = find { $_->{dm_name} eq $part->{dmcrypt_name} } partition_table::get_normal_parts($hd); + } + + my ($min, $max) = (min_partition_size($hd), max_partition_resize($hd, $low_part)); if (maybeFormatted($part)) { # here we may have a non-formatted or a formatted partition @@ -705,7 +801,7 @@ sub Resize { $nice_resize{fat} = resize_fat::main->new($part->{device}, devices::make($part->{device})); $min = max($min, $nice_resize{fat}->min_size); $max = min($max, $nice_resize{fat}->max_size); - } elsif (member($part->{fs_type}, qw(ext2 ext3))) { # resize2fs is known to be broken regarding extents with ext4 + } elsif (member($part->{fs_type}, qw(ext2 ext3 ext4))) { write_partitions($in, $hd) or return; require diskdrake::resize_ext2; if ($nice_resize{ext2} = diskdrake::resize_ext2->new($part->{device}, devices::make($part->{device}))) { @@ -713,6 +809,9 @@ sub Resize { } else { delete $nice_resize{ext2}; } + } elsif ($part->{fs_type} eq 'f2fs') { + $min = $part->{size}; #- ensure the user can only increase + $nice_resize{f2fs} = 1; } elsif ($part->{fs_type} =~ /ntfs/) { write_partitions($in, $hd) or return; require diskdrake::resize_ntfs; @@ -721,17 +820,27 @@ sub Resize { $min = $nice_resize{ntfs}->min_size or delete $nice_resize{ntfs}; } elsif ($part->{fs_type} eq 'reiserfs') { write_partitions($in, $hd) or return; + $nice_resize{reiserfs} = 1; if ($part->{isMounted}) { - $nice_resize{reiserfs} = 1; $min = $part->{size}; #- ensure the user can only increase - } elsif (defined(my $free = fs::df($part))) { - $nice_resize{reiserfs} = 1; - $min = max($min, $part->{size} - $free); + } else { + _set_min_size_from_avail_space($part, \$min); } - } elsif ($part->{fs_type} eq 'xfs' && isLVM($hd) && $::isStandalone && $part->{isMounted}) { + } elsif ($part->{fs_type} eq 'xfs') { $min = $part->{size}; #- ensure the user can only increase - $nice_resize{xfs} = 1; + $online_resize = $part->{fs_type}; + } elsif (member($part->{fs_type}, qw(btrfs nilfs2))) { + $online_resize = $part->{fs_type}; + } + + # Btrf, nilfs2 && XFS only support online resizing + # (Ext3/4 too but we can resize it offline so we don't care - though growing online is interesting) + if ($online_resize) { + write_partitions($in, $hd) or return; + $nice_resize{$online_resize} = 1; + _set_min_size_from_avail_space($part, \$min); } + #- make sure that even after normalizing the size to cylinder boundaries, the minimun will be saved, #- this save at least a cylinder (less than 8Mb). $min += partition_table::raw::cylinder_size($hd); @@ -740,7 +849,7 @@ sub Resize { #- for these, we have tools to resize partition table #- without losing data (or at least we hope so :-) if (%nice_resize) { - ask_alldatamaybelost($in, $part, N_("All data on this partition should be backed-up")) or return; + ask_alldatamaybelost($in, $part, N_("All data on this partition should be backed up")) or return; } else { ask_alldatawillbelost($in, $part, N_("After resizing partition %s, all data on this partition will be lost")) or return; } @@ -760,8 +869,8 @@ sub Resize { $part->{size} == $size and return; my $oldsize = $part->{size}; - $part->{size} = $size; - $hd->adjustEnd($part); + $low_part->{size} = $part->{size} = $size; + $hd->adjustEnd($low_part); undef $@; my $_b = before_leaving { $@ and $part->{size} = $oldsize }; @@ -770,12 +879,19 @@ sub Resize { my ($write_partitions) = @_; if (isLVM($hd)) { - lvm::lv_resize($part, $oldsize); + lvm::lv_resize($low_part, $oldsize); } else { - partition_table::will_tell_kernel($hd, resize => $part); - partition_table::adjust_local_extended($hd, $part); + if ($write_partitions && isLUKS($part)) { + run_program::run('cryptsetup', 'luksClose', $part->{dmcrypt_name}) or die("Failed to resize partition, maybe it is mounted"); + } + partition_table::will_tell_kernel($hd, resize => $low_part); + partition_table::adjust_local_extended($hd, $low_part); partition_table::adjust_main_extended($hd); - write_partitions($in, $hd) or return if $write_partitions && %nice_resize; + write_partitions($in, $hd) or return if $write_partitions && (%nice_resize || isLUKS($part)); + if ($write_partitions && isLUKS($part)) { + require fs::dmcrypt; + fs::dmcrypt::open_part([], $low_part); + } } 1; }; @@ -798,9 +914,29 @@ filesystem checks will be run on your next boot into Microsoft Windows®")); } elsif ($nice_resize{reiserfs}) { log::l("reiser resize to $part->{size} sectors"); run_program::run_or_die('resize_reiserfs', '-f', '-q', '-s' . int($part->{size}/2) . 'K', devices::make($part->{device})); - } elsif ($nice_resize{xfs}) { - #- happens only with mounted LVM, see above - run_program::run_or_die("xfs_growfs", $part->{mntpoint}); + } elsif ($online_resize) { + my $dir = _get_dir_for_online_resize($part); + my @cmd; + if ($nice_resize{btrfs}) { + # FIXME: only works for a FS on a single device. Multi-device FS would need to specify the device to enlarge + @cmd = (qw(btrfs filesystem resize), $part->{size}*512, $dir); + } elsif ($nice_resize{nilfs2}) { + @cmd = ('nilfs-resize', devices::make($part->{device}), $part->{size}*512); + } elsif ($nice_resize{xfs}) { + @cmd = ("xfs_growfs", $dir); + } else { + die("I don't know how to proceed"); + } + if (!run_program::run(@cmd)) { + $nice_resize{$part->{fs_type}} = undef; + } + # umount after online resize if it was mounted on demand: + if (!$part->{isMounted}) { + fs::mount::umount($dir); + unlink($dir); + } + } elsif ($nice_resize{f2fs}) { + run_program::run_or_die("resize.f2fs", devices::make($part->{device})); } if (%nice_resize) { @@ -808,11 +944,12 @@ filesystem checks will be run on your next boot into Microsoft Windows®")); } else { set_isFormatted($part, 0); partition_table::verifyParts($hd) if !isLVM($hd); - $part->{mntpoint} = '' if isNonMountable($part); #- mainly for ntfs, which we can not format + $part->{mntpoint} = '' if isNonMountable($part); #- mainly for ntfs, which we cannot format } $adjust->(0) if $size < $oldsize; } + sub Format { my ($in, $hd, $part, $all_hds) = @_; format_($in, $hd, $part, $all_hds); @@ -835,7 +972,7 @@ sub dmcrypt_open { my ($in, $_hd, $part, $all_hds) = @_; $part->{dm_name} ||= do { my $s = $part->{device}; - $s =~ s/[^\w]/_/g; + $s =~ s/\W/_/g; "crypt_$s"; }; @@ -847,11 +984,26 @@ sub dmcrypt_open { hidden => 1, focus => sub { 1 } } ]) or return; } - eval { fs::dmcrypt::open_part($all_hds->{dmcrypts}, $part) }; + eval { require fs::dmcrypt; fs::dmcrypt::open_part($all_hds->{dmcrypts}, $part) }; if ($@) { delete $part->{dmcrypt_key}; die(($? >> 8) == 255 ? N("Invalid key") : $@); } + detect_lvms_on_dmcrypt($all_hds); +} + +# Detect LVMs on top of dmcrypt +sub detect_lvms_on_dmcrypt { + my ($all_hds) = @_, + require File::Temp; + require fs::dmcrypt; + my (undef, $tmp_file) = File::Temp::mkstemp('/tmp/crypttab.XXXXXXX'); + fs::dmcrypt::save_crypttab_($all_hds, $tmp_file); + require lvm; + lvm::detect_during_install(); + $all_hds->{lvms} = [ fsedit::lvms($all_hds) ]; + fs::dmcrypt::read_crypttab_($all_hds, $tmp_file); + rm_rf($tmp_file); } sub Add2RAID { @@ -874,6 +1026,7 @@ sub Add2RAID { sub Add2LVM { my ($in, $hd, $part, $all_hds) = @_; my $lvms = $all_hds->{lvms}; + my @lvm_names = map { $_->{VG_name} } @$lvms; write_partitions($in, $_) or return foreach isRAID($part) ? @{$all_hds->{hds}} : $hd; my $lvm = $in->ask_from_listf_(N("Add to LVM"), N("Choose an existing LVM to add to"), @@ -882,11 +1035,27 @@ sub Add2LVM { require lvm; if (!ref $lvm) { # create new lvm - # FIXME: when mdv2006 is out: remove the question mark from the dialog title - my $name = $in->ask_from_entry(N("LVM name?"), N("LVM name?")) or return; + my $n; my $str = "vg-mga"; + while (member("$str$n", @lvm_names)) { + $n++; + } + + my $name = "$str$n"; + $in->ask_from_({ title => N("LVM name"), + messages => N("Enter a name for the new LVM volume group"), + focus_first => 1, + ok_disabled => sub { !$name }, + validate => sub { + member($name, @lvm_names) or return 1; + $in->ask_warn(N("Error"), N("\"%s\" already exists", $name)); + return 0; + } }, + [ { label => N("LVM name"), val => \$name } ]) or return; + $lvm = new lvm($name); push @$lvms, $lvm; } + my $_w = $in->wait_message(N("Please wait"), N("Setting up LVM")); raid::make($all_hds->{raids}, $part) if isRAID($part); lvm::check($in->do_pkgs) if $::isStandalone; lvm::add_to_VG($part, $lvm); @@ -901,6 +1070,7 @@ sub RemoveFromRAID { } sub RemoveFromDm { my ($_in, $_hd, $part, $all_hds) = @_; + require fs::dmcrypt; fs::dmcrypt::close_part($all_hds->{dmcrypts}, $part); } sub RemoveFromLVM { @@ -930,14 +1100,14 @@ sub Loopback { write_partitions($in, $hd) or return; - my $handle = any::inspect($real_part) or $in->ask_warn(N("Error"), N("This partition can not be used for loopback")), return; + my $handle = any::inspect($real_part) or $in->ask_warn(N("Error"), N("This partition cannot be used for loopback")), return; my ($min, $max) = (1, fs::loopback::getFree($handle->{dir}, $real_part)); $max = min($max, 1 << (31 - 9)) if $real_part->{fs_type} eq 'vfat'; #- FAT does not handle file size bigger than 2GB my $part = { maxsize => $max, size => 0, loopback_device => $real_part, notFormatted => 1 }; if (!fsedit::suggest_part($part, $all_hds)) { $part->{size} = $part->{maxsize}; - fs::type::suggest_fs_type($part, 'ext3'); + fs::type::suggest_fs_type($part, defaultFS()); } delete $part->{mntpoint}; # we do not want the suggested mntpoint @@ -967,7 +1137,7 @@ sub Loopback { } sub Options { - my ($in, $hd, $part, $all_hds) = @_; + my ($in, $_hd, $part, $_all_hds) = @_; my @simple_options = qw(users noauto username= password=); @@ -1001,27 +1171,6 @@ sub Options { if (($options->{usrquota} || $options->{grpquota}) && !$::isInstall) { $in->do_pkgs->ensure_binary_is_installed('quota', 'quotacheck'); } - if ($options->{encrypted}) { - # modify $part->{options} for the check - local $part->{options}; - fs::mount_options::pack($part, $options, $unknown); - if (!check($in, $hd, $part, $all_hds)) { - $options->{encrypted} = 0; - } elsif (!$part->{encrypt_key} && !isSwap($part)) { - if (my ($encrypt_key, $encrypt_algo) = choose_encrypt_key($in, $options, '')) { - $options->{'encryption='} = $encrypt_algo; - $part->{encrypt_key} = $encrypt_key; - } else { - $options->{encrypted} = 0; - } - } - #- don't be sure of anything - set_isFormatted($part, 0); - $part->{notFormatted} = 0; - } else { - delete $options->{'encryption='}; - delete $part->{encrypt_key}; - } }) or return; fs::mount_options::pack($part, $options, $unknown); @@ -1031,20 +1180,20 @@ sub Options { { no strict; - *{'Toggle to normal mode'} = sub() { $::expert = 0 }; - *{'Toggle to expert mode'} = sub() { $::expert = 1 }; + *{'Normal mode'} = sub() { $::expert = 0 }; + *{'Expert mode'} = sub() { $::expert = 1 }; *{'Clear all'} = \&Clear_all; *{'Auto allocate'} = \&Auto_allocate; *{'Mount point'} = \&Mount_point; *{'Modify RAID'} = \&ModifyRAID; *{'Add to RAID'} = \&Add2RAID; *{'Remove from RAID'} = \&RemoveFromRAID; - *{'Use'} = \&dmcrypt_open; + *{Use} = \&dmcrypt_open; *{'Remove from dm'} = \&RemoveFromDm; *{'Add to LVM'} = \&Add2LVM; *{'Remove from LVM'} = \&RemoveFromLVM; *{'Use for loopback'} = \&Loopback; - *{'Hard drive information'} = \&Hd_info; + *{'Hard disk drive information'} = \&Hd_info; } @@ -1063,7 +1212,7 @@ sub modifyRAID { $in->ask_from(N("Options"), '', [ { label => N("device"), val => \$new_device, list => [ $md_part->{device}, raid::free_mds($raids) ], sort => 0 }, -{ label => N("level"), val => \$md_part->{level}, list => [ qw(0 1 4 5 6 linear) ] }, +{ label => N("level"), val => \$md_part->{level}, list => [ qw(0 1 4 5 6 10 linear) ] }, { label => N("chunk size in KiB"), val => \$md_part->{'chunk-size'} }, ], ) or return; @@ -1095,7 +1244,8 @@ sub ask_alldatawillbelost { } sub partitions_suggestions { - my ($in) = @_; + my ($in, $all_hds, $hd) = @_; + fsedit::init_mntpnt_suggestions($all_hds, $hd); my $t = $::expert ? $in->ask_from_list_(N("Partitioning Type"), N("What type of partitioning?"), [ keys %fsedit::suggestions ]) : 'simple'; @@ -1135,7 +1285,7 @@ sub check { sub check_rebootNeeded { my ($_in, $hd) = @_; - $hd->{rebootNeeded} and die N("You'll need to reboot before the modification can take place"); + $hd->{rebootNeeded} and die N("You'll need to reboot before the modification can take effect"); } sub write_partitions { @@ -1155,17 +1305,14 @@ sub write_partitions { sub ensure_we_have_encrypt_key_if_needed { my ($in, $part) = @_; - if ($part->{options} =~ /encrypted/ && !$part->{encrypt_key}) { - my ($options, $_unknown) = fs::mount_options::unpack($part); - $part->{encrypt_key} = choose_encrypt_key($in, $options, 'skip_encrypt_algo') or return; - } elsif (fs::type::isRawLUKS($part)) { + if (fs::type::isRawLUKS($part)) { $part->{dmcrypt_key} ||= choose_encrypt_key($in, {}, 'skip_encrypt_algo') or return; } 1; } sub dmcrypt_format { - my ($in, $hd, $part, $all_hds) = @_; + my ($in, $_hd, $part, $_all_hds) = @_; my $_wait = $in->wait_message(N("Please wait"), N("Formatting partition %s", $part->{device})); require fs::dmcrypt; fs::dmcrypt::format_part($part); @@ -1187,12 +1334,18 @@ sub format_ { if ($::isStandalone) { fs::format::check_package_is_installed_format($in->do_pkgs, $part->{fs_type}) or return; } - if ($::expert && !member($part->{fs_type}, 'reiserfs', 'xfs')) { - $part->{toFormatCheck} = $in->ask_yesorno(N("Confirmation"), N("Check bad blocks?")); + _format_raw($in, $part, $all_hds); +} + +sub _format_raw { + my ($in, $part, $all_hds, $o_skip) = @_; + if ($::expert && isBlockCheckable($part)) { + $part->{toFormatCheck} = $in->ask_yesorno(N("Confirmation"), N("Check for bad blocks?")); } $part->{isFormatted} = 0; #- force format; + # Wait for the newly created device to appear before formatting it my ($_w, $wait_message) = $in->wait_message_with_progress_bar; - fs::format::part($all_hds, $part, $wait_message); + fs::format::part($all_hds, $part, $wait_message) if !$o_skip; 1; } @@ -1267,26 +1420,20 @@ sub format_part_info { $info .= N("Mount point: ") . "$part->{mntpoint}\n" if $part->{mntpoint}; $info .= N("Device: ") . "$part->{device}\n" if $part->{device} && !isLoopback($part); - $info .= N("Volume label: ") . "$part->{device_LABEL}\n" if $part->{device_LABEL} && $::expert; + $info .= N("Volume label: ") . "$part->{device_LABEL}\n" if $part->{device_LABEL}; $info .= N("UUID: ") . "$part->{device_UUID}\n" if $::expert && $part->{device_UUID}; $info .= N("DOS drive letter: %s (just a guess)\n", $part->{device_windobe}) if $part->{device_windobe}; - if (arch() eq "ppc") { - my $pType = $part->{pType}; - $pType =~ s/[^A-Za-z0-9_]//g; - $info .= N("Type: ") . $pType . ($::expert ? sprintf " (0x%x)", $part->{pt_type} : '') . "\n"; - if (defined $part->{pName}) { - my $pName = $part->{pName}; - $pName =~ s/[^A-Za-z0-9_]//g; - $info .= N("Name: ") . $pName . "\n"; - } - } elsif (isEmpty($part)) { + if (isEmpty($part)) { $info .= N("Empty") . "\n"; } else { $info .= N("Type: ") . (fs::type::part2type_name($part) || $part->{fs_type}) . ($::expert ? sprintf " (0x%x)", $part->{pt_type} : '') . "\n"; } $info .= N("Start: sector %s\n", $part->{start}) if $::expert && !isSpecial($part) && !isLVM($hd); - $info .= N("Size: %s", formatXiB($part->{size}, 512)); - $info .= sprintf " (%s%%)", int 100 * $part->{size} / $hd->{totalsectors} if $hd->{totalsectors}; + if ($hd->{totalsectors}) { + $info .= N("Size: %s (%s%% of disk)", formatXiB($part->{size}, 512), int 100 * $part->{size} / $hd->{totalsectors}); + } else { + $info .= N("Size: %s", formatXiB($part->{size}, 512)); + } $info .= N(", %s sectors", $part->{size}) if $::expert; $info .= "\n"; $info .= N("Cylinder %d to %d\n", $part->{start} / $hd->cylinder_size, ($part->{start} + $part->{size} - 1) / $hd->cylinder_size) if ($::expert || isEmpty($part)) && !isSpecial($part) && !isLVM($hd) && $hd->cylinder_size; @@ -1295,10 +1442,13 @@ sub format_part_info { $info .= N("Not formatted\n") if !$part->{isFormatted} && $part->{notFormatted}; $info .= N("Mounted\n") if $part->{isMounted}; $info .= N("RAID %s\n", $part->{raid}) if isPartOfRAID($part); - if (fs::type::isRawLUKS($part)) { - $info .= N("Encrypted") . ($part->{dm_active} && $part->{dm_name} ? N(" (mapped on %s)", $part->{dm_name}) : - $part->{dm_name} ? N(" (to map on %s)", $part->{dm_name}) : - N(" (inactive)")) . "\n"; + if (fs::type::isRawLUKS($part) || fs::type::isLUKS($part)) { + $info .= N("Encrypted") . "\n"; + if (fs::type::isRawLUKS($part)) { + $info .= ($part->{dm_active} && $part->{dm_name} ? N(" (mapped on %s)", $part->{dm_name}) : + $part->{dm_name} ? N(" (to map on %s)", $part->{dm_name}) : + N(" (inactive)")) . "\n"; + } } if (isPartOfLVM($part)) { $info .= sprintf "LVM %s\n", $part->{lvm}; @@ -1343,6 +1493,8 @@ sub format_hd_info { $info .= N("LVM-disks %s\n", join ", ", map { $_->{device} } @{$hd->{disks}}) if isLVM($hd) && $hd->{disks}; $info .= N("Partition table type: %s\n", $1) if $::expert && ref($hd) =~ /_([^_]+)$/; $info .= N("on channel %d id %d\n", $hd->{channel}, $hd->{id}) if $::expert && exists $hd->{channel}; + # restrict the length of the lines + $info =~ s/(.{60}).*/$1.../mg; $info; } diff --git a/perl-install/diskdrake/removable.pm b/perl-install/diskdrake/removable.pm index a4d225475..f3b73ed4b 100644 --- a/perl-install/diskdrake/removable.pm +++ b/perl-install/diskdrake/removable.pm @@ -1,4 +1,4 @@ -package diskdrake::removable; # $Id$ +package diskdrake::removable; use diagnostics; use strict; diff --git a/perl-install/diskdrake/resize_ext2.pm b/perl-install/diskdrake/resize_ext2.pm index 9bf113f90..a09cdb542 100644 --- a/perl-install/diskdrake/resize_ext2.pm +++ b/perl-install/diskdrake/resize_ext2.pm @@ -1,4 +1,4 @@ -package diskdrake::resize_ext2; # $Id$ +package diskdrake::resize_ext2; use diagnostics; use strict; diff --git a/perl-install/diskdrake/resize_ntfs.pm b/perl-install/diskdrake/resize_ntfs.pm index c6364fec6..db591e968 100644 --- a/perl-install/diskdrake/resize_ntfs.pm +++ b/perl-install/diskdrake/resize_ntfs.pm @@ -5,7 +5,7 @@ use strict; use run_program; use common; - +# perl_checker: require interactive sub new { my ($type, $_device, $dev) = @_; @@ -13,16 +13,16 @@ sub new { } sub check_prog { - my ($in) = @_; - #- ensure_binary_is_installed checks binary chrooted, whereas we run the binary non-chrooted (pb for Mandriva One) - $::isInstall || whereis_binary('ntfsresize') || $in->do_pkgs->ensure_binary_is_installed('ntfsprogs', 'ntfsresize'); + my ($in) = @_; # perl_checker: $in = interactive->new + #- ensure_binary_is_installed checks binary chrooted, whereas we run the binary non-chrooted (pb for Mageia One) + $::isInstall || whereis_binary('ntfsresize') || $in->do_pkgs->ensure_binary_is_installed('ntfs-3g', 'ntfsresize'); } sub min_size { my ($o) = @_; my $r; run_program::run('ntfsresize', '>', \$r, '-f', '-i', $o->{dev}) or die "ntfsresize failed:\n$r\n"; - $r =~ /minimal size: (\d+) KiB/ && $1 * 2; + $r =~ /You might resize at (\d+) bytes or / && $1 / 512; } sub resize { diff --git a/perl-install/diskdrake/smbnfs_gtk.pm b/perl-install/diskdrake/smbnfs_gtk.pm index f7e064b00..b2417ce83 100644 --- a/perl-install/diskdrake/smbnfs_gtk.pm +++ b/perl-install/diskdrake/smbnfs_gtk.pm @@ -1,4 +1,4 @@ -package diskdrake::smbnfs_gtk; # $Id$ +package diskdrake::smbnfs_gtk; use diagnostics; use strict; @@ -9,8 +9,8 @@ use common; use interactive; use fs::remote::smb; use fs::remote::nfs; -use mygtk2 qw(gtknew gtkset); -use ugtk2 qw(:helpers :wrappers :create); +use mygtk3 qw(gtknew gtkset); +use ugtk3 qw(:helpers :wrappers :create); my ($all_hds, $in, $tree_model, $current_entry, $current_leaf, %icons); @@ -19,7 +19,7 @@ sub main { my ($kind) = $type eq 'smb' ? smb2kind() : nfs2kind(); $kind->check($in) or return; - my $w = ugtk2->new(N("Partitioning")); + my $w = ugtk3->new(N("Partitioning")); add_smbnfs($w->{window}, $kind); $w->{rwindow}->set_default_size(400, 300) if $w->{rwindow}->can('set_default_size'); @@ -42,7 +42,7 @@ sub try_ { $in->ask_warn(N("Error"), formatError($err)); } update($kind); - Gtk2->main_quit if member($name, 'Cancel', 'Done'); + Gtk3->main_quit if member($name, 'Cancel', 'Done'); } sub raw_hd_options { @@ -87,7 +87,7 @@ sub per_entry_action_box { : gtknew('Label', text => ""); } group_by2(@l); - gtkadd($box, gtknew('HBox', children_loose => [ @buttons])); + gtkadd($box, gtknew('HBox', children_loose => \@buttons)); } sub done { @@ -127,14 +127,14 @@ sub import_tree { my ($kind, $info_box) = @_; my (%servers_displayed, %wservers, %wexports); - $tree_model = Gtk2::TreeStore->new("Gtk2::Gdk::Pixbuf", "Glib::String"); - my $tree = Gtk2::TreeView->new_with_model($tree_model); + $tree_model = Gtk3::TreeStore->new("Gtk3::Gdk::Pixbuf", "Glib::String"); + my $tree = Gtk3::TreeView->new_with_model($tree_model); $tree->get_selection->set_mode('browse'); - my $col = Gtk2::TreeViewColumn->new; - $col->pack_start(my $pixrender = Gtk2::CellRendererPixbuf->new, 0); + my $col = Gtk3::TreeViewColumn->new; + $col->pack_start(my $pixrender = Gtk3::CellRendererPixbuf->new, 0); $col->add_attribute($pixrender, 'pixbuf', 0); - $col->pack_start(my $texrender = Gtk2::CellRendererText->new, 1); + $col->pack_start(my $texrender = Gtk3::CellRendererText->new, 1); $col->add_attribute($texrender, 'text', 1); $tree->append_column($col); @@ -161,7 +161,7 @@ sub import_tree { return @l if !$@; if ($server->{username}) { - $in->ask_warn('', N("Can not login using username %s (bad password?)", $server->{username})); + $in->ask_warn('', N("Cannot login using username %s (bad password?)", $server->{username})); fs::remote::smb::remove_bad_credentials($server); } else { if (my @l = fs::remote::smb::authentications_available($server)) { @@ -194,7 +194,7 @@ sub import_tree { my $path = $tree_model->get_path($node); $tree->expand_row($path, 0); - foreach ($find_exports->($wservers{$tree_model->get_path_str($node)} || return)) { #- can not die here since insert_node provoque a tree_select_row before the %wservers is filled + foreach ($find_exports->($wservers{$tree_model->get_path_str($node)} || return)) { #- cannot die here since insert_node provoque a tree_select_row before the %wservers is filled my $s = $kind->to_string($_); my $w = $tree_model->append_set($node, [ 0 => export_icon(find_fstab_entry($kind, $_)), 1 => $s ]); @@ -208,7 +208,7 @@ sub import_tree { gtksignal_connect($search, clicked => sub { $add_server->($_) foreach sort { $a->{name} cmp $b->{name} } $kind->find_servers; - gtkset($search, text => N("Search new servers")); + gtkset($search, text => N("Search for new servers")); })); } @@ -226,10 +226,10 @@ sub import_tree { $current_entry = find_fstab_entry($kind, $wexports{$tree_model->get_path_str($curr)} || die(''), 'add'); } else { if (!$tree_model->iter_has_child($curr)) { - gtkset_mousecursor_wait($tree->window); - ugtk2::flush(); + gtkset_mousecursor_wait($tree->get_window); + ugtk3::flush(); $add_exports->($curr); - gtkset_mousecursor_normal($tree->window); + gtkset_mousecursor_normal($tree->get_window); } $current_entry = undef; } @@ -249,7 +249,7 @@ sub add_smbnfs { gtknew('VBox', spacing => 7, children => [ 1, gtknew('HBox', spacing => 7, children_loose => [ gtkset($kind->{display_box}, width => 200), - $kind->{info_box}]), + $kind->{info_box} ]), 0, $kind->{action_box}, ]); |
