diff options
-rwxr-xr-x | bin/draksambashare | 1259 |
1 files changed, 1259 insertions, 0 deletions
diff --git a/bin/draksambashare b/bin/draksambashare new file mode 100755 index 0000000..bd29dfc --- /dev/null +++ b/bin/draksambashare @@ -0,0 +1,1259 @@ +#!/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.2"; + +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 Gtk2::SimpleList; +use Gtk2::Gdk::Keysyms; + +# 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; + +#if (!-f "/etc/sysconfig/wizard_samba") { +# $in->do_pkgs->ensure_is_installed('drakwizard', '/usr/sbin/drakwizard'); +# err_dialog(N("Error"), N("Please setup a samba server")) and return; +#} + + +my $icon_path = "/usr/lib/libDrakX/icons"; +my $fileshare_icon = "$icon_path/IC-winacces2-16.png"; +my $printershare_icon = "$icon_path/IC-sambaprt-16.png"; +my $sambauser_icon = "$icon_path/ic82-users-16.png"; +my $pixbuf_file = Gtk2::Gdk::Pixbuf->new_from_file($fileshare_icon); +my $pixbuf_printer = Gtk2::Gdk::Pixbuf->new_from_file($printershare_icon); +my $pixbuf_user = Gtk2::Gdk::Pixbuf->new_from_file($sambauser_icon); + +my $printer_list = create_printer_list(); +my $share_list = create_share_list(); +my $user_list = create_user_list(); + +sub create_user_list() { + my $user_list = Gtk2::SimpleList->new('' => 'pixbuf', + N("User name") => 'text', + ); + $user_list; +} + +sub create_share_list() { + my $share_list = Gtk2::SimpleList->new('' => 'pixbuf', + N("Share name") => 'text', + N("Share directory") => 'text', + N("Comment") => 'text', + N("Browseable") => 'text', + N("Public") => 'text', + N("Writable") => 'text', + N("Create mask") => 'text', + N("Directory mask") => 'text', + N("Read list") => 'text', + N("Write list") => 'text', + N("Admin users") => 'text', + N("Valid users") => 'text', + N("Inherit Permissions") => 'text', + N("Hide dot files") => 'text', + N("Hide files") => 'text', + N("Preserve case") => 'text', + N("Force create mode") => 'text', + N("Force group") => 'text', + N("Default case") => 'text', + ); + $share_list->set_headers_clickable(1); + foreach ($share_list->get_columns) { + $_->set_resizable(1); + } + foreach (1, 2, 3) { + $share_list->get_column($_)->signal_connect('clicked', \&sort_by_column, $share_list->get_model); + $share_list->get_column($_)->set_sort_column_id($_ == 0 ? 1 : $_ + 2); + } + $share_list; +} + +sub create_printer_list() { + my $printer_list = Gtk2::SimpleList->new('' => 'pixbuf', + N("Printer name") => 'text', + N("Path") => 'text', + N("Comment") => 'text', + N("Browseable") => 'text', + N("Printable") => 'text', + N("Print Command") => 'text', + N("LPQ command") => 'text', + N("Guest ok") => 'text', + N("Writable") => 'text', + N("Write list") => 'text', + N("Inherit permissions") => 'text', + N("Printing") => 'text', + N("Create mode") => 'text', + N("Use client driver") => 'text', + ); + $printer_list->set_headers_clickable(1); + foreach (1, 2, 3) { + $printer_list->get_column($_)->signal_connect('clicked', \&sort_by_column, $printer_list->get_model); + $printer_list->get_column($_)->set_sort_column_id($_ == 0 ? 1 : $_ + 2); + } + $printer_list; +} + +sub sort_by_column { + my ($column, $model) = @_; + my $col_id = $column->get_sort_column_id; + my ($old_id, $old_order) = $model->get_sort_column_id; + $model->set_sort_column_id($col_id, $old_id == $col_id && $old_order ne 'descending' ? 'ascending' : 'descending'); +} + +#path comment browseable printable print command guest ok writable write list inherit permissions printing lpq command create mode use client driver + + +my $samba = new Libconf::Glueconf::Samba::Smb_conf({ filename => '/etc/samba/smb.conf'}); +my (@listshare, @listprinters, @listusers); +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, '<Branch>', ], + [ "/_File/_Write conf", undef, \&write_conf, 1, '<StockItem>', 'gtk-execute' ], + [ "/_File/_Exit", undef, \&quit_all, 1, '<StockItem>', 'gtk-quit' ], + + [ "/_Samba Server", undef, undef, undef, '<Branch>', ], + [ "/_Samba Server/_Restart", undef, \&restart_dialog, 1, '<StockItem>', 'gtk-execute' ], + [ "/_Samba Server/R_eload", undef, \&reload_dialog, 1, '<StockItem>', 'gtk-refresh' ], + + [ "/_About/Report a bug", undef, sub { unless (fork()) { exec("drakbug --report draksambashare &") } }, 1, '<StockItem>', 'gtk-stop' ], + [ "/_About/About...", undef, sub { + create_dialog(N("About Draksambashare"), N("Mandriva Linux \nRelease: %s\nAuthor: Antoine Ginies\n\nThis is a simple tool to easily manage Samba configuration.", $version)); + }, 1, '<StockItem>', 'gtk-preferences' ], + ); + 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), + if_($button, 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_user() { + undef @listusers; + foreach (cat_("/etc/samba/smbpasswd")) { + my ($user) = m!^(\w+):!; + $user and push @listusers, { + user_name => $user, + }; + } + return @listusers; +} + + +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'}, + lpq_command => $samba->{$clef}{'lpq command'}, + guest_ok => $samba->{$clef}{'guest ok'}, + writable => $samba->{$clef}{writable}, + write_list => $samba->{$clef}{'write list'}, + inherit_permissions => $samba->{$clef}{'inherit permissions'}, + printing => $samba->{$clef}{printing}, + create_mode => $samba->{$clef}{'create mode'}, + use_client_driver => $samba->{$clef}{'use client driver'}, + }; + } + } + return @listprinters; +} + +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 printdollar_section() { + $samba->{'print$'}; + $samba->{'print$'}{browseable} = "yes"; + $samba->{'print$'}{path} = "/var/lib/samba/printers"; + $samba->{'print$'}{browseable} = "yes"; + $samba->{'print$'}{'write list'} = "\@adm root"; + $samba->{'print$'}{'guest ok'} = "yes"; + $samba->{'print$'}{'inherit permissions'} = "yes"; +} + +sub pdf_section() { + $samba->{'pdf-gen'}; + $samba->{'pdf-gen'}{path} = "/var/tmp"; + $samba->{'pdf-gen'}{'guest ok'} = "no"; + $samba->{'pdf-gen'}{printable} = "yes"; + $samba->{'pdf-gen'}{comment} = "PDF Generator (only valid users)"; + $samba->{'pdf-gen'}{printing} = "bsd"; + $samba->{'pdf-gen'}{'print command'} = '/usr/share/samba/scripts/print-pdf %s %H \//%L/%u\ %m %I %J &'; + $samba->{'pdf-gen'}{'lpq command'} = "/bin/true"; +} + +sub printers_section() { + $samba->{printers}; + $samba->{printers}{comment} = "All Printers"; + $samba->{printers}{browseable} = "no"; + $samba->{printers}{'guest ok'} = "yes"; + $samba->{printers}{'create mode'} = "0700"; + $samba->{printers}{path} = "/var/spool/samba"; + $samba->{printers}{writable} = "no"; + $samba->{printers}{printable} = "yes"; + $samba->{printers}{'print command'} = 'lpr-cups -P %p -o raw %s -r'; + $samba->{printers}{'use client driver'} = "yes"; +} + +sub add_entry() { + require wizards; + my ($wiz_addshare_name, $wiz_addshare_comment, $wiz_addshare_path); + my $wiz = wizards->new({ + name => N("Add a Samba share"), + pages => { + welcome => { + name => N("Goal of this wizard is to easily create a new 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 'welcome'; + } + } + if (!$wiz_addshare_path) { + err_dialog(N("Error"), N("Can't create the directory, please enter a correct path.")) and return 'welcome'; + } + if (!$wiz_addshare_comment) { + err_dialog(N("Error"), N("Please enter a Comment for this share.")) and return 'welcome'; + } + 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 'welcome'; + } + }, + post => sub { + push @{$share_list->{data}}, [ + $pixbuf_file, + $wiz_addshare_name, + $wiz_addshare_path, + $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; + }, + no_back => 1, + 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, + }, + } + }); + $wiz->process($in); + $::isWizard = 0; + gtkset_mousecursor_normal(); +} + +sub add_printers_entry() { + require wizards; + my %print = ( + 1 => N("pdf-gen - a PDF generator"), + 2 => N("printers - all printers available"), + ); + my $wiz_todo; + my $wiz = wizards->new({ + name => N("Add Special Printer share"), + pages => { + welcome => { + name => N("Goal of this wizard is to easily create a new special printer Samba share."), + data => [ + { label => "", type => 'list', val => \$wiz_todo, list => [ keys %print ], format => sub { $print{$_[0]} } } + ], + no_back => 1, + next => 'end_add', + post => sub { + if ($wiz_todo == 1) { + exists $samba->{'pdf-gen'} and err_dialog(N("Error"), N("A PDF generator already exists.")) and return 'welcome'; + &pdf_section; + push @{$printer_list->{data}}, [ + $pixbuf_printer, + 'pdf-gen', + $samba->{'pdf-gen'}{path}, + $samba->{'pdf-gen'}{comment}, "", + $samba->{'pdf-gen'}{printable}, + $samba->{'pdf-gen'}{'print command'}, + $samba->{'pdf-gen'}{'lpq command'}, + $samba->{'pdf-gen'}{'guest ok'}, "", "", "", + $samba->{'pdf-gen'}{printing}, "", "", + ]; + push @listprinters, { + share_name => $samba->{'pdf-gen'}, + path => $samba->{'pdf-gen'}{path}, + comment => $samba->{'pdf-gen'}{comment}, + printebale => $samba->{'pdf-gen'}{printable}, + printing => $samba->{'pdf-gen'}{printing}, + print_command => $samba->{'pdf-gen'}{'print command'}, + lpq_command => $samba->{'pdf-gen'}{'lpq command'}, + guest_ok => $samba->{'pdf-gen'}{'guest ok'}, + }; + } elsif ($wiz_todo == 2) { + exists $samba->{'print$'} || exists $samba->{printers} and err_dialog(N("Error"), N("Printers and print\$ already exist.")) and return 'welcome'; + &printdollar_section; + &printers_section; + push @{$printer_list->{data}}, [ + $pixbuf_printer, + 'print$', + $samba->{'print$'}{path}, "", + $samba->{'print$'}{browseable}, "", "", "", + $samba->{'print$'}{'guest ok'}, "", + $samba->{'print$'}{'write list'}, + $samba->{'print$'}{'inherit permissions'}, + ]; + push @{$printer_list->{data}}, [ + $pixbuf_printer, + 'printers', + $samba->{printers}{path}, + $samba->{printers}{comment}, + $samba->{printers}{browseable}, + $samba->{printers}{printable}, + $samba->{printers}{'print command'}, "", + $samba->{printers}{'guest ok'}, + $samba->{printers}{writable}, "", "", "", + $samba->{printers}{'create mode'}, + $samba->{printers}{'use client driver'}, + ]; + push @listprinters, { + share_name => 'print$', + path => $samba->{'print$'}{path}, + browseable => $samba->{'print$'}{browseable}, + write_list => $samba->{'print$'}{'write list'}, + guest_ok => $samba->{'print$'}{'guest ok'}, + inherit_permissions => $samba->{'print$'}{'inherit permissions'}, + }; + push @listprinters, { + share_name => "printers", + comment => $samba->{printers}{comment}, + browseable => $samba->{printers}{browseable}, + guest_ok => $samba->{printers}{'guest ok'}, + create_mode => $samba->{printers}{'create mode'}, + path => $samba->{printers}{path}, + writable => $samba->{printers}{writable}, + printable => $samba->{printers}{printable}, + print_command => $samba->{printers}{'print command'}, + use_client_driver => $samba->{printers}{'use client driver'}, + }; + } + return; + }, + }, + end_add => { + name => N("Congratulations"), + data => [ { label => N("The wizard successfully added the printer Samba share") } ], + no_back => 1, + end => 1, + next => 0, + }, + } + }); + $wiz->process($in); + $::isWizard = 0; + # gtkset_mousecursor_normal() +} + +sub modify_printers_entry { + my ($selected) = @_; + my ($dir, $comment, $print_command, $guest_ok, $share_name, $browseable, $printable, $write_list, $printing, $lpq_command, $create_mode, $writable, $use_client_driver, $inherit_permissions); + + $share_name = Gtk2::Label->new; + $_ = Gtk2::Entry->new foreach $dir, $comment, $print_command, $write_list, $printing, $lpq_command, $create_mode; + $_ = Gtk2::OptionMenu->new foreach $browseable, $printable, $guest_ok, $writable, $use_client_driver, $inherit_permissions; + $_->set_popdown_strings(@yesno) foreach $browseable, $printable, $guest_ok, $writable, $use_client_driver, $inherit_permissions; + + + my $s = $printer_list->{data}[$selected][1]; + $s or info_dialog(N("Error"), N("Please add or select a Samba printer share to be able to modify it.")) and return; $share_name->set_text($s); + $dir->set_text($printer_list->{data}[$selected][2]); + $comment->set_text($printer_list->{data}[$selected][3]); + $browseable->set_text($printer_list->{data}[$selected][4]); + $printable->set_text($printer_list->{data}[$selected][5]); + $print_command->set_text($printer_list->{data}[$selected][6]); + $lpq_command->set_text($printer_list->{data}[$selected][7]); + $guest_ok->set_text($printer_list->{data}[$selected][8]); + $writable->set_text($printer_list->{data}[$selected][9]); + $write_list->set_text($printer_list->{data}[$selected][10]); + $inherit_permissions->set_text($printer_list->{data}[$selected][11]); + $printing->set_text($printer_list->{data}[$selected][12]); + $create_mode->set_text($printer_list->{data}[$selected][13]); + $use_client_driver->set_text($printer_list->{data}[$selected][14]); + + 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); + + if ($s eq "printers") { $printable->set_text("yes"); + $printing->set_text(""); + $_->set_sensitive(0) foreach $printable, $printing; + } + if ($s eq "pdf-gen") { $printing->set_text("bsd"); + $printing->set_sensitive(0); + } + + gtkpack_($dialog->vbox, + 0, gtkadd(Gtk2::Frame->new(N("Printer share")), + gtkpack_(gtkset_border_width(Gtk2::HBox->new, 3), + 0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1), + 0, $label_and_widgets->(N("Printer name:"), $share_name, ""), + 0, $label_and_widgets->(N("Comment:"), $comment, ""), + 0, $label_and_widgets->(N("Directory:"), $dir, $button), + ), + 0, Gtk2::VSeparator->new, + 0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1), + 0, $label_and_widgets->(N("Writable:"), $writable, ""), + 0, $label_and_widgets->(N("Browseable:"), $browseable, ""), + 0, $label_and_widgets->(N("Printable"), $printable, ""), + ), + ), + ), + 0, gtkadd(Gtk2::Frame->new(N("Advanced options")), + gtkpack_(gtkset_border_width(Gtk2::HBox->new, 3), + 0, gtkadd(Gtk2::Frame->new(N("Printer access")), + gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1), + 0, $label_and_widgets->(N("Write list"), $write_list, ""), + 0, $label_and_widgets->(N("Inherit permissions"), $inherit_permissions, ""), + 0, $label_and_widgets->(N("Guest ok:"), $guest_ok, ""), + 0, $label_and_widgets->(N("Create mode:"), $create_mode, ""), + ), + ), + 0, Gtk2::VSeparator->new, + 0, gtkadd(Gtk2::Frame->new(N("Printer command")), + gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1), + 0, $label_and_widgets->(N("Print command:"), $print_command, ""), + 0, $label_and_widgets->(N("LPQ command:"), $lpq_command, ""), + 0, $label_and_widgets->(N("Printing:"), $printing, ""), + ), + ), + ), + ), + 0, create_okcancel({ + cancel_clicked => sub { $dialog->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 (!-d $test_dir) { + err_dialog(N("Error!"), N("Please enter a directory to share.")) and return; + } + foreach ($create_mode->get_text) { + if ($_ && !/^\d+$/) { + err_dialog(N("Error"), N("create mode should be numeric. ie: 0755.")) and return 1; + } + } + # update gui SimpleList + remove_entry($selected, $printer_list); + push @{$printer_list->{data}}, [ + $pixbuf_printer, + $share, + $dir->get_text, + $comment->get_text, + $browseable->get_text, + $printable->get_text, + $print_command->get_text, + $lpq_command->get_text, + $guest_ok->get_text, + $writable->get_text, + $write_list->get_text, + $inherit_permissions->get_text, + $printing->get_text, + $create_mode->get_text, + $use_client_driver->get_text, + ]; + # update $samba + $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}; + $printable->get_text and $samba->{$share}{printable} = $printable->get_text || delete $samba->{$share}{printable}; + $print_command->get_text and $samba->{$share}{'print command'} = $print_command->get_text || delete $samba->{$share}{'print command'}; + $lpq_command->get_text and $samba->{$share}{'lpq command'} = $lpq_command->get_text || delete $samba->{$share}{'lpq command'}; + $guest_ok->get_text and $samba->{$share}{'guest ok'} = $guest_ok->get_text || delete $samba->{$share}{'guest ok'}; + $writable->get_text and $samba->{$share}{writable} = $writable->get_text || delete $samba->{$share}{writable}; + $write_list->get_text and $samba->{$share}{'write list'} = $write_list->get_text || delete $samba->{$share}{'write list'}; + $inherit_permissions->get_text and $samba->{$share}{'inherit permissions'} = $inherit_permissions->get_text || delete $samba->{$share}{'inherit permissions'}; + $printing->get_text and $samba->{$share}{printing} = $printing->get_text || delete $samba->{$share}{printing}; + $create_mode->get_text and $samba->{$share}{'create mode'} = $create_mode->get_text || delete $samba->{$share}{'create mode'}; + $use_client_driver->get_text and $samba->{$share}{'use client driver'} = $use_client_driver->get_text || delete $samba->{$share}{'use client driver'}; + + # + $dialog->destroy; + } + }, + ), + ); + $dialog->show_all; +} + +sub modify_entry { + my ($selected) = @_; + my ($dir, $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, $comment, $create_mask, $directory_mask, $hide_files; + $_ = 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_dot_files, $inherit_permissions; + + $default_case->set_popdown_strings(@default_case); + $_->set_popdown_strings(@yesno) foreach $browseable, $public, $writable, $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); + $w->{window}->set_position('center'); + + my $s = $share_list->{data}[$selected][1]; + $s or info_dialog(N("Error"), N("Please add or select a Samba share to be able to modify it.")) and return; + $share_name->set_text($s); + $dir->set_text($share_list->{data}[$selected][2]); + $comment->set_text($share_list->{data}[$selected][3]); + $browseable->set_text($share_list->{data}[$selected][4]); + $public->set_text($share_list->{data}[$selected][5]); + $writable->set_text($share_list->{data}[$selected][6]); + $create_mask->set_text($share_list->{data}[$selected][7]); + $directory_mask->set_text($share_list->{data}[$selected][8]); + $read_list->set_text($share_list->{data}[$selected][9]); + $write_list->set_text($share_list->{data}[$selected][10]); + $admin_users->set_text($share_list->{data}[$selected][11]); + $valid_users->set_text($share_list->{data}[$selected][12]); + $inherit_permissions->set_text($share_list->{data}[$selected][13]); + $hide_dot_files->set_text($share_list->{data}[$selected][14]); + $hide_files->set_text($share_list->{data}[$selected][15]); + $preserve_case->set_text($share_list->{data}[$selected][16]); + $force_create_mode->set_text($share_list->{data}[$selected][17]); + $force_group->set_text($share_list->{data}[$selected][18]); + $default_case->set_text($share_list->{data}[$selected][19]); + + 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; + }) 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; + } + } + foreach ($read_list->get_text, $write_list->get_text, $admin_users->get_text, $valid_users->get_text) { + my @users = split(" ", $_); + foreach my $user (@users) { + if (!any { /^$user:/ } cat_("/etc/samba/smbpasswd") and !/\@/) { + err_dialog(N("Error"), N("Please create this Samba user: %s", $user)) and return; + } + } + } + # update gui SimpleList + remove_entry($selected, $share_list); + push @{$share_list->{data}}, [ + $pixbuf_file, + $share_name->get_text, + $dir->get_text, + $comment->get_text, + $browseable->get_text, + $public->get_text, + $writable->get_text, + $create_mask->get_text, + $directory_mask->get_text, + $read_list->get_text, + $write_list->get_text, + $admin_users->get_text, + $valid_users->get_text, + $hide_dot_files->get_text, + $hide_files->get_text, + $preserve_case->get_text, + $force_create_mode->get_text, + $force_group->get_text, + $default_case->get_text, + $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'}; + + # update listshare + push @listshare, { + share_name => $share, + path => $samba->{$share}{path}, + comment => $samba->{$share}{comment}, + browseable => $samba->{$share}{browseable}, + public => $samba->{$share}{public}, + writable => $samba->{$share}{writable}, + create_mask => $samba->{$share}{'create mask'}, + directory_mask => $samba->{$share}{'directory mask'}, + read_list => $samba->{$share}{'read list'}, + write_list => $samba->{$share}{'write list'}, + admin_users => $samba->{$share}{'admin users'}, + valid_users => $samba->{$share}{'valid users'}, + hide_dot_files => $samba->{$share}{'hide dot files'}, + hide_files => $samba->{$share}{'hide files'}, + preserve_case => $samba->{$share}{'preserve case'}, + force_create_mode => $samba->{$share}{'force create mode'}, + force_group => $samba->{$share}{'force group'}, + default_case => $samba->{$share}{'default case'}, + inherit_permissions => $samba->{$share}{'inherit permissions'}, + }; + $w->destroy; + }, + }, + ), + ] + ), + ); + $w->{window}->show_all; +} + +sub remove_entry { + my ($selected, $list) = @_; + my $share_name = $list->{data}[$selected][1]; + splice @{$list->{data}}, $selected, 1; + delete $samba->{$share_name}; +} + +sub remove_user { + my ($user) = @_; + system("smbpasswd -x $user"); +} + +sub get_user() { + my $conf = "/etc/passwd"; + my @data; local $_; + foreach (cat_($conf)) { + push @data, $1 if m/^([^#:]+):[^:]+:([^:]+):/ and $2 > 499; + } + push @data, " "; + return sort(@data); +} + + +sub modify_user_info { + my ($user, $passwd, $todo) = @_; + my ($buser, $bpasswd); + my $dialog = new Gtk2::Dialog(); + $dialog->set_title("Add Samba user"); + $dialog->set_modal(1); + $dialog->set_position('center'); + $dialog->set_resizable(0); + if ($todo eq "add") { + $buser = Gtk2::ComboBox->new_with_strings([ get_user() ]); + $buser->set_wrap_width(3); + } else { + $buser = Gtk2::Label->new; + $buser->set_text($user); + } + $bpasswd = Gtk2::Entry->new; + $bpasswd->set_visibility(0); + + gtkpack_($dialog->vbox, + 0, gtkadd(Gtk2::Frame->new(N("User information")), + gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), + 0, $label_and_widgets->(N("User name:"), $buser, ""), + 0, $label_and_widgets->(N("Password:"), $bpasswd, ""), + ), + ), + 0, create_okcancel({ + cancel_clicked => sub { $dialog->destroy }, + ok_clicked => sub { + my $user_selected = $buser->get_text; + if ($todo eq "add") { + if (any { /^$user_selected:/ } cat_("/etc/samba/smbpasswd")) { + err_dialog(N("Error"), ("Samba User already exist")) and return; + } + system("smbpasswd -a $user_selected -n"); + push @{$user_list->{data}}, [ + $pixbuf_user, + $user_selected, + ]; + push @listusers, { + user_name => $user_selected, + }; + } + my $passwd_e = $bpasswd->get_text; + set_user_passwd($user_selected, $passwd_e); + $dialog->destroy; + } + }, + ), + ); + $dialog->show_all; +} + +sub set_user_passwd { + my ($user, $passwd) = @_; + my $F; + open($F, '|' . qq(smbpasswd $user -s)); + print $F "$passwd\n"; + print $F "$passwd\n"; + close $F; +} + +sub add_data_share_list { + my ($share_list) = @_; + get_samba_share(); + + foreach my $data (@listshare) { + push @{$share_list->{data}}, [ + $pixbuf_file, + $data->{share_name}, + $data->{path}, + $data->{comment}, + $data->{browseable}, + $data->{public}, + $data->{writable}, + $data->{create_mask}, + $data->{directory_mask}, + $data->{read_list}, + $data->{write_list}, + $data->{admin_users}, + $data->{valid_users}, + $data->{inherit_permissions}, + $data->{hide_dot_files}, + $data->{hide_files}, + $data->{preserve_case}, + $data->{force_create_mode}, + $data->{force_group}, + $data->{default_case}, + ]; + } +} + +sub add_data_user_list { + my ($user_list) = @_; + get_samba_user(); + foreach my $data (@listusers) { + push @{$user_list->{data}}, [ + $pixbuf_user, + $data->{user_name}, + ]; + } +} + +sub add_data_printer_list { + my ($printer_list) = @_; + get_samba_printers(); + foreach my $data (@listprinters) { + push @{$printer_list->{data}}, [ + $pixbuf_printer, + $data->{share_name}, + $data->{path}, + $data->{comment}, + $data->{browseable}, + $data->{printable}, + $data->{print_command}, + $data->{lpq_command}, + $data->{guest_ok}, + $data->{writable}, + $data->{write_list}, + $data->{inherit_permissions}, + $data->{printing}, + $data->{create_mode}, + $data->{use_client_driver}, + ]; + } +} + +############### +# Main Program +############### +# create model +add_data_share_list($share_list); +add_data_printer_list($printer_list); +add_data_user_list($user_list); +$_->set_rules_hint(1) foreach $share_list, $printer_list, $user_list; + +my $window = ugtk2->new("DrakSamba"); +$::main_window = $window->{real_window}; +$window->{rwindow}->set_size_request(600, 410) unless $::isEmbedded; +$window->{rwindow}->set_position('center') if !$::isEmbedded; +my $W = $window->{window}; +$W->signal_connect(delete_event => sub { ugtk2->exit }); + +# double clic and popup modify window +$share_list->signal_connect(button_press_event => sub { + my (undef, $event) = @_; + my ($selected) = $share_list->get_selected_indices; + $share_list->{data}[$selected][1] and modify_entry($selected) if $event->type eq '2button-press'; + }); + +$printer_list->signal_connect(button_press_event => sub { + my (undef, $event) = @_; + my ($selected) = $printer_list->get_selected_indices; + $printer_list->{data}[$selected][1] and modify_printers_entry($selected) if $event->type eq '2button-press'; + }); + +$user_list->signal_connect(button_press_event => sub { + my (undef, $event) = @_; + my ($selected) = $user_list->get_selected_indices; + $user_list->{data}[$selected][1] and modify_user_info($user_list->{data}[$selected][1], "", "change") if $event->type eq '2button-press'; + }); + +# dont know why "$event->type eq '2button-press'" when starting draksambashare so i can't use mapn :/ +#mapn { +# $_[0]->signal_connect(button_press_event => sub { +# my (undef, $event) = @_; +# my ($selected) = $_[0]->get_selected_indices; +# return unless $event->type eq '2button-press'; +# $_[0]->{data}[$selected][1] and $_[1]($selected); # if $event->type eq '2button-press'; +# }); +#} [ $share_list, $printer_list, $user_list ], [ modify_entry, modify_printers_entry, modify_user_info ]; + +# create popup menu +my $menupopup = Gtk2::Menu->new; +my $menuitem1 = Gtk2::MenuItem->new(N("Modify")); +my $menuitem2 = Gtk2::MenuItem->new(N("Remove")); +$menuitem1->signal_connect(activate => sub { + my ($selected) = $share_list->get_selected_indices; + modify_entry($selected, $share_list); + }); +$menuitem2->signal_connect(activate => sub { + my ($selected) = $share_list->get_selected_indices; + ask_okcancel("Remove entry ?", "Remove $share_list->{data}[$selected][1]") or return; + remove_entry($selected, $share_list); + }); +$_->show foreach $menuitem1, $menuitem2; +$menupopup->append($_) foreach $menuitem1, $menuitem2; +$share_list->signal_connect('button-press-event' => sub { + my ($widget, $event) = @_; + return unless $event->button == 3; + $menupopup->popup(undef, undef, undef, undef, $event->button, $event->time); + } + ); + +$share_list->signal_connect(key_press_event => sub { + my ($widget, $event) = @_; + return unless $event->keyval == $Gtk2::Gdk::Keysyms{Return}; + my ($selected) = $share_list->get_selected_indices; + modify_entry($selected, $share_list); + return 1; +}); + +# create menu +my @items = get_items(); +my $factory = Gtk2::ItemFactory->new('Gtk2::MenuBar', '<main>', undef); +$factory->create_items('menu', @items); +my $menu = $factory->get_widget('<main>'); + +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($share_list), + 0, gtkpack_(create_vbox('start'), + 0, gtksignal_connect(Gtk2::Button->new(N("Add")), clicked => sub { + eval { add_entry() }; + 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 { + my ($selected) = $share_list->get_selected_indices; + eval { modify_entry($selected, $share_list) }; + 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 { + my ($selected) = $share_list->get_selected_indices; + ask_okcancel("Remove entry ?", "Remove $share_list->{data}[$selected][1]") or return; + eval { remove_entry($selected, $share_list) }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to remove a Samba share.") . "\n\n" . $err); + } + }), + ), + ), + gtkshow(gtkpack_(Gtk2::HBox->new(0,0), + 0, Gtk2::Image->new_from_file($fileshare_icon), + 0, Gtk2::Label->new(N("File share")), + ), + ), + ); + +gtkappend_page($nb, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 0), + 1, create_scrolled_window($printer_list), + 0, gtkpack_(create_vbox('start'), + 0, gtksignal_connect(Gtk2::Button->new(N("Add printers")), clicked => sub { + eval { add_printers_entry() }; + my $err = $@; + $::WizardWindow->destroy if defined $::WizardWindow; + undef $::WizardWindow; + if ($err && $err !~ /wizcancel/) { + 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 { + my ($selected) = $printer_list->get_selected_indices; + eval { modify_printers_entry($selected) }; + 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 { + my ($selected) = $printer_list->get_selected_indices; + ask_okcancel("Remove entry ?", "Remove $printer_list->{data}[$selected][1]") or return; + eval { remove_entry($selected, $printer_list) }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to remove.") . "\n\n" . $err); + } + }), + ), + ), + gtkshow(gtkpack_(Gtk2::HBox->new(0,0), + 0, Gtk2::Image->new_from_file($printershare_icon), + 0, Gtk2::Label->new(N("Printers")), + ), + ), + ); + +gtkappend_page($nb, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 0), + 1, create_scrolled_window($user_list), + 0, gtkpack_(create_vbox('start'), + 0, gtksignal_connect(Gtk2::Button->new(N("Change password")), clicked => sub { + my ($selected) = $user_list->get_selected_indices; + eval { modify_user_info($user_list->{data}[$selected][1], "", "change") }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to change user password.") . "\n\n" . $err); + } + }), + 0, Gtk2::HSeparator->new, + 0, gtksignal_connect(Gtk2::Button->new(N("Add user")), clicked => sub { + eval { modify_user_info("", "", "add") }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to add user.") . "\n\n" . $err); + } + }), + 0, gtksignal_connect(Gtk2::Button->new(N("Delete user")), clicked => sub { + my ($selected) = $user_list->get_selected_indices; + ask_okcancel("Remove entry ?", "Remove $user_list->{data}[$selected][1]") or return; + eval { + remove_user($user_list->{data}[$selected][1]); + remove_entry($selected, $user_list); + }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to delete user.") . "\n\n" . $err); + } + }), + 0, Gtk2::HSeparator->new, + 0, gtksignal_connect(Gtk2::Button->new(N("Userdrake")), clicked => sub { + run_program::raw({ detach => 1 }, 'userdrake'); + } + ), + ), + ), + gtkshow(gtkpack_(Gtk2::HBox->new(0,0), + 0, Gtk2::Image->new_from_file($sambauser_icon), + 0, Gtk2::Label->new(N("Samba Users"))), + ), + ); + +$nb->set_show_border(0); + +# main interface +$W->add(gtkpack_(Gtk2::VBox->new(0,0), + 0, $menu, + if_(!$::isEmbedded, 0, Gtk2::Banner->new('IC-winacces1-48', 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; |