home *** CD-ROM | disk | FTP | other *** search
-
- #!/bin/sh
- # \
- exec wish "$0" "$@"
-
- #
- # xeznet - Tcl/Tk interface for 'eznet'
- # xeznet,v 1.8 1999/02/19 00:55:48 migh Exp
- #
-
- option add *borderWidth 1
- option add *Label*anchor w
- option add *Label*foreground DarkBlue
-
- bind Entry <FocusIn> {%W configure -background gray95; show_help %W}
- bind Entry <FocusOut> {%W configure -background gray85}
-
- set upd_rate 60 ;# status update rate (see menu settings)
- set nquick 0 ;# number of quick updates for service up/down
-
- set rc_file ~/.xeznet_rc
-
- #
- # Return a list of selected service names
- #
- proc get_sel { } {
- msg ""
- set svcs {}
- foreach ix [.lbox.list curselection] {
- set line [.lbox.list get $ix]
- set svc [string trim \
- [string range $line 1 \
- [string wordend $line 1]]]
- if {$svc == ""} {
- continue
- }
- lappend svcs $svc
- }
- if {[llength $svcs] == 0} {
- msg "Select a service, then click the button."
- }
- return $svcs
- }
-
- #
- # Make a new action window for each selected service name
- #
- proc do_sel {action} {
- if {$action == "add"} {
- msg ""
- svc_window add new
- } {
- foreach svc [get_sel] {
- svc_window $action $svc
- }
- }
- return
- }
-
- #
- # Bring the selected service(s) up or down
- # TODO: we sometimes exit when we bring down a service
- #
- proc do_updn {dir} {
- set svcs [get_sel]
- foreach svc $svcs {
- msg "Bringing $dir $svc."
- catch {exec eznet $dir $svc >/dev/null &}
- }
- if {[llength $svcs] > 0} {
- global nquick
- set nquick 12
- svc_status
- }
- return
- }
-
- #
- # Refresh the current service status
- #
- proc svc_status {{repeat 0}} {
- set fid 0
- if {[catch {open "|eznet status" r} fid] == 0} {
- set sel [lindex [.lbox.list curselection] 0]
- .lbox.list delete 0 end
- while {[gets $fid line] > 0} {
- set p [string first ":" $line]
- set svc [string range $line 0 [expr {$p - 1}]]
- set stat [string range $line [expr {$p + 1}] end]
- .lbox.list insert end [format " %-10s %s" $svc $stat]
- }
- catch {close $fid}
- if {$sel != ""} {
- .lbox.list selection set $sel
- .lbox.list activate $sel
- .lbox.list see $sel
- }
- } {
- msg "Unable to get status from 'eznet'."
- }
-
- # do we repeat? how soon?
- set dt 0
- global nquick
- if {$nquick > 0} {
- set dt 5000
- incr nquick -1
- } elseif {$repeat > 0} {
- global upd_rate
- set dt [expr {$upd_rate * 1000}]
- }
- if {$dt > 0} {
- after $dt svc_status 1
- }
- return
- }
-
- #
- # Handle the "OK" button on the service information window
- #
- proc do_svc_ok {w action} {
- set svc [$w.service.e get]
- if {$action == "delete"} {
- msg "Deleted $svc"
- catch {exec eznet delete $svc >/dev/null}
- } elseif {$action != "show"} {
- set cmd "eznet $action $svc"
- set args ""
- global all_entries
- foreach x $all_entries {
- set val [$w.$x.e get]
- # TODO: How do we clear an entry???
- if {$val != ""} {
- if {$x == "password" && [string index $val 0] == "*"} {
- continue
- } {
- append args " \"$x=$val\""
- }
- }
- }
- if {$args != ""} {
- msg "$cmd ..."
- catch {eval exec $cmd $args >/dev/null}
- }
- }
- destroy $w
- update idletasks
- if {$action != "show"} {
- svc_status
- }
- return
- }
-
- array set entry_help {
- phone "Phone number for modem to dial"
- user "User login name"
- password "Login password"
- tty "Serial port for the modem"
- baud "Baud rate for the serial port"
- service "Name of the ISP"
- chat "`no' to ignore `login:' prompts, etc."
- autostart "`no' to not start pppd if no `login:'"
- pppversion "Version of pppd in use"
- debug "`yes' to turn on pppd debugging"
- expectN "Extra expect string"
- replyN "Reply to issue after expect string"
- initN "Extra modem initialization string"
- diald "Name of diald executable"
- pppd "Name of pppd executable"
- local "Local IP address for diald slip link"
- remote "Remote IP address for diald slip link"
- idle "Number of seconds for idle timeout"
- persist "`yes' for a permanent connection"
- defaultroute "`no' to not create a default route"
- pppoptN "Extra parameters to pppd"
- routeN "Add this route when pppd comes up"
- ip "Network accessed by this service"
- netmask "Netmask for the ip network"
- dialtimeout "Time allowed for modem connect"
- chattimeout "Time allowed for chat dialog"
- }
-
- proc show_help {w} {
- global entry_help
- set parts [split $w .]
- set pw [lindex $parts 1]
- set ent [lindex $parts 2]
- if {[winfo exists .$pw.help]} {
- regsub {[0-9]} $ent N ent
- if {![info exists entry_help($ent)]} {
- set entry_help($ent) "(unknown)"
- }
- .$pw.help configure -text "$ent - $entry_help($ent)"
- }
- return
- }
-
- array set win_txt {
- add "Create Service"
- show "Show Service for $svc"
- edit "Edit Service for $svc"
- delete "Delete Service for $svc ?"
- }
-
- set win_id 0
-
- #
- # Split all the available entries/settings into subsets for display
- #
- set basic_entries {
- service phone user password tty baud
- }
-
- set modem_entries {
- chat
- diald dialtimeout chattimeout idle
- init0 init1 init2 init3 init4
- }
-
- set chat_entries {
- expect0 reply0
- expect1 reply1
- expect2 reply2
- expect3 reply3
- expect4 reply4
- }
-
- set ppp_entries {
- pppd pppversion
- pppopt0 pppopt1 pppopt2 pppopt3 pppopt4
- autostart debug
- }
-
- set ip_entries {
- local remote ip netmask persist
- }
-
- set route_entries {
- defaultroute
- route0 route1 route2 route3 route4
- }
-
- set all_entries [concat $basic_entries $modem_entries $chat_entries\
- $ppp_entries $ip_entries $route_entries]
-
- #
- # List of frame names and titles
- # (names should match above entry lists)
- #
- set frame_list {
- {basic "Basic Settings"}
- {modem "Modem Settings"}
- {chat "Chat Dialog Settings"}
- {ppp "PPP Settings"}
- {ip "IP Settings"}
- {route "Route Settings"}
- }
-
- #
- # Unpack the current selection frame; pack a new one
- #
- proc newframe {w opt} {
- # unpack the old frame (find it by name "f_xyz")
- foreach slave [pack slaves $w] {
- if {[string first "f_" $slave] > 0} {
- pack forget $slave
- }
- }
- # new text on menu button
- global frame_defs
- $w.fs configure -text $frame_defs($opt)
-
- # pack the new frame
- pack $w.f_$opt -side top -fill both -expand yes
-
- # select first entry (to update the help-text, if there)
- global ${opt}_entries
- set x [lindex [set ${opt}_entries] 0]
- $w.$x.e select range 0 end
- focus $w.$x.e
- }
-
- #
- # Make a service-information window
- #
- proc svc_window {action svc} {
- global win_id win_txt
-
- # make a new window
- set w .w[incr win_id]
- toplevel $w
- wm title $w [subst $win_txt($action)]
- # TODO: wm iconbitmap $w ... ?
-
- # make a menu button to choose among the frames
- menubutton $w.fs -indicatoron 1 -menu $w.fs.menu -anchor w \
- -text "Basic Settings" -relief raised
- menu $w.fs.menu -tearoff 0
-
- # make some frames to hold subsets of entries
- global frame_list frame_defs
- foreach x $frame_list {
- foreach {base label} $x { }
-
- # save name-label association for later
- # add menu button to the menu
- set frame_defs($base) $label
- $w.fs.menu add radiobutton -label $label -indicatoron 0 \
- -command "newframe $w $base"
-
- # make the frame and fill it with its labelled entries
- global ${base}_entries
- frame $w.f_$base
- foreach x [set ${base}_entries] {
- labent $w $x
- pack $w.$x -in $w.f_$base -side top -fill x
- }
- }
-
- # make the bottom button row
- buttons $w.b left \
- [list OK "do_svc_ok $w $action"] \
- [list Cancel "destroy $w"]
-
- # put the frame-selector on top, button-row on bottom, frame inbetween
- pack $w.fs -side top -fill x
- pack $w.b -side bottom -fill x
- pack $w.f_basic -side top -fill both -expand yes
-
- # make the 'OK' button look special on the delete-window
- if {$action == "delete"} {
- $w.b.b1 configure -activeforeground Red -fg Red -text Delete
- }
-
- # for editable windows, add a prompt-line for help messages
- if {$action == "add" || $action == "edit"} {
- label $w.help -text "" -fg Black -relief sunken -padx 1m \
- -font Helvetica
- pack $w.help -side bottom -fill x
- }
-
- if {$action == "add"} {
- $w.service.e insert 0 service-name
- $w.service.e select range 0 end
- focus $w.service.e
- } {
- update
- if {[catch {open "|eznet list $svc" r} fid] == 0} {
- while {[gets $fid buf] > 0} {
- set p [string first "=" $buf]
- incr p -1
- set var [string trim [string range $buf 0 $p]]
- incr p 2
- set val [string trim [string range $buf $p end]]
- if {[winfo exists $w.$var.e]} {
- $w.$var.e insert 0 $val
- }
- # TODO: else report missing values?
- }
- catch {close $fid}
- }
- }
-
- # make the 'show' and 'delete' windows read-only
- if {$action == "show" || $action == "delete"} {
- global all_entries
- foreach x $all_entries {
- $w.$x.e configure -state disabled
- }
- if {$action == "show"} {
- bind $w <Return> [list $w.b.b1 invoke]
- }
- }
- return
- }
-
- #
- # Put messages or errors in the message line
- #
- proc err {msg} {
- .msg configure -text "Error! $msg"
- return
- }
-
- proc msg {msg} {
- .msg configure -text $msg
- return
- }
-
- # proc ask_yn {msg} {
- # return [tk_messageBox -title Question -message $msg \
- # -icon question -type yesno]
- # }
-
- ###
- ### Some GUI-creation helper routines...
- ###
-
- #
- # Make a menubar with menus
- #
- proc menu_bar {w args} {
- if {[winfo exists $w] == 0} {
- frame $w -relief raised -borderwidth 2
- }
- set mnum 0 ;# menu counter
- set inum 0 ;# item counter
-
- foreach arg $args {
- foreach {type name var val v2} $arg { }
- if {$inum == 0 && [string match "menu*" $type] == 0} {
- err "menu_bar: need menu to hold $type/$name menu-item"
- return
- }
- switch $type {
- menu {
- set mbase $w.m[incr mnum]
- set new $mbase.menu
- menubutton $mbase -text $name -menu $new
- menu $new -disabledforeground DarkBlue
- set inum 1
- }
- sep {
- $new add sep
- }
- label {
- $new add command -label $name -state disabled
- incr inum
- }
- cmd {
- $new add command -label $name -command $var
- incr inum
- }
- radio {
- global $var
- $new add radiobutton -label $name \
- -variable $var -value $val
- incr inum
- }
- check {
- global $var
- $new add checkbutton -label $name \
- -variable $var -offvalue $val -onvalue $v2
- incr inum
- }
- end {
- # pack this menu on the given side
- pack $mbase -side $name -padx 1m
- set inum 0
- }
- default {
- err "menu_bar: unknown type '$type' for '$name'"
- return
- }
- }
- }
- return
- }
-
- #
- # Make a button row from names and commands
- #
- proc buttons {w dir args} {
- if {[winfo exists $w] == 0} {
- frame $w
- }
- set i 0
- set btns ""
- foreach arg $args {
- foreach {name cmd} $arg { }
- set btn $w.b[incr i]
- append btns " $btn"
- button $btn -text $name -command $cmd -width 4
- }
- eval pack $btns -side $dir -fill x -expand yes
- return
- }
-
- #
- # Make a labeled entry
- #
- proc labent {w x} {
- if {[winfo exists $w.$x] == 0} {
- frame $w.$x
- }
- label $w.$x.l -text $x -anchor e -width 10 -padx 3m
- entry $w.$x.e -width 25
- pack $w.$x.l -side left -fill x
- pack $w.$x.e -side left -fill x -expand yes
- return
- }
-
- #
- # Make a listbox/scrollbar pair, connect them
- #
- proc list_box {w title action} {
- if {[winfo exists $w] == 0} {
- frame $w
- }
- label $w.hdr -text $title -font fixed -anchor w
- scrollbar $w.sb -command "$w.list yview"
- listbox $w.list -yscroll "$w.sb set" \
- -font fixed -setgrid 1 -height 5
-
- pack $w.hdr -side top -fill x
- pack $w.sb -side right -fill y
- pack $w.list -side left -fill both -expand yes
- if {$action != ""} {
- bind $w.list <Double-1> $action
- bind $w.list <Return> $action
- }
- bind $w.list <Control-p> {tkListboxUpDown %W -1}
- bind $w.list <Control-n> {tkListboxUpDown %W 1}
- bind $w.list <k> {tkListboxUpDown %W -1}
- bind $w.list <j> {tkListboxUpDown %W 1}
- return
- }
-
- #
- # Make a text-box/scrollbar pair, connect them
- #
- proc text_box {w {title ""}} {
- if {[winfo exists $w] == 0} {
- frame $w
- }
- if {$title != ""} {
- label $w.hdr -text $title -font fixed
- pack $w.hdr -side top -fill x
- }
- scrollbar $w.sb -command "$w.text yview"
- text $w.text -yscroll "$w.sb set" -setgrid 1
- # -font fixed
-
- pack $w.sb -side right -fill y
- pack $w.text -side left -fill both -expand yes
-
- $w.text insert end "Please wait..."
- return
- }
-
- #
- # Given some text, fill a text-box
- #
- proc fill_textbox {tb ro txt} {
- set t $tb.text
- $t configure -state normal
- $t delete 1.0 end
- $t mark set insert 0.0
- $t insert end $txt
-
- if {$ro == "ro"} {
- $t configure -state disabled
- $t mark set curs 0.0
- } {
- $t mark set insert 0.0
- }
- return
- }
-
- #
- # Make a simple text window
- #
- proc simple_text {w title} {
- if {[winfo exists $w] == 0} {
- toplevel $w
- # TODO: wm iconbitmap . ...
- if {$title != ""} {
- wm title $w $title
- }
- text_box $w.tbox
- buttons $w.b left [list Done "destroy $w"]
- pack $w.tbox -side top -fill both -expand yes
- pack $w.b -side bottom -fill x
- bind $w <Return> "destroy $w"
- focus $w.tbox.text
- } {
- wm deiconify $w
- }
- return
- }
-
- ###
- ### End of GUI helpers
- ###
-
- #
- # Save our current settings
- #
- proc save_settings { } {
- global rc_file
- if {[catch {open $rc_file w} fid] == 0} {
- puts $fid "wm geometry . [wm geometry .]"
- set sel [lindex [.lbox.list curselection] 0]
- if {$sel != ""} {
- puts $fid "set lbsel $sel"
- } {
- puts $fid "set lbsel -1"
- }
- catch {close $fid}
- }
- }
-
- #
- # Are we 'root'?
- #
- proc as_root { } {
- global env
- set rt 0
- if {[info exists env(TESTING_XEZNET)]} {
- set rt 1
- } elseif {[catch {open "|id" r} fid] == 0} {
- set id [read $fid]
- catch {close $fid}
- if {[string first "(root)" $id] > 0} {
- set rt 1
- }
- }
- return $rt
- }
-
- #
- # Make a new window, fill it with 'eznet log'
- #
- proc see_log { } {
- simple_text .w_log "Log file from eznet"
- update
- if {[catch {open "|eznet log" r} fid] == 0} {
- set txt [read $fid]
- catch {close $fid}
- } {
- set txt "Problems running 'eznet log'!"
- }
- fill_textbox .w_log.tbox ro $txt
- return
- }
-
- set eznet_icon {
- #define eznet_width 32
- #define eznet_height 32
- static unsigned char eznet_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0xfe, 0x1f, 0xf8, 0x3f, 0xfe, 0x1f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1c,
- 0x18, 0x00, 0x00, 0x0e, 0x18, 0x00, 0x00, 0x07, 0x18, 0x00, 0x80, 0x03,
- 0x18, 0x1f, 0xc0, 0x01, 0x18, 0x1f, 0xe0, 0x00, 0x18, 0x00, 0x70, 0x00,
- 0x18, 0x00, 0x38, 0x00, 0x18, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0e, 0x00,
- 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0xfe, 0x3f,
- 0xf8, 0x3f, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- }
-
- #
- # Work-around a Tcl/Tk "feature":
- # - bitmaps work OK on buttons, but are not accepted by the 'wm' command
- #
- proc wm_set_icon {w icon} {
- set iconFile /tmp/.eznet_icon.[pid]
- if {[catch {open $iconFile w} fid] == 0} {
- puts $fid $icon
- close $fid
- wm iconbitmap $w @$iconFile
- catch {file delete $iconFile}
- }
- return
- }
-
- #
- # Make the main control and status panel
- #
- proc make_ui { } {
- global upd_rate eznet_icon
- wm title . "EZNET Interface"
- wm iconname . "xeznet"
- wm command . "xeznet"
- wm_set_icon . $eznet_icon
-
- menu_bar .mbar \
- {menu File} \
- {cmd "See log..." see_log} \
- {cmd Save save_settings} \
- {sep} \
- {cmd Quit exit} \
- {end left} \
- \
- {menu Update} \
- {cmd Now svc_status} \
- {radio "10 sec" upd_rate 10} \
- {radio "30 sec" upd_rate 30} \
- {radio " 1 min" upd_rate 60} \
- {radio " 5 min" upd_rate 300} \
- {end left} \
- \
- {menu Help} \
- {cmd About do_about} \
- {cmd Usage do_use} \
- {end right}
-
- list_box .lbox " Service Status" {do_sel show}
- bind . <Any-Enter> {focus .lbox.list}
-
- buttons .cmd left \
- {Show {do_sel show}} \
- {Edit {do_sel edit}} \
- {Add {do_sel add}} \
- {Delete {do_sel delete}} \
- {Up {do_updn up}} \
- {Down {do_updn down}} \
- {Quit exit}
-
- # if not root, pull off Edit/Add/Delete buttons
- if {[as_root] == 0} {
- destroy .cmd.b2
- destroy .cmd.b3
- destroy .cmd.b4
- }
-
- label .msg -text ""
-
- pack .mbar -side top -fill x
- pack .lbox -side top -fill both -expand yes
- pack .cmd .msg -side bottom -fill x
- return
- }
-
- proc do_about { } {
- simple_text .w_about "About xeznet"
- .w_about.tbox.text configure -height 9
- fill_textbox .w_about.tbox ro {
- xeznet is a graphical front-end for the 'eznet' command.
- This is version 1.8 made on 1999/02/19 00:55:48.
-
- Mike Hall <mghall@enteract.com> is the author of 'xeznet'.
-
- D. Richard Hipp" <drh@acm.org> is the author of 'eznet',
- and provided essential suggestions to improve 'xeznet'.
- }
- return
- }
-
- proc do_use { } {
- simple_text .w_usage "How to use 'xeznet'"
- fill_textbox .w_usage.tbox ro {
- OPERATION:
- ----------
-
- NOTE: The Edit, Add, and Delete buttons will appear only for the 'root' user!
-
- To create a new service, you must be 'root':
- Click on the Add button.
- A new window will appear; fill in the forms.
- Click on the OK button to have 'eznet' create the new service.
-
- To edit or delete an existing service, you must be 'root':
- Select an entry, then click on the Edit (or Delete) button.
- A new window will appear, showing you the service.
- Click on the OK button to post your edits to 'eznet'
- (or click on the Delete button to delete the service).
-
- To show the settings for a service:
- Method 1: select an entry, then click on the Show button.
- Method 2: select an entry, then press the Return key
- Method 3: double-click on an entry
-
- A new window will appear, showing you the service parameters.
- Click on the OK button to close the window.
-
- To bring a service up or down:
- Select the service, then click on the Up or Down button.
- The listbox will track the progress of the connection.
-
-
- SERVICE INFORMATION WINDOW:
- -------------------------------
- There are several sections in the service popup window:
- - Selection menu, to select groups of settings
- - List of entries, to examine or change 'eznet' settings
- - Optional setting description, to explain the meaning of a setting
- - OK and Cancel buttons, to accept the settings or cancel
-
- One of several groups of entries can be selected from the menu:
- Basic Settings
- Modem Settings
- Chat Dialog Settings
- PPP Settings
- IP Settings
- Route Settings
-
-
- MENUS:
- ------
- File /
- See log ... Show the 'eznet' log file.
- Save Save the current position, size, and service.
- Quit Exit the 'xeznet' program.
-
- Update /
- Now Update the status panel immediately.
- 10 sec Update the status panel every 10 seconds.
- 30 sec .. .. 30 seconds
- 1 min .. .. minute
- 5 min .. .. 5 minutes
-
- Note: when bringing a service up or down,
- the status is automatically updated every 5 seconds for one minute.
-
- Help /
- About Pops up a small version panel.
- Usage Brings up this text panel.
- }
- return
- }
-
- #
- # Make the interface, start status updates
- #
- make_ui
-
- # no entries to highlight; read in the RC file for position/settings
- set lbsel -1
- if {[file exists $rc_file]} {
- source $rc_file
- }
-
- # draw the interface
- update
-
- # start the updates (fill the listbox)
- svc_status 1
-
- # highlight an entry if one was saved last time
- if {$lbsel >= 0} {
- .lbox.list selection set $lbsel
- .lbox.list activate $lbsel
- }
-