#!/usr/bin/perl # # Copyright (C) 2005 by Mandriva aginies _ateuh_ mandriva.com # # 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, 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 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. my $version = "0.1 test release"; use strict; use lib qw(/usr/lib/libDrakX); use standalone; use common; use network::network; use interactive; use ugtk2 qw(:ask :wrappers :create :dialogs); use mygtk2 qw(gtknew); # use libconf use Libconf::Templates; use Libconf::Glueconf::Samba::Smb_conf; my $in = 'interactive'->vnew('su'); $in->do_pkgs->ensure_is_installed('samba-server', '/usr/sbin/smbd') or return; local *COLUMN_SHARE_NAME; use constant COLUMN_SHARE_NAME => 0; local *COLUMN_PATH; use constant COLUMN_PATH => 1; local *COLUMN_COMMENT; use constant COLUMN_COMMENT => 2; local *COLUMN_BROWSEABLE; use constant COLUMN_BROWSEABLE => 3; local *COLUMN_PUBLIC; use constant COLUMN_PUBLIC => 4; local *COLUMN_WRITABLE; use constant COLUMN_WRITABLE => 5; local *COLUMN_CREATE_MASK; use constant COLUMN_CREATE_MASK => 6; local *COLUMN_DIRECTORY_MASK; use constant COLUMN_DIRECTORY_MASK => 7; local *COLUMN_READ_LIST; use constant COLUMN_READ_LIST => 8; local *COLUMN_WRITE_LIST; use constant COLUMN_WRITE_LIST => 9; local *COLUMN_ADMIN_USERS; use constant COLUMN_ADMIN_USERS => 10; local *COLUMN_VALID_USERS; use constant COLUMN_VALID_USERS => 11; local *COLUMN_HIDE_DOT_FILES; use constant COLUMN_HIDE_DOT_FILES => 12; local *COLUMN_HIDE_FILES; use constant COLUMN_HIDE_FILES => 13; local *COLUMN_PRESERVE_CASE; use constant COLUMN_PRESERVE_CASE => 14; local *COLUMN_FORCE_CREATE_MODE; use constant COLUMN_FORCE_CREATE_MODE => 15; local *COLUMN_FORCE_GROUP; use constant COLUMN_FORCE_GROUP => 16; local *COLUMN_DEFAULT_CASE; use constant COLUMN_DEFAULT_CASE => 17; local *COLUMN_INHERIT_PERMISSIONS; use constant COLUMN_INHERIT_PERMISSIONS => 18; use constant COLUMN_PRINTABLE => 4; use constant COLUMN_PRINT_COMMAND => 5; use constant COLUMN_GUEST_OK => 6; my $samba = new Libconf::Glueconf::Samba::Smb_conf({ filename => '/etc/samba/smb.conf', show_commented_info => 1 }); my (@listshare, @listprinters); my @yesno = qw(yes no); push @yesno, ""; my @default_case = qw(upper lower); push @default_case, ""; my %adv_options = ( read_list => N("Read List"), write_list => N("Write List"), admin_users => N("Admin users"), valid_users => N("Valid users"), hide_dot_files => N("Hide dot files"), hide_files => N("Hide files"), force_group => N("Force Group"), force_create_mode => N("Force create group"), default_case => N("Default case"), preserve_case => N("Preserve case"), create_mask => N("Create mask"), directory_mask => N("Directory mask"), inherit_permissions => N("Inherit permissions"), ); sub get_items() { my @items = ( [ "/_File", undef, undef, undef, '', ], [ "/_File/_Write conf", undef, \&write_conf, 1, '', 'gtk-execute' ], [ "/_File/_Exit", undef, \&quit_all, 1, '', 'gtk-quit' ], [ "/_Samba Server", undef, undef, undef, '', ], [ "/_Samba Server/_Restart", undef, \&restart_dialog, 1, '', 'gtk-execute' ], [ "/_Samba Server/R_eload", undef, \&reload_dialog, 1, '', 'gtk-refresh' ], ); return @items; } sub quit_all() { ugtk2->exit; } sub restart_dialog() { wait_action("service smb restart"); } sub reload_dialog() { wait_action("service smb reload"); } sub wait_action { my ($cmd) = @_; my $w = $in->wait_message(N("Samba server"), N("Restarting/Reloading Samba server...")); run_program::get_stdout($cmd) !~ /unknown|error/ or err_dialog(N("Error!"), N("Error Restarting/Reloading Samba server")) and return; undef $w; } my %size_groups = map { $_ => Gtk2::SizeGroup->new('horizontal') } qw(label widget button); my $label_and_widgets = sub { my ($label, $widget, $button) = @_; gtkpack_(Gtk2::HBox->new(0,1), 0, gtkadd_widget($size_groups{label}, $label), 0, gtkadd_widget($size_groups{widget}, $widget), 0, gtkadd_widget($size_groups{button}, $button), ); }; my $fdwidget = sub { my ($data) = @_; my $fd = new Gtk2::FileSelection(N("Directory Selection")); $fd->set_modal(1); $fd->signal_connect("destroy", sub { $fd->hide }); $fd->ok_button->signal_connect(clicked => sub { my $file = $fd->get_filename; -d $file or err_dialog(N("Error!"), N("Should be a directory.")) and return; $data->set_text($file); $fd->hide; }, $fd); $fd->cancel_button->signal_connect(clicked => sub { $fd->hide }); return $fd; }; sub get_samba_share() { undef @listshare; foreach my $clef (keys %$samba) { if ($samba->{$clef}{printable} =~ /yes/i || $clef =~ /print\$/) { print "$clef is a printer\n"; } elsif ($clef =~ /global/ || $clef =~ /cdrom$/ || $clef eq "Profiles") { print "unwanted (special shares)\n"; } else { push @listshare, { share_name => $clef, path => $samba->{$clef}{path}, comment => $samba->{$clef}{comment}, browseable => $samba->{$clef}{browseable}, public => $samba->{$clef}{public}, writable => $samba->{$clef}{writable}, create_mask => $samba->{$clef}{'create mask'}, directory_mask => $samba->{$clef}{'directory mask'}, read_list => $samba->{$clef}{'read list'}, write_list => $samba->{$clef}{'write list'}, admin_users => $samba->{$clef}{'admin users'}, valid_users => $samba->{$clef}{'valid users'}, hide_dot_files => $samba->{$clef}{'hide dot files'}, hide_files => $samba->{$clef}{'hide files'}, preserve_case => $samba->{$clef}{'preserve case'}, force_create_mode => $samba->{$clef}{'force create mode'}, force_group => $samba->{$clef}{'force group'}, default_case => $samba->{$clef}{'default case'}, inherit_permissions => $samba->{$clef}{'inherit permissions'}, }; } } return @listshare; } sub get_samba_printers() { undef @listprinters; foreach my $clef (keys %$samba) { if ($samba->{$clef}{printable} =~ /yes/i || $clef =~ /print\$/) { push @listprinters, { share_name => $clef, path => $samba->{$clef}{path}, comment => $samba->{$clef}{comment}, browseable => $samba->{$clef}{browseable}, printable => $samba->{$clef}{printable}, print_command => $samba->{$clef}{'print command'}, guest_ok => $samba->{$clef}{'guest ok'}, }; } } return @listprinters; } sub create_smbuser { my ($list) = @_; my @users = split(" ", $list); foreach my $user (@users) { if (!any { /^$user:/ } cat_("/etc/samba/smbpasswd")) { system("smbpasswd -a $user -n"); } } } sub write_conf() { $samba->write_conf("/etc/samba/smb.conf"); } sub create_pango_help_box { # perl code from draksec my ($help) = @_; my $text = Gtk2::TextView->new; use Gtk2::Pango; my %common_opts = ('left-margin' => '10', 'right-margin' => '10'); gtktext_insert($text, [ map { if (s!^/span>!!) { [ $_, \%common_opts ]; } elsif (s!span !!) { my %tags = %common_opts; while (s!(\w+?)="(\w+?)"!!) { $tags{weight} ||= Gtk2::Pango->PANGO_WEIGHT_BOLD if $1 eq 'foreground'; $tags{$1} = $2 eq "bold" ? Gtk2::Pango->PANGO_WEIGHT_BOLD : $2; } s/^>//; [ $_, \%tags ]; } else { [ $_, \%common_opts ]; } } split("<", formatAlaTeX($help)) ]); gtkset_size_request(create_scrolled_window($text), 350, 300); } sub help_b { my ($help_data) = @_; gtksignal_connect(new Gtk2::Button->new_from_stock('gtk-dialog-info'), clicked => sub { my $dialog = _create_dialog(); $dialog->set_transient_for($::main_window); $dialog->set_title(N("Help")); $dialog->set_modal(1); gtkpack_($dialog->vbox, 1, create_pango_help_box($help_data), 0, gtksignal_connect(Gtk2::Button->new_from_stock('gtk-close'), clicked => sub { $dialog->destroy; } ), ); $dialog->show_all; } ); } sub add_entry { my ($treeview) = @_; my $model = $treeview->get_model; use wizards; my ($wiz_addshare_name, $wiz_addshare_comment, $wiz_addshare_path, $wiz_addshare_browseable, $wiz_addshare_public); my $w = wizards->new; my $wiz = { name => N("Add a Samba share"), pages => { welcome => { name => N("Goal of this wizard is to easily create a new Samba share."), no_back => 1, next => 'add_share', }, add_share => { name => N("Add a Samba share"), data => [ { label => N("Name of the share:"), val => \$wiz_addshare_name }, { label => N("Comment:"), val => \$wiz_addshare_comment }, { label => N("Path:"), val => \$wiz_addshare_path }, ], complete => sub { foreach my $clef (keys %$samba) { if ($clef =~ /$wiz_addshare_name/) { err_dialog(N("Error"), N("Share with the same name already exist or share name empty, please choose another name.")) and return 'add_img'; } } if (!$wiz_addshare_path) { err_dialog(N("Error"), N("Can\'t create the directory, please enter a correct path.")) and return 'add_share'; } if (!$wiz_addshare_comment) { err_dialog(N("Error"), N("Please enter a Comment for this share.")) and return 'add_share'; } if (! -d $wiz_addshare_path) { mkdir_p($wiz_addshare_path) or err_dialog(N("Error"), N("Can\'t create the directory, please enter a correct path.")) and return 'add_share'; } }, post => sub { # update iter my $iter = $model->append; $model->set($iter, COLUMN_SHARE_NAME, $wiz_addshare_name, COLUMN_PATH, $wiz_addshare_path, COLUMN_COMMENT, $wiz_addshare_comment, ); my $share = $wiz_addshare_name; # update listshare push @listshare, { share_name => $share, path => $wiz_addshare_path, comment => $wiz_addshare_comment, }; # update samba conf $samba->{$share}; $samba->{$share}{path} = $wiz_addshare_path; $samba->{$share}{comment} = $wiz_addshare_comment; return; }, next => 'end_add', }, end_add => { name => N("Congratulations"), data => [ { label => N("The wizard successfully added the Samba share. Now just double click on it in treeview to modify it") } ], no_back => 1, end => 1, next => 0, }, } }; $w->process($wiz, $in); $::isWizard = 0; gtkset_mousecursor_normal(); } sub modify_printers_entry { my ($treeview) = @_; my $model = $treeview->get_model; my $selection = $treeview->get_selection; my ($dir, $i, $path, $comment, $print_command, $guest_ok, $share_name, $browseable, $printable); $share_name = Gtk2::Label->new; $_ = Gtk2::Entry->new foreach $dir, $path, $comment, $print_command; $_ = Gtk2::OptionMenu->new foreach $browseable, $printable, $guest_ok; $_->set_popdown_strings(@yesno) foreach $browseable, $printable, $guest_ok; my $iter = $selection->get_selected; $iter or info_dialog(N("Error"), N("Please add or select a Samba printer share to be able to modify it.")) and return; $path = $model->get_path($iter); $i = ($path->get_indices)[0]; $share_name->set_text($listprinters[$i]{share_name}); $dir->set_text($listprinters[$i]{path}); $comment->set_text($listprinters[$i]{comment}); $browseable->set_text($listprinters[$i]{browseable}); $guest_ok->set_text($listprinters[$i]{guest_ok}); $printable->set_text($listprinters[$i]{printable}); $print_command->set_text($listprinters[$i]{print_command}); my $file_dialog = $fdwidget->($dir, ""); my $button = Gtk2::Button->new_from_stock('gtk-open'); $button->signal_connect(clicked => sub { $file_dialog->show }); my $dialog = _create_dialog(); $dialog->set_transient_for($::main_window); local $::main_window = $dialog; $dialog->set_title("DrakSamba Printers entry"); $dialog->set_position('center'); $dialog->set_modal(1); $dialog->set_resizable(1); gtkpack_($dialog->vbox, 0, gtkadd(Gtk2::Frame->new(N("Printer share")), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), 0, $label_and_widgets->(N("Printer name:"), $share_name, ""), 0, $label_and_widgets->(N("Directory:"), $dir, $button), ), ), 0, gtkadd(Gtk2::Frame->new(N("Options")), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), 0, $label_and_widgets->(N("Printable"), $printable, ""), 0, $label_and_widgets->(N("Browseable:"), $browseable, ""), 0, $label_and_widgets->(N("Guest ok:"), $guest_ok, ""), 0, $label_and_widgets->(N("Print command:"), $print_command, ""), ), ), 0, create_okcancel({ cancel_clicked => sub { $dialog->destroy }, ok_clicked => sub { $dialog->destroy; } }, ), ); $dialog->show_all; } sub modify_entry { my ($treeview) = @_; my $model = $treeview->get_model; my $selection = $treeview->get_selection; my $iter; my ($dir, $i, $path, $comment, $create_mask, $directory_mask, $read_list, $write_list, $admin_users, $valid_users, $force_group, $browseable, $public, $writable, $hide_files, $hide_dot_files, $force_create_mode, $preserve_case, $default_case, $inherit_permissions, $share_name); $share_name = Gtk2::Label->new; $_ = Gtk2::Entry->new foreach $dir, $path, $comment, $create_mask, $directory_mask; $_ = Gtk2::Entry->new foreach $read_list, $write_list, $admin_users, $valid_users, $force_group, $force_create_mode; $_ = Gtk2::OptionMenu->new foreach $browseable, $public, $writable, $default_case, $preserve_case, $hide_files, $hide_dot_files, $inherit_permissions; $default_case->set_popdown_strings(@default_case); $_->set_popdown_strings(@yesno) foreach $browseable, $public, $writable, $hide_files, $hide_dot_files, $preserve_case, $inherit_permissions; my $file_dialog = $fdwidget->($dir, ""); my $button = Gtk2::Button->new_from_stock('gtk-open'); $button->signal_connect(clicked => sub { $file_dialog->show }); my $w = ugtk2->new(N("DrakSamba entry")); $w->{window}->set_modal(1); $iter = $selection->get_selected; $iter or info_dialog(N("Error"), N("Please add or select a Samba share to be able to modify it.")) and return; $path = $model->get_path($iter); $i = ($path->get_indices)[0]; $share_name->set_text($listshare[$i]{share_name}); $dir->set_text($listshare[$i]{path}); $comment->set_text($listshare[$i]{comment}); $browseable->set_text($listshare[$i]{browseable}); $public->set_text($listshare[$i]{public}); $writable->set_text($listshare[$i]{writable}); $create_mask->set_text($listshare[$i]{create_mask}); $directory_mask->set_text($listshare[$i]{directory_mask}); $read_list->set_text($listshare[$i]{read_list}); $write_list->set_text($listshare[$i]{write_list}); $admin_users->set_text($listshare[$i]{admin_users}); $valid_users->set_text($listshare[$i]{valid_users}); $force_group->set_text($listshare[$i]{force_group}); $force_create_mode->set_text($listshare[$i]{force_create_mode}); $default_case->set_text($listshare[$i]{default_case}); $preserve_case->set_text($listshare[$i]{preserve_case}); $hide_files->set_text($listshare[$i]{hide_files}); $hide_dot_files->set_text($listshare[$i]{hide_dot_files}); $inherit_permissions->set_text($listshare[$i]{inherit_permissions}); my $expander_user = Gtk2::Expander->new('User options (user access, mask option, force mode)'); $expander_user->add(gtkpack_(Gtk2::HBox->new, 0, gtkadd(Gtk2::Frame->new(N("Samba user access")), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1), 0, $label_and_widgets->($adv_options{read_list}, $read_list, ""), 0, $label_and_widgets->($adv_options{write_list}, $write_list, ""), 0, $label_and_widgets->($adv_options{admin_users}, $admin_users, ""), 0, $label_and_widgets->($adv_options{valid_users}, $valid_users, ""), ), ), 0, gtkadd(Gtk2::Frame->new(N("Mask options")), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1), 0, $label_and_widgets->($adv_options{create_mask}, $create_mask, ""), 0, $label_and_widgets->($adv_options{directory_mask}, $directory_mask, ""), 0, $label_and_widgets->($adv_options{force_group}, $force_group, ""), 0, $label_and_widgets->($adv_options{force_create_mode}, $force_create_mode, ""), 0, $label_and_widgets->($adv_options{inherit_permissions}, $inherit_permissions, ""), ), ), ), ); my $expander_file = Gtk2::Expander->new('File options (hide files, case)'); $expander_file->add(gtkpack_(Gtk2::VBox->new, 0, gtkadd(Gtk2::Frame->new(N("Display options")), gtkpack_(gtkset_border_width(Gtk2::HBox->new, 1), 0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 0), 0, $label_and_widgets->($adv_options{hide_dot_files}, $hide_dot_files, ""), 0, $label_and_widgets->($adv_options{hide_files}, $hide_files, ""), ), 0, Gtk2::VSeparator->new, 0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 0), 0, $label_and_widgets->($adv_options{default_case}, $default_case, ""), 0, $label_and_widgets->($adv_options{preserve_case}, $preserve_case, ""), ), ), ), ), ); $_->signal_connect(activate => sub { $w->shrink_topwindow; # gtkflush(); }) foreach $expander_file, $expander_user; gtkadd($w->{window}, gtknew('VBox', spacing => 0, children_loose => [ gtkadd(Gtk2::Frame->new(N("Samba share directory")), gtkpack_(gtkset_border_width(Gtk2::HBox->new, 1), 0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 0), 0, $label_and_widgets->(N("Share name:"), $share_name), 0, $label_and_widgets->(N("Directory:"), $dir, $button), 0, $label_and_widgets->(N("Comment:"), $comment, ""), ), 0, Gtk2::VSeparator->new, 0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 0), 0, $label_and_widgets->(N("Public:"), $public, ""), 0, $label_and_widgets->(N("Writable:"), $writable, ""), 0, $label_and_widgets->(N("Browseable:"), $browseable, ""), ), ), ), gtkadd(Gtk2::Frame->new("Advanced options"), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1), 0, $expander_user, 0, Gtk2::HSeparator->new, 0, $expander_file, ), ), create_okcancel({ cancel_clicked => sub { $w->destroy }, ok_clicked => sub { my $share = $share_name->get_text; my $test_dir = $dir->get_text; $comment->get_text or err_dialog(N("Information"), N("Please enter a Comment for this share.")) and return 1; if ($share !~ /^homes$/ and !-d $test_dir) { err_dialog(N("Error!"), N("Please enter a directory to share.")) and return; } foreach ($create_mask->get_text, $directory_mask->get_text) { if ($_ && !/^\d+$/) { err_dialog(N("Error"), N("Create mask, create mode and directory mask should be numeric. ie: 0755.")) and return 1; } } # update gui treeview $model->set($iter, COLUMN_SHARE_NAME, $share_name->get_text, COLUMN_PATH, $dir->get_text, COLUMN_COMMENT, $comment->get_text, COLUMN_BROWSEABLE, $browseable->get_text, COLUMN_PUBLIC, $public->get_text, COLUMN_WRITABLE, $writable->get_text, COLUMN_CREATE_MASK, $create_mask->get_text, COLUMN_DIRECTORY_MASK, $directory_mask->get_text, COLUMN_READ_LIST, $read_list->get_text, COLUMN_WRITE_LIST, $write_list->get_text, COLUMN_ADMIN_USERS, $admin_users->get_text, COLUMN_VALID_USERS, $valid_users->get_text, COLUMN_HIDE_DOT_FILES, $hide_dot_files->get_text, COLUMN_HIDE_FILES, $hide_files->get_text, COLUMN_PRESERVE_CASE, $preserve_case->get_text, COLUMN_FORCE_CREATE_MODE, $force_create_mode->get_text, COLUMN_FORCE_GROUP, $force_group->get_text, COLUMN_DEFAULT_CASE, $default_case->get_text, COLUMN_INHERIT_PERMISSIONS, $inherit_permissions->get_text, ); # update $samba with the new value # $samba->{$share}; $samba->{$share}{path} = $dir->get_text; $samba->{$share}{comment} = $comment->get_text; $browseable->get_text and $samba->{$share}{browseable} = $browseable->get_text || delete $samba->{$share}{browseable}; $public->get_text and $samba->{$share}{public} = $public->get_text || delete $samba->{$share}{public}; $writable->get_text and $samba->{$share}{writable} = $writable->get_text || delete $samba->{$share}{writable}; $create_mask->get_text and $samba->{$share}{'create mask'} = $create_mask->get_text || delete $samba->{$share}{'create mask'}; $directory_mask->get_text and $samba->{$share}{'directory mask'} = $directory_mask->get_text || delete $samba->{$share}{'directory mask'}; $read_list->get_text and $samba->{$share}{'read list'} = $read_list->get_text || delete $samba->{$share}{'read list'}; $write_list->get_text and $samba->{$share}{'write list'} = $write_list->get_text || delete $samba->{$share}{'write list'}; $admin_users->get_text and $samba->{$share}{'admin users'} = $admin_users->get_text || delete $samba->{$share}{'admin users'}; $valid_users->get_text and $samba->{$share}{'valid users'} = $valid_users->get_text || delete $samba->{$share}{'valid users'}; $hide_dot_files->get_text and $samba->{$share}{'hide dot files'} = $hide_dot_files->get_text || delete $samba->{$share}{'hide dot files'}; $hide_files->get_text and $samba->{$share}{'hide files'} = $hide_files->get_text || delete $samba->{$share}{'hide files'}; $preserve_case->get_text and $samba->{$share}{'preserve case'} = $preserve_case->get_text || delete $samba->{$share}{'preserve case'}; $force_create_mode->get_text and $samba->{$share}{'force create mode'} = $force_create_mode->get_text || delete $samba->{$share}{'force create mode'}; $force_group->get_text and $samba->{$share}{'force group'} = $force_group->get_text || delete $samba->{$share}{'force group'}; $default_case->get_text and $samba->{$share}{'default case'} = $default_case->get_text || delete $samba->{$share}{'default case'}; $inherit_permissions->get_text and $samba->{$share}{'inherit permissions'} = $inherit_permissions->get_text || delete $samba->{$share}{'inherit permissions'}; $w->destroy; }, }, ), ] ), ); $w->{window}->show_all; } sub remove_entry { my ($treeview, $type) = @_; my $model = $treeview->get_model; my $selection = $treeview->get_selection; my $iter = $selection->get_selected; my $share; if ($iter) { my $path = $model->get_path($iter); my $i = ($path->get_indices)[0]; if ($type eq 'share') { $share = $listshare[$i]{share_name}; } else { $share = $listprinters[$i]{share_name}; } ask_okcancel("Remove entry ?", "Remove $share") or return; $model->remove($iter); if ($type eq 'share') { splice @listshare, $i, 1 } else { splice @listshare, $i, 1 } delete $samba->{$share}; } } sub create_model() { get_samba_share(); my $model = Gtk2::ListStore->new("Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String"); foreach my $a (@listshare) { my $iter = $model->append; $model->set($iter, COLUMN_SHARE_NAME, $a->{share_name}, COLUMN_PATH, $a->{path}, COLUMN_COMMENT, $a->{comment}, COLUMN_BROWSEABLE, $a->{browseable}, COLUMN_PUBLIC, $a->{public}, COLUMN_WRITABLE, $a->{writable}, COLUMN_CREATE_MASK, $a->{create_mask}, COLUMN_DIRECTORY_MASK, $a->{directory_mask}, COLUMN_READ_LIST, $a->{read_list}, COLUMN_WRITE_LIST, $a->{write_list}, COLUMN_ADMIN_USERS, $a->{admin_users}, COLUMN_VALID_USERS, $a->{valid_users}, COLUMN_HIDE_DOT_FILES, $a->{hide_dot_files}, COLUMN_HIDE_FILES, $a->{hide_files}, COLUMN_PRESERVE_CASE, $a->{preserve_case}, COLUMN_FORCE_CREATE_MODE, $a->{force_create_mode}, COLUMN_FORCE_GROUP, $a->{force_group}, COLUMN_DEFAULT_CASE, $a->{default_case}, COLUMN_INHERIT_PERMISSIONS, $a->{inherit_permissions}, ); } return $model; } sub create_model_printers() { get_samba_printers(); my $model_printers = Gtk2::ListStore->new("Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String"); foreach my $a (@listprinters) { my $iter = $model_printers->append; $model_printers->set($iter, COLUMN_SHARE_NAME, $a->{share_name}, COLUMN_PATH, $a->{path}, COLUMN_COMMENT, $a->{comment}, COLUMN_BROWSEABLE, $a->{browseable}, COLUMN_PRINTABLE, $a->{printable}, COLUMN_PRINT_COMMAND, $a->{print_command}, COLUMN_GUEST_OK, $a->{guest_ok}, ); } return $model_printers; } # add colum to model sub add_columns { my $treeview = shift; # my $model = $treeview->get_model; each_index { my $renderer = Gtk2::CellRendererText->new; $renderer->set_data(column => $::i); $treeview->insert_column_with_attributes(-1, $_, $renderer, 'text' => $::i); } N("Share name"), N("Share directory"), N("Comment"), N("Browseable"), N("Public"), N("Writable"), N("Create mask"), N("Directory mask"), N("Read list"), N("Write list"), N("Admin users"), N("Valid users"), N("Hide dot files"), N("Hide files"), N("Preserve case"), N("Force create mode"), N("Force group"), N("Default case"), N("Inherit Permissions"); } sub add_columns_printers { my $treeview_printers = shift; each_index { my $renderer = Gtk2::CellRendererText->new; $renderer->set_data(column => $::i); $treeview_printers->insert_column_with_attributes(-1, $_, $renderer, 'text' => $::i); } N("Printer name"), N("Share directory"), N("Comment"), N("Browseable"), N("Printable"), N("Print Command"), N("Guest OK"); } ############### # Main Program ############### # create model my $model = create_model(); my $model_printers = create_model_printers(); my $window = ugtk2->new("DrakSamba $version"); $::main_window = $window->{real_window}; $window->{rwindow}->set_size_request(550, 400) unless $::isEmbedded; $window->{rwindow}->set_position('center') if !$::isEmbedded; my $W = $window->{window}; $W->signal_connect(delete_event => sub { ugtk2->exit }); my $treeview = Gtk2::TreeView->new_with_model($model); add_columns($treeview); my $treeview_printers = Gtk2::TreeView->new_with_model($model_printers); add_columns_printers($treeview_printers); $_->set_rules_hint(1) foreach $treeview_printers, $treeview; $_->get_selection->set_mode('single') foreach $treeview_printers, $treeview; # double clic and popup modify window $treeview->signal_connect(button_press_event => sub { my (undef, $event) = @_; $treeview->get_selection->get_selected and modify_entry($treeview) if $event->type eq '2button-press'; }); $treeview_printers->signal_connect(button_press_event => sub { my (undef, $event) = @_; $treeview_printers->get_selection->get_selected and modify_printers_entry($treeview_printers) if $event->type eq '2button-press'; }); # create menu my @items = get_items(); my $factory = Gtk2::ItemFactory->new('Gtk2::MenuBar', '
', undef); $factory->create_items('menu', @items); my $menu = $factory->get_widget('
'); my $okcancel = create_okcancel({ cancel_clicked => sub { ugtk2->exit }, ok_clicked => sub { write_conf; ugtk2->exit }, }, ); gtkappend_page(my $nb = Gtk2::Notebook->new, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 0), 1, create_scrolled_window($treeview), 0, gtkpack_(create_vbox('start'), 0, gtksignal_connect(Gtk2::Button->new(N("Add")), clicked => sub { eval { add_entry($treeview) }; my $err = $@; $::WizardWindow->destroy if defined $::WizardWindow; undef $::WizardWindow; if ($err && $err !~ /wizcancel/) { err_dialog(N("Error"), N("Failed to add Samba share.") . "\n\n" . $err); } }), 0, Gtk2::HSeparator->new, 0, gtksignal_connect(Gtk2::Button->new(N("Modify")), clicked => sub { eval { modify_entry($treeview) }; my $err = $@; if ($err) { err_dialog(N("Error"), N("Failed to Modify Samba share.") . "\n\n" . $err); } }), 0, gtksignal_connect(Gtk2::Button->new(N("Remove")), clicked => sub { eval { remove_entry($treeview, "share") }; my $err = $@; if ($err) { err_dialog(N("Error"), N("Failed to remove a Samba share.") . "\n\n" . $err); } }), ), ), gtkshow(Gtk2::Label->new(N("File Share")))); gtkappend_page($nb, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 0), 1, create_scrolled_window($treeview_printers), 0, gtkpack_(create_vbox('start'), # 0, gtksignal_connect(Gtk2::Button->new(N("Add pdf-gen")), clicked => sub { # eval { add_pdfgen_entry($treeview_printers) }; # my $err = $@; # if ($err) { # err_dialog(N("Error"), N("Failed to add pdf-gen.") . "\n\n" . $err); # } # }), # 0, gtksignal_connect(Gtk2::Button->new(N("Add printers")), clicked => sub { # eval { add_printers_entry($treeview_printers) }; # my $err = $@; # if ($err) { # err_dialog(N("Error"), N("Failed to add printers.") . "\n\n" . $err); # } # }), # 0, Gtk2::HSeparator->new, 0, gtksignal_connect(Gtk2::Button->new(N("Modify")), clicked => sub { eval { modify_printers_entry($treeview_printers) }; my $err = $@; if ($err) { err_dialog(N("Error"), N("Failed to Modify.") . "\n\n" . $err); } }), 0, gtksignal_connect(Gtk2::Button->new(N("Remove")), clicked => sub { eval { remove_entry($treeview_printers, "printers") }; my $err = $@; if ($err) { err_dialog(N("Error"), N("Failed to remove.") . "\n\n" . $err); } }), ), ), gtkshow(Gtk2::Label->new(N("Printers")))); $nb->set_show_border(0); # main interface $W->add(gtkpack_(Gtk2::VBox->new(0,0), 0, $menu, if_(!$::isEmbedded, 0, Gtk2::Banner->new('drakgw', N("DrakSamba manage Samba shares"))), if_($::isEmbedded, 0, Gtk2::Label->new("Here you can add, remove and alter Samba shares.")), 1, $nb, 0, $okcancel, ), ); $W->show_all; Gtk2->main;