PageRenderTime 60ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/linkedfs/usr/lib/libDrakX/diskdrake/smbnfs_gtk.pm

https://bitbucket.org/harakiri/trk
Perl | 270 lines | 222 code | 45 blank | 3 comment | 24 complexity | 770881063174ea0d3d44497b1033f7f4 MD5 | raw file
Possible License(s): GPL-2.0, MIT, LGPL-3.0
  1. package diskdrake::smbnfs_gtk; # $Id: smbnfs_gtk.pm,v 1.33 2004/12/13 15:55:33 tvignaud Exp $
  2. use any;
  3. use fs::get;
  4. use diskdrake::interactive;
  5. use common;
  6. use interactive;
  7. use network::smb;
  8. use network::nfs;
  9. use ugtk2 qw(:helpers :wrappers :create);
  10. my ($all_hds, $in, $tree_model, $current_entry, $current_leaf, %icons);
  11. sub main {
  12. ($in, $all_hds, my $type) = @_;
  13. my ($kind) = $type eq 'smb' ? smb2kind() : nfs2kind();
  14. $kind->check($in) or return;
  15. my $w = ugtk2->new('DiskDrake');
  16. add_smbnfs($w->{window}, $kind);
  17. $w->{rwindow}->set_default_size(400, 300) if $w->{rwindow}->can('set_default_size');
  18. $w->{window}->show_all;
  19. $w->main;
  20. }
  21. ################################################################################
  22. # nfs/smb: helpers
  23. ################################################################################
  24. sub try {
  25. my ($kind, $name, @args) = @_;
  26. my $f = $diskdrake::interactive::{$name} or die "unknown function $name";
  27. try_($kind, $name, \&$f, @args);
  28. }
  29. sub try_ {
  30. my ($kind, $name, $f, @args) = @_;
  31. eval { $f->($in, @args, $all_hds) };
  32. if (my $err = $@) {
  33. $in->ask_warn(N("Error"), formatError($err));
  34. }
  35. update($kind);
  36. Gtk2->main_quit if member($name, 'Cancel', 'Done');
  37. }
  38. sub raw_hd_options {
  39. my ($in, $raw_hd) = @_;
  40. diskdrake::interactive::Options($in, {}, $raw_hd, fs::get::empty_all_hds());
  41. }
  42. sub raw_hd_mount_point {
  43. my ($in, $raw_hd) = @_;
  44. my ($default) = $raw_hd->{device} =~ m|([^/]+)$|;
  45. $default =~ s/\s+/-/g;
  46. diskdrake::interactive::Mount_point_raw_hd($in, $raw_hd, $all_hds, "/mnt/$default");
  47. }
  48. sub per_entry_info_box {
  49. my ($box, $kind, $entry) = @_;
  50. my $info = $entry ? diskdrake::interactive::format_raw_hd_info($entry) : '';
  51. $kind->{per_entry_info_box}->destroy if $kind->{per_entry_info_box};
  52. gtkpack($box, $kind->{per_entry_info_box} = gtkadd(Gtk2::Frame->new(N("Details")), gtkset_justify(Gtk2::Label->new($info), 'left')));
  53. }
  54. sub per_entry_action_box {
  55. my ($box, $kind, $entry) = @_;
  56. $_->destroy foreach $box->get_children;
  57. my @buttons;
  58. push @buttons, map {
  59. my $s = $_;
  60. gtksignal_connect(Gtk2::Button->new(translate($s)), clicked => sub { try($kind, $s, {}, $entry) });
  61. } (if_($entry->{isMounted}, N_("Unmount")),
  62. if_($entry->{mntpoint} && !$entry->{isMounted}, N_("Mount"))) if $entry;
  63. my @l = (
  64. if_($entry, N_("Mount point") => \&raw_hd_mount_point),
  65. if_($entry && $entry->{mntpoint}, N_("Options") => \&raw_hd_options),
  66. N_("Cancel") => sub {},
  67. N_("Done") => \&done,
  68. );
  69. push @buttons, map {
  70. my ($txt, $f) = @$_;
  71. $f ? gtksignal_connect(Gtk2::Button->new(translate($txt)), clicked => sub { try_($kind, $txt, $f, $entry) })
  72. : Gtk2::Label->new("");
  73. } group_by2(@l);
  74. gtkadd($box, gtkpack(Gtk2::HBox->new(0,0), @buttons));
  75. }
  76. sub done {
  77. my ($in) = @_;
  78. diskdrake::interactive::Done($in, $all_hds);
  79. }
  80. sub export_icon {
  81. my ($entry) = @_;
  82. $entry ||= {};
  83. $icons{$entry->{isMounted} ? 'mounted' : $entry->{mntpoint} ? 'has_mntpoint' : 'default'};
  84. }
  85. sub update {
  86. my ($kind) = @_;
  87. per_entry_action_box($kind->{action_box}, $kind, $current_entry);
  88. per_entry_info_box($kind->{info_box}, $kind, $current_entry);
  89. $tree_model->set($current_leaf, 0 => export_icon($current_entry)) if $current_entry;
  90. }
  91. sub find_fstab_entry {
  92. my ($kind, $e, $b_add_or_not) = @_;
  93. my $fs_entry = $kind->to_fstab_entry($e);
  94. if (my $fs_entry_ = find { $fs_entry->{device} eq $_->{device} } @{$kind->{val}}) {
  95. $fs_entry_;
  96. } elsif ($b_add_or_not) {
  97. push @{$kind->{val}}, $fs_entry;
  98. $fs_entry;
  99. } else {
  100. undef;
  101. }
  102. }
  103. sub import_tree {
  104. my ($kind, $info_box) = @_;
  105. my (%servers_displayed, %wservers, %wexports);
  106. $tree_model = Gtk2::TreeStore->new("Gtk2::Gdk::Pixbuf", "Glib::String");
  107. my $tree = Gtk2::TreeView->new_with_model($tree_model);
  108. $tree->get_selection->set_mode('browse');
  109. my $col = Gtk2::TreeViewColumn->new;
  110. $col->pack_start(my $pixrender = Gtk2::CellRendererPixbuf->new, 0);
  111. $col->add_attribute($pixrender, 'pixbuf', 0);
  112. $col->pack_start(my $texrender = Gtk2::CellRendererText->new, 1);
  113. $col->add_attribute($texrender, 'text', 1);
  114. $tree->append_column($col);
  115. $tree->set_headers_visible(0);
  116. foreach ('default', 'server', 'has_mntpoint', 'mounted') {
  117. $icons{$_} = gtkcreate_pixbuf("smbnfs_$_");
  118. }
  119. my $add_server = sub {
  120. my ($server) = @_;
  121. my $name = $server->{name} || $server->{ip};
  122. $servers_displayed{$name} ||= do {
  123. my $w = $tree_model->append_set(undef, [ 0 => $icons{server}, 1 => $name ]);
  124. $wservers{$tree_model->get_path_str($w)} = $server;
  125. $w;
  126. };
  127. };
  128. my $find_exports; $find_exports = sub {
  129. my ($server) = @_;
  130. my @l = eval { $kind->find_exports($server) };
  131. return @l if !$@;
  132. if ($server->{username}) {
  133. $in->ask_warn('', N("Can not login using username %s (bad password?)", $server->{username}));
  134. network::smb::remove_bad_credentials($server);
  135. } else {
  136. if (my @l = network::smb::authentications_available($server)) {
  137. my $user = $in->ask_from_list_(N("Domain Authentication Required"),
  138. N("Which username"), [ @l, N_("Another one") ]) or return;
  139. if ($user ne 'Another one') {
  140. network::smb::read_credentials($server, $user);
  141. goto $find_exports;
  142. }
  143. }
  144. }
  145. if ($in->ask_from(N("Domain Authentication Required"),
  146. N("Please enter your username, password and domain name to access this host."),
  147. [
  148. { label => N("Username"), val => \$server->{username} },
  149. { label => N("Password"), val => \$server->{password}, hidden => 1 },
  150. { label => N("Domain"), val => \$server->{domain} },
  151. ])) {
  152. goto $find_exports;
  153. } else {
  154. delete $server->{username};
  155. ();
  156. }
  157. };
  158. my $add_exports = sub {
  159. my ($node) = @_;
  160. my $path = $tree_model->get_path($node);
  161. $tree->expand_row($path, 0);
  162. 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
  163. my $s = $kind->to_string($_);
  164. my $w = $tree_model->append_set($node, [ 0 => export_icon(find_fstab_entry($kind, $_)),
  165. 1 => $s ]);
  166. $wexports{$tree_model->get_path_str($w)} = $_;
  167. }
  168. };
  169. {
  170. my $search = Gtk2::Button->new(N("Search servers"));
  171. gtkpack__($info_box,
  172. gtksignal_connect($search,
  173. clicked => sub {
  174. $add_server->($_) foreach sort { $a->{name} cmp $b->{name} } $kind->find_servers;
  175. $search->set_label(N("Search new servers"));
  176. }));
  177. }
  178. foreach (uniq(map { ($kind->from_dev($_->{device}))[0] } @{$kind->{val}})) {
  179. my $node = $add_server->({ name => $_ });
  180. $add_exports->($node);
  181. }
  182. $tree->get_selection->signal_connect(changed => sub {
  183. my ($_model, $curr) = $_[0]->get_selected;
  184. $curr or return;
  185. if ($tree_model->iter_parent($curr)) {
  186. $current_leaf = $curr;
  187. $current_entry = find_fstab_entry($kind, $wexports{$tree_model->get_path_str($curr)} || die(''), 'add');
  188. } else {
  189. if (!$tree_model->iter_has_child($curr)) {
  190. gtkset_mousecursor_wait($tree->window);
  191. ugtk2::flush();
  192. $add_exports->($curr);
  193. gtkset_mousecursor_normal($tree->window);
  194. }
  195. $current_entry = undef;
  196. }
  197. update($kind);
  198. });
  199. $tree;
  200. }
  201. sub add_smbnfs {
  202. my ($widget, $kind) = @_;
  203. die if $kind->{main_box};
  204. $kind->{info_box} = Gtk2::VBox->new(0,0);
  205. $kind->{display_box} = create_scrolled_window(import_tree($kind, $kind->{info_box}));
  206. $kind->{action_box} = Gtk2::HBox->new(0,0);
  207. $kind->{main_box} =
  208. gtkpack_(Gtk2::VBox->new(0,7),
  209. 1, gtkpack(Gtk2::HBox->new(0,7),
  210. gtkset_size_request($kind->{display_box}, 200, 0),
  211. $kind->{info_box}),
  212. 0, $kind->{action_box},
  213. );
  214. $widget->add($kind->{main_box});
  215. $current_entry = undef;
  216. update($kind);
  217. $kind;
  218. }
  219. sub nfs2kind() {
  220. network::nfs->new({ type => 'nfs', name => 'NFS', val => $all_hds->{nfss}, no_auto => 1 });
  221. }
  222. sub smb2kind() {
  223. network::smb->new({ type => 'smb', name => 'Samba', val => $all_hds->{smbs}, no_auto => 1 });
  224. }
  225. 1;