A simlpe Telnet Client Class utilizing Todd Martin's telnet package available at http://www.tmartin.org/tcltelnet .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | package require Itcl 3.3
package require telnet 2.0.0
itcl::class TelnetClient {
public variable host ""
public variable port 23
public variable user "admin"
public variable password "password"
public variable timeout 10
public variable debug 0
private variable my_sock ""
private variable out_buffer ""
public variable xwait ""
common xtimeout
constructor {args} {}
destructor {
disconnect
}
public method connect {args}
public method send {args}
public method disconnect {}
private method get_data {}
private method wait_complete {}
private method timeout {}
private method reset_timeout {}
private method wait_or_timeout {}
}
# Lowercase access procedure
proc telnetclient {args} {
uplevel ::TelnetClient $args
}
itcl::body TelnetClient::constructor {args} {
eval configure $args
if {($ip == "") || ($port == "")} {
error "IP and Port must be specified"
}
}
itcl::body TelnetClient::connect {args} {
if {![catch {telnet::open $host $port} conn]} {
set my_sock $conn
fconfigure $my_sock -blocking false -buffering none -translation auto -eofchar {}
flush $my_sock
fileevent $my_sock readable [itcl::code $this get_data]
wait_or_timeout
if {[regexp -nocase {(username|login|user)\s?:} $out_buffer]} {
set login [send "$user"]
if {[regexp -nocase {(password)\s?:} $login]} {
set passdRes [send "$password"]
if {[regexp {(.>)} $passdRes]} {
return 0
} else {
close $conn
error "Error: Unexpected System Prompt"
}
} else {
close $conn
error "Error: Unexpectd Password Prompt"
}
} else {
close $conn
error "Error: Unexpected Login Prompt"
}
} else {
error "Error: Connection Refused"
}
}
itcl::body TelnetClient::get_data {} {
if {[eof $my_sock]} {
close $my_sock
set connected 0
} else {
if {![catch {telnet::read $my_sock} data]} {
switch -regexp $data {
# Add login and password patterns as needed
{([Uu]sername|[Ll]ogin|[Pp]assword)\s?:} {
append out_buffer $data
wait_complete
return
}
# Change this value to your Telnet Prompt
{.>} {
append out_buffer $data
wait_complete
return
}
default {
append out_buffer $data
reset_timeout
}
}
} else {
wait_complete
close $mySocked
return
}
}
}
itcl::body TelnetClient::timeout {} {
catch {after cancel $xwait}
set xtimeout($this) 1
puts "Timeout of after [expr {$timeout * 1000}] seconds"
return
}
itcl::body TelnetClient::wait_or_timeout {} {
set xwait [after [expr {$timeout * 1000}] [itcl::code $this timeout]]
vwait [itcl::scope xtimeout($this)]
return
}
itcl::body tti::TelnetClient::reset_timeout {} {
catch {after cancel $xwait}
set xwait [after [expr {$timeout * 1000}] [itcl::code $this timeout]]
return
}
itcl::body TelnetClient::wait_complete {} {
catch {after cancel $xwait} wres
set xtimeout($this) 1
return
}
itcl::body TelnetClient::send {data} {
set out_buffer ""
if {![eof $my_sock]} {
if {![catch {telnet::write $my_sock "$data\r"} err]} {
flush $my_sock
fileevent $my_sock readable [itcl::code $this get_data]
wait_or_timeout
return $out_buffer
} else {
error "$err"
}
} else {
error "Error: Connection Closed"
}
}
itcl::body TelnetClient::disconnect {} {
catch { close $my_sock }
}
|
Useful when wrapping an existing client with Expect is too slow or not convinient due to the limitations with Expect and 64 bit apps in Windows.
To use the client create a telnet client object:
set tn1 [telnetclient #auto -host 192.168.165.100 -user user -password password]
Open the conncetion to the telnet server $tn1 connect
Send a command to to be executed. The result of the command is returned or an error.
set commandResult [$tn1 send "systeminfo"]
Close the connection to the telnet server $tn1 disconnect
Should this recipe work as is? I would like to use this code, but I can not get it to work.
I notice the value of "$data" is empty when telneting to the windows xp machine and then the script closes the telnet session.
Any thoughts?