#!/usr/bin/wish -f
#
# CHANGE the line above if wish is in a different location on
# your system.
#
# tkSamba-0.2a (replaces tkSamba-0.1a)
#
# This tcl/tk script provides a graphical interface to 
# the Samba routines for examining and connecting to shares.
#
# Written by Allin Cottrell (cottrell@wfu.edu), July 1996.
#

# ******************************************************************
# User-configurable variables -- you need to fill in appropriate
# values for the following: 

#username and password:
set user bloggs
set password gorble2
# NOTE: You should ensure this script is readable only by
# yourself.  Run "secure.sh" if you like.  
#
# label (to appear on button) for "global" NT server:
set global_label Global
# name (to be used by smbclient) of "global" NT server:
set global_server bigserv
# label (to appear on button) for local workgroup server:
set local_label Local
# name (to be used by smbclient) of local workgroup server:
set local_server myserve
# label for button for first "special" command:
set special1_label "Special 1"
# command string for first "special" button:
set special1_command "exec xterm -e shell_script.1"
# label for button for second "special" command:
set special2_label "Special 2"
# command string for second "special" button:
set special2_command "exec xterm -e shell_script.2"
# base directory for mounting shares with smbmount:
set mntdir "/mnt"
# additional string for smbmount, setting user and group:
set mntstring "-u bloggs -g users"
# (See the manpage for smbmount if in doubt.)
# xterm command:
set term "color_xterm"
# If you are using tk 4.0 or later and prefer the old "bisque"
# look to Motif gray, then uncomment the next line:
# tk_bisque

# End of user-configurable section *********************************


global server top_server sharelist 
global user password userstring IP mntdir mntstring nomount
global term open_term

set userstring "$user\x25$password"

wm title . "tkSamba"

label .toplabel 
pack .toplabel
.toplabel config -text "NT shares via Samba"

# Set up frame

    frame .frame -borderwidth 10
    pack .frame -side top -fill x -pady 0
    
# Buttons for global/local groups 

    radiobutton .frame.b1 -text $global_label -variable top_server \
	-relief flat -value $global_server
    .frame.b1 invoke
    	
    radiobutton .frame.b2 -text $local_label -variable top_server \
	-relief flat -value $local_server 
	
    pack .frame.b1 .frame.b2 \
        -side top -pady 2 -padx 200 -anchor w   


# Control buttons, special1 and special2    
    
    button .frame.sp1 -text $special1_label -width 12 -relief groove \
            -command $special1_command

    button .frame.sp2 -text $special2_label -width 12 -relief groove \
	    -command $special2_command

    pack .frame.sp1 .frame.sp2 -side left -expand yes -fill x 
    
    
# Control buttons, Shares and Quit    
    
    button .frame.ok -text Shares  -width 12 -relief groove \
            -command {
            catch {destroy .topshares}
            exec smbclient -L $top_server -U $userstring >top_list
            mkShowShares .topshares top_list
            }
            
    button .frame.quit -text Quit -width 12 -relief groove \
	    -command "rm_if_exist top_list; \
	              rm_if_exist next_list; \
	              destroy . "
	              
    pack .frame.ok .frame.quit -side left -expand yes -fill x 
    
    
# Various procedures follow: 

proc rm_if_exist {file} {
	if {[file exists "$file"]} {
	   exec rm "$file"
	}
}

# The following procedure creates a window to display the results of
# doing "smbclient -L" on the chosen server.

proc mkShowShares {w file} {
    global sharelist textlist1 browselist textlist2 
    global bold normal server top_server next_server
    catch {destroy $w}
    toplevel $w
    if {$file == "top_list"} {
        wm geometry $w +150+200
        set server $top_server
    } else {
        wm geometry $w +175+225
        set server $next_server
    }
    wm title $w "$server"
    wm iconname $w "$server"
    
    # Set up frame

    frame $w.frame
    
    # Set up little explanatory message
    
    message $w.msg -relief raised -text "Mouse button 1 over\
       a share to connect/browse; button 3 to mount" \
       -justify center -aspect 2000
    pack $w.msg -side top -fill x
       

    # Set up dismiss button
    
    button $w.frame.ok -text Dismiss -command "destroy $w"
    text $w.t -relief raised -bd 2 -yscrollcommand "$w.s set" \
       -setgrid true -width 92 
    scrollbar $w.s -relief flat -command "$w.t yview"

    pack $w.frame -side bottom -fill x -pady 0
    pack $w.frame.ok -side left -expand yes -fill x 

    pack $w.s -side right -fill y
    pack $w.t -expand yes -fill both
    
    # Set up display styles

    if {[winfo depth $w] != 1} {
	set bold "-foreground red"
	set normal "-foreground {}"
    } else {
	set bold "-foreground white -background black"
	set normal "-foreground {} -background {}"
    }
    
    parsefile $w $file
    $w.t configure -state disabled
}

proc insertWithTags {w text args} {
    set start [$w index insert]
    $w insert insert $text
    foreach tag [$w tag names $start] {
	$w tag remove $tag $start insert
    }
    foreach i $args {
	$w tag add $i $start insert
    }
}

# The following procedure parses the file written by "smbclient -L"
# (directed at the chosen server), and creates hotlinks to both
# shares on this server and the elements of its browse list, if any.

proc parsefile {w file} {
   global sharelist textlist1 browselist textlist2 
   global user password userstring IP mntdir mntpoint mntstring
   global bold normal server top_server next_server term
   set sharelist {}
   set textlist1 {}
   set browselist {}
   set textlist2 {}
   set info [open "$file" r]
   set k 0
   if {$file == "top_list"} {
       set t1 "a"
       set t2 "b"
       set IPstuff \"\"
   } else {
       set t1 "c"
       set t2 "d"
       set IPstuff " -I $IP"
   }
   
   #  First get introductory text from smbclient
   
   while {[gets $info line] >= 0 && $k < 1} {
      $w.t insert insert "$line\n"
      if {[string first "Comment" $line] != -1} { incr k }
   }
   
   # Then get the share list
   
   $w.t insert insert "$line\n"
   while {[gets $info line] >= 0 && $line != ""} {
         scan $line "%s" next
         lappend sharelist $next
         set len [expr [string length $next] + 1]
         set remainder [string range $line $len end]
         lappend textlist1 $remainder
   }
   
   set n [llength $sharelist]
   set taglist1 {}

   for {set i 0} {$i < $n} {incr i} {
        lappend taglist1 "$t1$i"
        insertWithTags $w.t "        [lindex $sharelist $i]" \
                                     [lindex $taglist1 $i]
        insertWithTags $w.t [lindex $textlist1 $i]
        insertWithTags $w.t \n
        $w.t tag bind [lindex $taglist1 $i] <Any-Enter> \
            "$w.t tag configure [lindex $taglist1 $i] $bold"
        $w.t tag bind [lindex $taglist1 $i] <Any-Leave> \
            "$w.t tag configure [lindex $taglist1 $i] $normal"
        $w.t tag bind [lindex $taglist1 $i] <1> \
            " exec $term -title $server/[lindex $sharelist $i] -e \
              smbclient \\\\\\\\$server\\\\[lindex $sharelist $i] \
              $IPstuff -U $user\\x25$password "
        $w.t tag bind [lindex $taglist1 $i] <3> \
            " set nomount 0
              mkMountpt .mnt $server/[lindex $sharelist $i]
              tkwait window .mnt
              if {\$nomount == 0} {
              exec mkdir -p \$mntpoint ;
              exec smbmount //$server/[lindex $sharelist $i] \
              \$mntpoint -P $password -U $user \$mntstring 
              if {\$open_term == 1} {
                  set currdir \[pwd\]
                  cd \$mntpoint
                  exec $term -title \$mntpoint &
                  cd \$currdir }
              } "
   }     
   
   $w.t insert insert "\n"
   
   # Now get the next bit of text (if there is one)
   
   while {[gets $info line] >= 0 && $k < 2} {
      $w.t insert insert "$line\n"
      if {[string first "Comment" $line] != -1} { incr k }
   }
   
   # And the machine's browse list (if any)
   
   $w.t insert insert "$line\n"
   while {[gets $info line] >= 0} {
         scan $line "%s" next
         lappend browselist $next
         set len [expr [string length $next] + 1]
         set remainder [string range $line $len end]
         lappend textlist2 $remainder
   }
    
   set n [llength $browselist]
   set taglist2 {}

   for {set i 0} {$i < $n} {incr i} {
        lappend taglist2 "$t2$i"
        insertWithTags $w.t "        [lindex $browselist $i]" \
                                     [lindex $taglist2 $i]
        insertWithTags $w.t [lindex $textlist2 $i]
        insertWithTags $w.t \n
        $w.t tag bind [lindex $taglist2 $i] <Any-Enter> \
            "$w.t tag configure [lindex $taglist2 $i] $bold"
        $w.t tag bind [lindex $taglist2 $i] <Any-Leave> \
            "$w.t tag configure [lindex $taglist2 $i] $normal"
        $w.t tag bind [lindex $taglist2 $i] <1> \
            " set IP \[exec nmblookup [lindex $browselist $i] \
               | grep [lindex $browselist $i] \
               | sed /[lindex $browselist $i]/s///\]
              exec smbclient -L [lindex $browselist $i] \
              -I \$IP -U $user\\x25$password >next_list
               set next_server [lindex $browselist $i]
               mkShowShares .nextshares next_list "
   }   
   
}

proc mkMountpt {w share} {
    global mntdir mntstring mntpoint nomount open_term
    catch {destroy $w}
    toplevel $w
    wm geometry $w +160+175
    wm title $w "Smbmount"
    wm iconname $w "mounting"

    message $w.msg -font -Adobe-times-medium-r-normal--*-180* -aspect 2000 \
	    -text "Mounting $share..."
    frame $w.frame -borderwidth 10
    pack $w.msg -side top
    pack $w.frame -side top -expand yes -fill y
    
    # Entry boxes for directory, extra string
    
    set mntpoint "$mntdir/$share"
           
    frame $w.frame.vars    
    foreach i {mntpoint mntstring} {
        frame $w.frame.vars.$i -bd 1m
        entry $w.frame.vars.$i.entry -relief sunken -width 30 \
            -textvariable $i
        label $w.frame.vars.$i.label -width 14
        pack $w.frame.vars.$i.label -side left -padx 2 -anchor w
        pack $w.frame.vars.$i.entry  -padx 4 -anchor w
        bind $w.frame.vars.$i.entry <Delete>  {DelChar .$i.entry}
        pack $w.frame.vars.$i -side top -fill x
    }
    pack $w.frame.vars -side top

    $w.frame.vars.mntpoint.label config -text "mount point:"
    $w.frame.vars.mntstring.label config -text "extra string:"
    
    # Checkbutton for opening xterm on the mount point
    
    checkbutton $w.frame.term -text "Open xterm on mount point?" \
         -variable open_term 
    pack $w.frame.term
	
    # Control buttons at foot of window, OK, Clear and Quit
    
    frame $w.control
    button $w.control.ok -relief groove -text OK \
         -command "set mntstring \" $mntstring\" ; destroy $w"
       
    button $w.control.clear -relief groove -text Clear -command {
         foreach i {mntpoint mntstring} {
         set $i ""
         }
    }
        
    button $w.control.cancel -relief groove -text Quit \
        -command "set nomount 1 ; destroy $w"
        
    pack $w.control.ok $w.control.clear $w.control.cancel \
        -side left -expand yes -fill x
        
    pack $w.control -side top -expand yes -fill x
           
}

