#!/usr/bin/perl -w ############################################################################### # # # FUSESMBTOOL # # Fusesmb configuration Tool # # # # Authors : # # # # - Jean-Philippe Guillemin # # - Thibaud Guerin # # # # Released in the terms of the GNU GENERAL PUBLIC LICENSE # # http://www.gnu.org/copyleft/gpl.html # # This program is free software; you can redistribute it and/or modify it # # under the terms of the GNU General Public License as published by the Free # # Software Foundation; either version 2 of the License, or (at your option) # # any later version. Please take a look at # # http://www.gnu.org/copyleft/gpl.htm # # # ############################################################################### # Changelog: # - 2006/07/30: v0.1: # - options: # mountpoint, hiddenshares, login/pass, entry timout, # update interval # - 2007/01/25: v0.2: # - options: # umask, connection timout, access to others # - specific servers/shares rules: # login/pass, hiddenshare, ignore # - specific "ignore" rule # servers list, workgroups list # use strict; use Getopt::Std; use POSIX; use Gtk2 '-init' ; set_locale Gtk2; # internationalize my $version="v0.2"; #set debug to 1 to enable my $debug; my $user=$ENV{USER}; my $home=$ENV{HOME}; my $uid=getuid(); my $FuseToolConfFilePath="$home/.smb"; my $FuseToolConfFile="$FuseToolConfFilePath/fusesmbtool.conf"; my $FuseSmbConfFilePath="$home/.smb"; my $FuseSmbConfFile="$FuseToolConfFilePath/fusesmb.conf"; my $DefaultMountPoint="$home/smb"; my %ToolConfHash; use constant TRUE => 1 ; use constant FALSE => 0 ; my $UsageTxt = "usage : fusesmbtool [-h] [-l] [-c]\n". "-h: print this help\n". "-l [mountpoint]: start fusesmb\n". "-c: config mode\n"; my $StatusTxt = "Status"; my $IsMountedTxt = "SMB is mounted"; my $IsNotMountedTxt = "SMB is not mounted"; my $MainOptFrameTxt = "Main options"; my $MntPntTxt = "MountPoint"; my $TrueTxt = "true"; my $FalseTxt = "false"; my $HdShareLblTxt = "Show Hidden Shares"; #my $ShHdSharesTxt = "Show Hidden Shares"; my $GenUserLblTxt = "Glogal username:"; my $GenPassLblTxt = "Glogal password:"; my $MiscOptFrameTxt = "Misc options"; my $UmaskLblTxt = "Umask (octal):"; my $EntTimoutLblTxt = "Names cache timeout (x.y s):"; my $TimeoutLblTxt = "Conn. Timout (min):"; my $IntervalLblTxt = "Update Interval (sec):"; my $OtherAccessTxt = "Allow access to others"; my $AboutTxt = "Configuration utility for Fusesmb.\n". "Authors :\n". "- Jean-Philippe Guillemin \n". "- Thibaud Guerin .\n". "Licence : Gnu Public Licence version 2. "; my $CantCreateTxt = "can't create"; my $CantOpenTxt = "can't open"; my $CantWriteTxt = "Unable to write"; my $NewRule = "New Rule"; my $AddNewRuleDlgTxt = "Add New Server/Share Rule"; my $AddNewRuleTxt = "New share-rule's name :"; my $NoNewName = "No new share name"; my $AlreadyExists = "A rule with this name already exists"; my $RuleUserTxt = "Share login"; my $RulePassTxt = "Share pass"; my $RuleServerTxt = "Servers to ignore:\n(separator: ',')"; my $RuleWrkGTxt = "Workgroups to ignore:\n(separator: ',')"; my $RulesShHiddenTxt = "Show Hidden shares"; my $RulesIgnoreTxt = "Ignore"; my $UmaskUsrFrameTxt = "Denied User Rights"; my $UmaskUsrRTxt = "Read"; my $UmaskUsrWTxt = "Write"; my $UmaskUsrXTxt = "Execute"; my $UmaskGrpFrameTxt = "Denied Group Rights"; my $UmaskGrpRTxt = "Read"; my $UmaskGrpWTxt = "Write"; my $UmaskGrpXTxt = "Execute"; my $UmaskOthFrameTxt = "Denied Other Rights"; my $UmaskOthRTxt = "Read"; my $UmaskOthWTxt = "Write"; my $UmaskOthXTxt = "Execute"; #for command line args my %opts; # gtk stuff my $window = 0; my ($StatusField, $StatusIcon, $StatusBox, $MntPntButton,$MntPnt, $HdShareLbl, $HdShare, $GenUserLbl, $GenUser, $GenPassLbl, $GenPass, $TimeoutLbl, $Timeout, $IntervalLbl, $Interval, $UmaskUsrFrame, $UmaskUsrBox, $UmaskUsrR, $UmaskUsrW, $UmaskUsrX, $UmaskGrpFrame, $UmaskGrpBox, $UmaskGrpR, $UmaskGrpW, $UmaskGrpX, $UmaskOthFrame, $UmaskOthBox, $UmaskOthR, $UmaskOthW, $UmaskOthX, $OtherAccess, $EntTimoutLbl, $EntTimout1, $EntTimout2, $EntTimoutBox, $MainOptMatrix, $MiscOptMatrix, $ActionMatrix, $NtBook, $LeftBox, $RightBox, $TopBox, $FuseSMBGenOptFrame, $SaveButton, $ExitButton, $StartStopButton, $AddNewButton, $AboutButton, $FooterMatrix, $OuterBox, $StatusFrame ); my $AddNewDlg = Gtk2::Window->new('toplevel'); my $NewNameEnt = Gtk2::Entry->new(); my $RuleName = ""; my %RulesUser; my %RulesPass; my %RulesHidden; my %RulesIgnore; #################################################################### #################################################################### #################################################################### sub disp_err { my $msg="Unknown error"; $msg=$_[0] if (@_ > 0); chomp($msg); my $isexit=1; $isexit=$_[1] if (@_ > 1); print "ERROR: $msg\n" if (defined($debug) && $window != 0); if ($window != 0) { my $ErrDlg = Gtk2::MessageDialog->new($window, 'modal','error', 'close', "$msg"); $ErrDlg->signal_connect (response => sub { $ErrDlg->destroy; TRUE }); $ErrDlg->run; Gtk2->main_quit() if $isexit == 1; } else { print "ERROR: $msg\n"; } exit if $isexit == 1; return TRUE; } sub ReadCLIArgs { print "ARGV =".@ARGV . "\n" if (defined($debug)); #heck the -h -l -c option getopts( "hcl:", \%opts ); if (keys(%opts) != 1 || exists($opts{'h'})) { disp_err "$UsageTxt", 2; exit; } } sub ReadConfFile { return disp_err("Unable to read $_[0]", 0) if ( ! -r "$_[0]"); my $hashtab = $_[1]; my $sect=""; open(MYINPUTFILE, "<$_[0]"); while() { chomp($_); s/^\s*(.*?)\s*$/$1/; s/^[#;].*//g; if ("$_" ne "") { my ($opt, $val) = split /=/, $_, 2; $val="" if !defined($val); if ("$opt" =~ /\[.*\]/) { print "section: $opt\n" if defined($debug); $sect="$opt"; } map{s/^\s+//;s/\s+$//} ("$val", "$opt"); $hashtab->{"$opt"}->{"$sect"}="$val"; print "$sect $opt=$val\n" if defined($debug) && "$opt" ne "$sect"; } } return FALSE; } # We check for an already mounted smbfuse directory, #usage : IsMountedSmbFuse, return values = "" or the mountpoint sub IsMountedSmbFuse { my $line; print "IsMountedSmbFuse\n" if (defined($debug)); open(MTAB, ") { chomp $line; if ( defined($line) && "$line" ne "" && "$line" =~ /^.*smb.*fuse.*$/ ) { my @arr = split / /, $line; my @optarr = split /,/, $line; print "found this mounted: [$arr[1]]\n" if (defined($debug)); foreach my $op (@optarr) { my @opt = split /=/, $op; if (@opt == 2 && $opt[0] eq "user_id" && $opt[1] eq $uid) { close(MTAB); return "$arr[1]"; } } print "can't umount : [$arr[1]] (no write access)\n" if (defined($debug)); } } close(MTAB); print "Nothing mounted\n" if (defined($debug)); return ""; } sub Unmount { my $NeedUmount = IsMountedSmbFuse; if (defined($NeedUmount) && "$NeedUmount" ne "") { print "Unmount: $NeedUmount\nfusermount -u $NeedUmount 2>/dev/stdout\n" if (defined($debug)); my $err_msg = `fusermount -u "$NeedUmount" 2>/dev/stdout`; disp_err("$err_msg", 0) if (defined($err_msg) && "$err_msg" ne ""); } } # create main window $window = Gtk2::Window->new('toplevel') ; $window->set_title("FuseSMBtool"); $window->signal_connect(destroy => \&ExitCallback); $window->set_border_width(7); $window->set_icon_from_file("/usr/share/icons/hicolor/scalable/apps/fusesmbtool.svg"); ReadCLIArgs if (@ARGV > 0); my $ReadError = ReadConfFile "$FuseSmbConfFile", \%ToolConfHash; $ReadError = $ReadError + ReadConfFile "$FuseToolConfFile", \%ToolConfHash; if (exists($opts{'l'}) && !$ReadError) { my $mountpoint = (defined($opts{'l'}) ? $opts{'l'} : $ToolConfHash{'path'}{'[global]'}); Unmount "$mountpoint"; print $opts{'l'}."\n"; my $OtherAccessVal = $ToolConfHash{'allow_other'}{'[global]'} eq "yes" ? TRUE : FALSE; $OtherAccessVal = $OtherAccess->get_active if (defined($OtherAccess)); my $FuseMntOpts = "-o ".($OtherAccessVal ? "allow_other," : ""). "fsname=smb $mountpoint"; my $err_msg = `fusesmb $FuseMntOpts 2>/dev/stdout`; if (defined($err_msg) && "$err_msg" ne "") { my ($prog, $msg) = split /: /, $err_msg, 2; $err_msg = disp_err("$msg", FALSE); } print "Mounting fusesmb on $mountpoint : ". (defined($err_msg) && $err_msg eq 1 ? "ERROR" : "SUCCESS")."\n" if (defined($debug)); exit if ($err_msg ne 1); } #################################################################### # GTK time #################################################################### # status field $StatusField = Gtk2::Label->new; $StatusIcon = Gtk2::Image->new; $StatusBox = Gtk2::HBox->new(TRUE,0); $StatusBox->set_border_width(7); $StatusBox->pack_start($StatusField, FALSE, TRUE, 0); $StatusBox->pack_start($StatusIcon, FALSE, TRUE, 0); $StatusFrame = Gtk2::Frame->new("$StatusTxt"); #$StatusFrame->set_border_width(3); $StatusFrame->add($StatusBox); ######### Main options fields # Mountpoint Part $MntPntButton = Gtk2::Button->new_with_label("$MntPntTxt"); $MntPntButton->signal_connect(clicked => \&ChooseMnt); $MntPnt = Gtk2::Entry->new(); ## HiddenShare Part $HdShare = Gtk2::CheckButton->new_with_mnemonic("$HdShareLblTxt"); # access to other users Part $OtherAccess = Gtk2::CheckButton->new_with_mnemonic("$OtherAccessTxt"); #$OtherAccess->set_active(TRUE); # General user Part $GenUserLbl = Gtk2::Label->new; $GenUserLbl->set_justify('left'); $GenUser = Gtk2::Entry->new(); # General password Part $GenPassLbl = Gtk2::Label->new; $GenPassLbl->set_justify('left'); $GenPass = Gtk2::Entry->new(); $GenPass->set_visibility(FALSE); ######### Misc options fields #Umask part $UmaskUsrR = Gtk2::CheckButton->new_with_mnemonic("$UmaskUsrRTxt"); $UmaskUsrW = Gtk2::CheckButton->new_with_mnemonic("$UmaskUsrWTxt"); $UmaskUsrX = Gtk2::CheckButton->new_with_mnemonic("$UmaskUsrXTxt"); $UmaskUsrFrame = Gtk2::Frame->new("$UmaskUsrFrameTxt"); $UmaskUsrBox = Gtk2::HBox->new(TRUE,0); $UmaskUsrBox->pack_start($UmaskUsrR, FALSE, TRUE, 0); $UmaskUsrBox->pack_start($UmaskUsrW, FALSE, TRUE, 0); $UmaskUsrBox->pack_start($UmaskUsrX, FALSE, TRUE, 0); $UmaskUsrFrame->add($UmaskUsrBox); $UmaskGrpR = Gtk2::CheckButton->new_with_mnemonic("$UmaskGrpRTxt"); $UmaskGrpW = Gtk2::CheckButton->new_with_mnemonic("$UmaskGrpWTxt"); $UmaskGrpX = Gtk2::CheckButton->new_with_mnemonic("$UmaskGrpXTxt"); $UmaskGrpFrame = Gtk2::Frame->new("$UmaskGrpFrameTxt"); $UmaskGrpBox = Gtk2::HBox->new(TRUE,0); $UmaskGrpBox->pack_start($UmaskGrpR, FALSE, TRUE, 0); $UmaskGrpBox->pack_start($UmaskGrpW, FALSE, TRUE, 0); $UmaskGrpBox->pack_start($UmaskGrpX, FALSE, TRUE, 0); $UmaskGrpFrame->add($UmaskGrpBox); $UmaskOthR = Gtk2::CheckButton->new_with_mnemonic("$UmaskOthRTxt"); $UmaskOthW = Gtk2::CheckButton->new_with_mnemonic("$UmaskOthWTxt"); $UmaskOthX = Gtk2::CheckButton->new_with_mnemonic("$UmaskOthXTxt"); $UmaskOthFrame = Gtk2::Frame->new("$UmaskOthFrameTxt"); $UmaskOthBox = Gtk2::HBox->new(TRUE,0); $UmaskOthBox->pack_start($UmaskOthR, FALSE, TRUE, 0); $UmaskOthBox->pack_start($UmaskOthW, FALSE, TRUE, 0); $UmaskOthBox->pack_start($UmaskOthX, FALSE, TRUE, 0); $UmaskOthFrame->add($UmaskOthBox); #EntTimout part $EntTimoutLbl = Gtk2::Label->new; $EntTimoutLbl->set_justify('left'); $EntTimout1 = Gtk2::SpinButton::new_with_range($window, 0, 1000, 1); $EntTimout2 = Gtk2::SpinButton::new_with_range($window, 0, 9, 1); $EntTimoutBox = Gtk2::HBox->new(TRUE,0); $EntTimoutBox->pack_start($EntTimout1, FALSE, TRUE, 0); $EntTimoutBox->pack_start($EntTimout2, FALSE, TRUE, 0); #Timeout part $TimeoutLbl = Gtk2::Label->new; $TimeoutLbl->set_justify('left'); $Timeout = Gtk2::SpinButton::new_with_range($window, 0, 10000, 1); #Interval part $IntervalLbl = Gtk2::Label->new; $IntervalLbl->set_justify('left'); $Interval = Gtk2::SpinButton::new_with_range($window, 0, 10000, 1); # Main options tab matrix $MainOptMatrix = Gtk2::Table->new(6, 2, FALSE); $MainOptMatrix->set_border_width(7); $MainOptMatrix->set_row_spacings(5); $MainOptMatrix->set_col_spacings(7); $MainOptMatrix->attach_defaults($MntPntButton, 0, 1, 0, 1); $MainOptMatrix->attach_defaults($MntPnt, 1, 2, 0, 1); $MainOptMatrix->attach_defaults($GenUserLbl, 0, 1, 1, 2); $MainOptMatrix->attach_defaults($GenUser, 1, 2, 1, 2); $MainOptMatrix->attach_defaults($GenPassLbl, 0, 1, 2, 3); $MainOptMatrix->attach_defaults($GenPass, 1, 2, 2, 3); $MainOptMatrix->attach_defaults($HdShare, 1, 2, 3, 4); $MainOptMatrix->attach_defaults($OtherAccess, 1, 2, 5, 6); # Misc options tab matrix $MiscOptMatrix = Gtk2::Table->new(6, 2, FALSE); $MiscOptMatrix->set_border_width(7); $MiscOptMatrix->set_row_spacings(10); $MiscOptMatrix->set_col_spacings(7); $MiscOptMatrix->attach_defaults($UmaskUsrFrame, 0, 2, 0, 1); $MiscOptMatrix->attach_defaults($UmaskGrpFrame, 0, 2, 1, 2); $MiscOptMatrix->attach_defaults($UmaskOthFrame, 0, 2, 2, 3); $MiscOptMatrix->attach_defaults($EntTimoutLbl, 0, 1, 3, 4); $MiscOptMatrix->attach_defaults($EntTimoutBox, 1, 2, 3, 4); $MiscOptMatrix->attach_defaults($TimeoutLbl, 0, 1, 4, 5); $MiscOptMatrix->attach_defaults($Timeout, 1, 2, 4, 5); $MiscOptMatrix->attach_defaults($IntervalLbl, 0, 1, 5, 6); $MiscOptMatrix->attach_defaults($Interval, 1, 2, 5, 6); $NtBook = Gtk2::Notebook->new; $NtBook->append_page($MainOptMatrix, "$MainOptFrameTxt"); $NtBook->append_page($MiscOptMatrix, "$MiscOptFrameTxt"); $NtBook->set_scrollable(TRUE); sub AddNewExitCallback { $AddNewDlg->destroy; return FALSE; } sub CheckNameInNotbook { my $name="$_[0]"; foreach my $num (0..$NtBook->get_n_pages - 1) { my $page = $NtBook->get_tab_label($NtBook->get_nth_page($num))->get_text; return TRUE if ($page eq "$name"); } return FALSE; } sub AddNewOkCallback { $AddNewDlg->destroy; } sub DeleteRule { my $TabName = $NtBook->get_tab_label ($NtBook->get_nth_page ($NtBook->get_current_page))->get_text; delete $RulesUser{"$TabName"}; delete $RulesPass{"$TabName"}; $NtBook->remove_page($NtBook->get_current_page); } sub CreateNewRuleTab { my $TabName = $_[0]; my $NewPageMatrix; $NewPageMatrix = Gtk2::Table->new(7, 2, TRUE); $NewPageMatrix->set_border_width(7); # $NewPageMatrix->set_row_spacings(2); $NtBook->append_page($NewPageMatrix, "$TabName"); my $RulesPassLbl; my $RulesUserLbl; if ("$TabName" eq "[ignore]") { $RulesUserLbl = Gtk2::Label->new("$RuleServerTxt"); $RulesPassLbl = Gtk2::Label->new("$RuleWrkGTxt"); } else { $RulesUserLbl = Gtk2::Label->new("$RuleUserTxt"); $RulesPassLbl = Gtk2::Label->new("$RulePassTxt"); $RulesHidden{"$TabName"} = Gtk2::CheckButton->new_with_mnemonic("$RulesShHiddenTxt"); $RulesHidden{"$TabName"}->set_active(TRUE); $NewPageMatrix->attach_defaults($RulesHidden{"$TabName"}, 1, 2, 2, 3); if ("$TabName" ne "[global]") { $RulesIgnore{"$TabName"} = Gtk2::CheckButton->new_with_mnemonic("$RulesIgnoreTxt"); $RulesIgnore{"$TabName"}->set_active(FALSE); $NewPageMatrix->attach_defaults($RulesIgnore{"$TabName"}, 1, 2, 3, 4); } } $RulesUserLbl->set_justify('left'); $RulesPassLbl->set_justify('left'); $RulesUser{"$TabName"} = Gtk2::Entry->new(); $RulesPass{"$TabName"} = Gtk2::Entry->new(); if ("$TabName" ne "[global]") { my $RuleExitButton = Gtk2::Button->new_from_stock('gtk-delete'); $RuleExitButton->signal_connect(clicked => \&DeleteRule); $NewPageMatrix->attach_defaults($RuleExitButton, 0, 2, 5, 6); } $NewPageMatrix->attach_defaults($RulesUserLbl, 0, 1, 0, 1); $NewPageMatrix->attach_defaults($RulesUser{"$TabName"}, 1, 2, 0, 1); $NewPageMatrix->attach_defaults($RulesPassLbl, 0, 1, 1, 2); $NewPageMatrix->attach_defaults($RulesPass{"$TabName"}, 1, 2, 1, 2); $NewPageMatrix->show_all; return $NewPageMatrix; } sub AddNewRule { $AddNewDlg->set_title("$AddNewRuleDlgTxt"); $AddNewDlg->signal_connect(destroy => \&ExitCallback); $AddNewDlg->set_border_width(7); $AddNewDlg->set_icon_from_file("/usr/share/icons/hicolor/scalable/apps/fusesmbtool.svg"); my $NewNameEntLbl = Gtk2::Label->new("$AddNewRuleTxt"); $NewNameEntLbl->set_justify('left'); my $AddNewDlgOkButton = Gtk2::Button->new_from_stock('gtk-ok'); $AddNewDlgOkButton->signal_connect(clicked => \&AddNewOkCallback); $AddNewDlg->set_focus($AddNewDlgOkButton); my $AddNewDlgCloseButton = Gtk2::Button->new_from_stock('gtk-close'); $AddNewDlgCloseButton->signal_connect(clicked => \&AddNewExitCallback); my $AddNewDlgTbl = Gtk2::Table->new(2, 2, TRUE); $AddNewDlgTbl->set_col_spacings(7); $AddNewDlgTbl->attach_defaults($NewNameEntLbl, 0, 1, 0, 1); $AddNewDlgTbl->attach_defaults($NewNameEnt, 1, 2, 0, 1); $AddNewDlgTbl->attach_defaults($AddNewDlgOkButton, 0, 1, 1, 2); $AddNewDlgTbl->attach_defaults($AddNewDlgCloseButton, 1, 2, 1, 2); $AddNewDlg->add($AddNewDlgTbl); $AddNewDlg->show_all; Gtk2->main; $RuleName = $NewNameEnt->get_text; disp_err "$NoNewName", 2 if (!defined($RuleName) || "$RuleName" eq ""); disp_err "$AlreadyExists", 2 if (CheckNameInNotbook "$[RuleName]"); return if (!defined($RuleName) || "$RuleName" eq "" || "$RuleName" eq "global" || CheckNameInNotbook "[$RuleName]"); print "new rule name: [$RuleName]\n" if (defined($debug)); CreateNewRuleTab "[$RuleName]"; } ## Welcome to the Matrix #$OptionsMatrix = Gtk2::Table->new(2, 6, FALSE); #$OptionsMatrix->set_border_width(7); #$OptionsMatrix->set_row_spacings(7); #$OptionsMatrix->set_col_spacings(7); #$OptionsMatrix->attach_defaults($MntPntButton, 0, 1, 0, 1) ; #$OptionsMatrix->attach_defaults($MntPnt, 1, 2, 0, 1) ; # #$OptionsMatrix->attach_defaults($HdShareLbl, 0, 1, 1, 2) ; #$OptionsMatrix->attach_defaults($HdShare, 1, 2, 1, 2) ; # #$OptionsMatrix->attach_defaults($GenUserLbl, 0, 1, 2, 3) ; #$OptionsMatrix->attach_defaults($GenUser, 1, 2, 2, 3) ; # #$OptionsMatrix->attach_defaults($GenPassLbl, 0, 1, 3, 4) ; #$OptionsMatrix->attach_defaults($GenPass, 1, 2, 3, 4) ; # #$OptionsMatrix->attach_defaults($TimeoutLbl, 0, 1, 4, 5) ; #$OptionsMatrix->attach_defaults($Timeout, 1, 2, 4, 5) ; # #$OptionsMatrix->attach_defaults($IntervalLbl, 0, 1, 5, 6) ; #$OptionsMatrix->attach_defaults($Interval, 1, 2, 5, 6) ; # ## The frame around options #$OptionsFrame = Gtk2::Frame->new('Options'); #$OptionsFrame->set_border_width(3); #$OptionsFrame->add($OptionsMatrix); $LeftBox = Gtk2::VBox->new; $LeftBox->pack_start($NtBook, TRUE, TRUE, 0); $LeftBox->pack_start($StatusFrame, TRUE, TRUE, 0); #$LeftBox->pack_start($OptionsFrame, FALSE, TRUE, 0); #$LeftBox->pack_start($StatusFrame, FALSE, TRUE, 0); # Action area $ActionMatrix = Gtk2::Table->new(1, 1, TRUE); $StartStopButton = Gtk2::Button->new_from_stock('gtk-connect'); $StartStopButton->signal_connect(clicked => \&StartCallback); $ActionMatrix->attach_defaults($StartStopButton, 0, 1, 0, 1); $SaveButton = Gtk2::Button->new_from_stock('gtk-save'); $SaveButton->signal_connect(clicked => \&SaveCallback); $AddNewButton = Gtk2::Button->new("$NewRule"); $AddNewButton->signal_connect(clicked => \&AddNewRule); # In the Matrix again $ActionMatrix->set_col_spacings(7); $ActionMatrix->attach_defaults($AddNewButton, 0, 1, 2, 3); $ActionMatrix->attach_defaults($SaveButton, 0, 1, 4, 5); $RightBox = Gtk2::VBox->new; $RightBox->pack_start($ActionMatrix, FALSE, TRUE, 0); # The frame around action butttons $TopBox = Gtk2::HBox->new; $TopBox->pack_start($LeftBox, TRUE, TRUE, 0); $TopBox->pack_start($RightBox, TRUE, TRUE, 0); # Exit and About buttons $AboutButton = Gtk2::Button->new_from_stock('gtk-about'); $AboutButton->signal_connect(clicked => \&AboutCallback); $ExitButton = Gtk2::Button->new_from_stock('gtk-close'); $ExitButton->signal_connect(clicked => \&ExitCallback); $FooterMatrix = Gtk2::Table->new(1, 1, TRUE); $FooterMatrix->attach_defaults($AboutButton, 0, 1, 0, 1); $FooterMatrix->attach_defaults($ExitButton, 2, 3, 0, 1); $OuterBox = Gtk2::VBox->new; $OuterBox->pack_start($TopBox, TRUE, TRUE, 0); $OuterBox->pack_start($FooterMatrix, TRUE, TRUE, 0); $window->add($OuterBox); ####################################################################### # Core Functions ####################################################################### # We check for mountpoint availability, #usage : IsMounted $mountpoint, return values = TRUE/FALSE sub IsMounted { my $line; my $mountpoint = $_[0]; print "IsMounted : $mountpoint\n" if (defined($debug)); open(MTAB, ") { chomp $line; if (defined($line) && defined($mountpoint) && "$line" =~ /^.*$mountpoint.*$/ ) { print "found this mounted: $mountpoint\n" if (defined($debug)); close(MTAB); return TRUE; } } close(MTAB); print "ismounted=false\n" if (defined($debug)); return FALSE; } # Update the status field sub UpdateStatus { my $mountpoint = $_[0]; if (defined($mountpoint) && "$mountpoint" ne "" && IsMounted($mountpoint)) { $StatusField->set_text("$IsMountedTxt"); $StatusIcon->set_from_icon_name("gtk-yes", "menu"); $StartStopButton->destroy; $StartStopButton = Gtk2::Button->new_from_stock('gtk-disconnect'); $StartStopButton->signal_connect(clicked => \&StopCallback); $ActionMatrix->attach_defaults($StartStopButton, 0, 1, 0, 1); $StartStopButton->show; } else { $StatusField->set_text("$IsNotMountedTxt"); $StatusIcon->set_from_icon_name("gtk-no", "menu"); $StartStopButton->destroy; $StartStopButton = Gtk2::Button->new_from_stock('gtk-connect'); $StartStopButton->signal_connect(clicked => \&StartCallback); $ActionMatrix->attach_defaults($StartStopButton, 0, 1, 0, 1); $StartStopButton->show; } } sub TrueOrFalse { my $togglebutton = $_[0]; $togglebutton->set_label($togglebutton->get_active ? "$TrueTxt" : "$FalseTxt"); } sub ChooseMnt { my $mountpoint; my $ChooseFile = Gtk2::FileChooserDialog->new("Add File", $window, "select-folder", "gtk-cancel"=>"cancel", "gtk-ok"=>"ok" ); $ChooseFile->set_select_multiple ( FALSE ); if ($MntPnt && $MntPnt->get_text) { $ChooseFile->set_current_folder_uri($MntPnt->get_text); $ChooseFile->set_filename($MntPnt->get_text); } elsif (-w "$DefaultMountPoint") { $ChooseFile->set_current_folder_uri("$DefaultMountPoint"); $ChooseFile->set_filename("$DefaultMountPoint"); } else { $ChooseFile->set_current_folder_uri("/home/$user"); $ChooseFile->set_filename("/home/$user"); } if ( "ok" eq $ChooseFile->run ) { $mountpoint = $ChooseFile->get_filenames; $MntPnt->set_text($mountpoint); &UpdateStatus($mountpoint) ; $ChooseFile->destroy; return; } &UpdateStatus($mountpoint) ; $ChooseFile->show_all; $ChooseFile->destroy; } sub ExitCallback { Gtk2->main_quit ; return FALSE ; } sub SaveCallback { file_output("$FuseSmbConfFilePath", "$FuseSmbConfFile", 0, "### configuration file for fusesmb ###\n", "### Written by Fusesmbtool ###\n\n", "#global options\n\n", "[global]\n\n", &GetHideShConfigString, &GetGenUserConfigString, &GetGenPassConfigString,&GetTimeoutConfigString, &GetIntervalConfigString, "#specific options\n\n", &GetRulesConfigString, "#Todo....\n\n"); file_output("$FuseToolConfFilePath", "$FuseToolConfFile", 0, "### configuration file for Fusesmbtool ###\n", "### Written by Fusesmbtool ###\n\n", "#global options\n\n", "[global]\n\n", &GetMntPntConfigString, &GetUmaskConfigString, &GetOthAccessConfigString, &GetEntTimoutConfigString, "#specific options\n\n", "#Todo....\n\n"); } sub StartCallback { SaveCallback; my $mountpoint = $MntPnt->get_text(); Unmount "$mountpoint"; my $FuseMntOpts = "-o ".($OtherAccess->get_active? "allow_other," : ""). "fsname=smb $mountpoint"; my $err_msg = `fusesmb $FuseMntOpts 2>/dev/stdout`; if (defined($err_msg) && "$err_msg" ne "") { my ($prog, $msg) = split /: /, $err_msg, 2; disp_err("$msg", 0); } UpdateStatus("$mountpoint") ; } sub StopCallback { my $mountpoint = $MntPnt->get_text(); Unmount "$mountpoint"; UpdateStatus("$mountpoint") ; } sub AboutCallback { my $AboutBox = Gtk2::MessageDialog->new($window, 'modal', 'info', 'ok', "Fusesmbtool ($version):\n". "$AboutTxt"); # Close dialog on user response $AboutBox->signal_connect (response => sub { $AboutBox->destroy; 1 }); $AboutBox->show; } # get config file strings from widgets sub GetMntPntConfigString { return "; mountpoint for fusesmb path=".$MntPnt->get_text() . "\n\n"; } sub GetHideShConfigString { return "; List hidden shares showhiddenshares=". ($HdShare->get_active? "true" : "false") . "\n\n"; } sub GetGenUserConfigString { return "; General username username=". $GenUser->get_text() . "\n\n"; } sub GetGenPassConfigString { return "; General password password=". $GenPass->get_text() . "\n\n"; } sub GetTimeoutConfigString { return "; Connection timeout in seconds timeout=". $Timeout->get_text() . "\n\n"; } sub GetIntervalConfigString { return ";Interval for updating new shares in minutes interval=". $Interval->get_text() . "\n\n"; } sub GetUmaskConfigString { my $UmaskU=($UmaskUsrR->get_active ? 4 : 0) +($UmaskUsrW->get_active ? 2 : 0) +($UmaskUsrX->get_active ? 1 : 0); my $UmaskG=($UmaskGrpR->get_active ? 4 : 0) +($UmaskGrpW->get_active ? 2 : 0) +($UmaskGrpX->get_active ? 1 : 0); my $UmaskO=($UmaskOthR->get_active ? 4 : 0) +($UmaskOthW->get_active ? 2 : 0) +($UmaskOthX->get_active ? 1 : 0); return ";set file permissions (octal) umask=". $UmaskU. $UmaskG. $UmaskO . "\n\n"; } sub GetOthAccessConfigString { return "; allow access to other users allow_other=". ($OtherAccess->get_active ? "yes" : "no") . "\n\n"; } sub GetEntTimoutConfigString { return "; cache timeout for deleted names (0.0s) entry_timeout=". $EntTimout1->get_text(). $EntTimout2->get_text() . "\n\n"; } sub GetRulesConfigString { my $msg = ""; foreach my $num (2..$NtBook->get_n_pages - 1) { my $name = $NtBook->get_tab_label($NtBook->get_nth_page($num))->get_text; if ($name ne "[ignore]" && $name ne "$MainOptFrameTxt" && $name ne "$MiscOptFrameTxt" && $name ne "[global]") { $msg = "$msg; Servers/Share specific settings\n". "$name\n". "username=".$RulesUser{"$name"}->get_text."\n". "password=".$RulesPass{"$name"}->get_text."\n". "showhiddenshares=". ($RulesHidden{"$name"}->get_active? "true" : "false")."\n". "ignore=". ($RulesIgnore{"$name"}->get_active? "true" : "false"). "\n\n"; } elsif ($name eq "[ignore]") { $msg = "$msg; Section for servers and/or workgroups to ignore\n". "[ignore]\n". "servers=".$RulesUser{"$name"}->get_text."\n". "workgroups=".$RulesPass{"$name"}->get_text."\n\n"; } } return "$msg"; } sub FillValues { #set default values $MntPnt->set_text("$DefaultMountPoint"); $GenUserLbl->set_text("$GenUserLblTxt"); $GenUser->set_text("guest"); $GenPassLbl->set_text("$GenPassLblTxt"); $GenPass->set_text(""); $TimeoutLbl->set_text("$TimeoutLblTxt"); $Timeout->set_value(10); $IntervalLbl->set_text("$IntervalLblTxt"); $Interval->set_value(10); $OtherAccess->set_active(TRUE); $EntTimoutLbl->set_text("$EntTimoutLblTxt"); $EntTimout1->set_value(1); $EntTimout2->set_value(0); #general options $MntPnt->set_text($ToolConfHash{'path'}{'[global]'}) if (exists($ToolConfHash{'path'}) && exists($ToolConfHash{'path'}{'[global]'})); if (exists($ToolConfHash{'showhiddenshares'}) && exists($ToolConfHash{'showhiddenshares'}{'[global]'})) { $HdShare->set_active($ToolConfHash{'showhiddenshares'}{'[global]'} eq "true" ? TRUE : FALSE); } $GenUser->set_text($ToolConfHash{'username'}{'[global]'}) if (exists($ToolConfHash{'username'}) && exists($ToolConfHash{'username'}{'[global]'})); $GenPass->set_text($ToolConfHash{'password'}{'[global]'}) if (exists($ToolConfHash{'password'}) && exists($ToolConfHash{'password'}{'[global]'})); $Timeout->set_value($ToolConfHash{'timeout'}{'[global]'}) if (exists($ToolConfHash{'timeout'}) && exists($ToolConfHash{'timeout'}{'[global]'})); $Interval->set_value($ToolConfHash{'interval'}{'[global]'}) if (exists($ToolConfHash{'interval'}) && exists($ToolConfHash{'interval'}{'[global]'})); if (exists($ToolConfHash{'umask'}) && exists($ToolConfHash{'umask'}{'[global]'})) { my @umasktab = split //, $ToolConfHash{'umask'}{'[global]'}; if (@umasktab == 3) { if ($umasktab[0] > 3) { $UmaskUsrR->set_active(TRUE); $umasktab[0] -= 4; } else { $UmaskUsrR->set_active(FALSE); } if ($umasktab[0] > 1) { print "UmaskUsrW|"; $UmaskUsrW->set_active(TRUE); $umasktab[0] -= 2; } else { $UmaskUsrW->set_active(FALSE); } $UmaskUsrX->set_active($umasktab[0] ? TRUE : FALSE); if ($umasktab[1] > 3) { $UmaskGrpR->set_active(TRUE); $umasktab[1] -= 4; } else { $UmaskGrpR->set_active(FALSE); } if ($umasktab[1] > 1) { $UmaskGrpW->set_active(TRUE); $umasktab[1] -= 2; } else { $UmaskGrpW->set_active(FALSE); } $UmaskGrpX->set_active($umasktab[1] ? TRUE : FALSE); if ($umasktab[2] > 3) { $UmaskOthR->set_active(TRUE); $umasktab[2] -= 4; } else { $UmaskOthR->set_active(FALSE); } if ($umasktab[2] > 1) { $UmaskOthW->set_active(TRUE); $umasktab[2] -= 2; } else { $UmaskOthW->set_active(FALSE); } $UmaskOthX->set_active($umasktab[2] ? TRUE : FALSE); } } if (exists($ToolConfHash{'allow_other'}) && exists($ToolConfHash{'allow_other'}{'[global]'})) { $OtherAccess->set_active($ToolConfHash{'allow_other'}{'[global]'} eq "yes" ? TRUE : FALSE); } if (exists($ToolConfHash{'entry_timeout'}) && exists($ToolConfHash{'entry_timeout'}{'[global]'})) { my @EntTimeoutTab = split //, $ToolConfHash{'entry_timeout'}{'[global]'}; if (@EntTimeoutTab == 2) { $EntTimout1->set_value($EntTimeoutTab[0]); $EntTimout2->set_value($EntTimeoutTab[1]); } } ##Rules #ignore if ((exists($ToolConfHash{'servers'}) && exists($ToolConfHash{'servers'}{'[ignore]'})) ||(exists($ToolConfHash{'workgroups'}) && exists($ToolConfHash{'workgroups'}{'[ignore]'}))) { CreateNewRuleTab "[ignore]"; $RulesUser{"[ignore]"}->set_text($ToolConfHash{'servers'}{'[ignore]'}) if (exists($ToolConfHash{'servers'}) && exists($ToolConfHash{'servers'}{'[ignore]'})); $RulesPass{"[ignore]"}->set_text($ToolConfHash{'workgroups'}{'[ignore]'}) if (exists($ToolConfHash{'workgroups'}) && exists($ToolConfHash{'workgroups'}{'[ignore]'})); } my $Subk; my $k; foreach $k ("username", "password", "showhiddenshares", "ignore") { if (exists($ToolConfHash{"$k"})) { foreach $Subk (keys(%{$ToolConfHash{"$k"}})) { print "check section -$Subk-\n" if (defined($debug)); if ("$Subk" ne "[ignore]" && "$Subk" ne "[global]" && !CheckNameInNotbook("$Subk")) { print "CreateTab $Subk\n" if (defined($debug)); CreateNewRuleTab "$Subk"; $RulesUser{"$Subk"}->set_text($ToolConfHash{'username'}{"$Subk"}) if (exists($ToolConfHash{'username'}) && exists($ToolConfHash{'username'}{"$Subk"})); $RulesPass{"$Subk"}->set_text($ToolConfHash{'password'}{"$Subk"}) if (exists($ToolConfHash{'password'}) && exists($ToolConfHash{'password'}{"$Subk"})); $RulesHidden{"$Subk"}->set_active($ToolConfHash{'showhiddenshares'}{"$Subk"} eq "true" ? TRUE : FALSE) if (exists($ToolConfHash{'showhiddenshares'}) && exists($ToolConfHash{'showhiddenshares'}{"$Subk"})); $RulesIgnore{"$Subk"}->set_active($ToolConfHash{'ignore'}{"$Subk"} eq "true" ? TRUE : FALSE) if (exists($ToolConfHash{'ignore'}) && exists($ToolConfHash{'ignore'}{"$Subk"})); } } } } UpdateStatus($MntPnt->get_text()); } sub file_output { my $prog; my $msg; if ( ! -x "$_[0]") { print "creating $_[0]\n" if defined($debug); mkdir "$_[0]" or disp_err "$CantCreateTxt"." $_[0]", 0; } print "Saving in : $_[1]\n" if defined($debug); if (-w "$_[1]" || -w "$_[0]") { my $err_msg = `touch "$_[1]" 2>/dev/stdout`; if (defined($err_msg) && "$err_msg" ne "") { ($prog, $msg) = split /: /, $err_msg, 2; disp_err("$msg", 0); } #open for write overwrite append open(MYOUTFILE, ((! $_[2]) ? ">" : ">>")."$_[1]") or disp_err "$CantOpenTxt"." $_[1]", 0; for (my $i=3; $_[$i]; $i++) { print $_[$i] if defined($debug); print MYOUTFILE $_[$i]; print MYOUTFILE "\n"; } close(MYOUTFILE); $err_msg = `chmod 600 "$_[1]" 2>/dev/stdout`; if (defined($err_msg) && "$err_msg" ne "") { ($prog, $msg) = split /: /, $err_msg, 2; disp_err("$msg", 0); } } else {disp_err("$CantWriteTxt"." $_[1]", 0);} } ###### The end of times ###### FillValues; # show window and enter GTK+2 loop $window->show_all; Gtk2->main;