1# Copyright (C) 1992-2019, 2020 Free Software Foundation, Inc. 2# 3# This file is part of DejaGnu. 4# 5# DejaGnu is free software; you can redistribute it and/or modify it 6# under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 3 of the License, or 8# (at your option) any later version. 9# 10# DejaGnu is distributed in the hope that it will be useful, but 11# WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with DejaGnu; if not, write to the Free Software Foundation, 17# Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 18 19# Connect to HOSTNAME using rsh(1). 20# 21proc rsh_open { hostname } { 22 global spawn_id 23 24 set tries 0 25 set result -1 26 27 if {![board_info $hostname exists rsh_prog]} { 28 if { [which remsh] != 0 } { 29 set RSH remsh 30 } else { 31 set RSH rsh 32 } 33 } else { 34 set RSH [board_info $hostname rsh_prog] 35 } 36 37 if {[board_info $hostname exists username]} { 38 set rsh_useropts "-l [board_info $hostname username]" 39 } else { 40 set rsh_useropts "" 41 } 42 43 # Get the hostname and port number from the config array. 44 if {[board_info $hostname exists name]} { 45 set hostname [board_info $hostname name] 46 } 47 set hostname [lindex [split [board_info $hostname netport] ":"] 0] 48 if {[board_info $hostname exists shell_prompt]} { 49 set shell_prompt [board_info $hostname shell_prompt] 50 } else { 51 set shell_prompt ".*> " 52 } 53 54 if {[board_info $hostname exists fileid]} { 55 unset board_info($hostname,fileid) 56 } 57 58 spawn $RSH $rsh_useropts $hostname 59 if { $spawn_id < 0 } { 60 perror "invalid spawn id from $RSH" 61 return -1 62 } 63 64 send "\r\n" 65 while { $tries <= 3 } { 66 expect { 67 -re ".*$shell_prompt.*$" { 68 verbose "Got prompt\n" 69 set result 0 70 break 71 } 72 -re "TERM = .*$" { 73 warning "Setting terminal type to vt100" 74 set result 0 75 send "vt100\n" 76 break 77 } 78 "unknown host" { 79 exp_send "\003" 80 perror "telnet: unknown host" 81 break 82 } 83 "has logged on from" { 84 exp_continue 85 } 86 -re "isn't registered for Kerberos.*service.*$" { 87 warning "$RSH: isn't registered for Kerberos, please kinit" 88 catch close 89 catch wait 90 break 91 } 92 -re "Kerberos rcmd failed.*$" { 93 warning "$RSH: Kerberos rcmd failed, please kinit" 94 catch close 95 catch wait 96 break 97 } 98 -re "You have no Kerberos tickets.*$" { 99 warning "$RSH: No kerberos Tickets, please kinit" 100 catch close 101 catch wait 102 break 103 } 104 "Terminal type is" { 105 verbose "$RSH: connected, got terminal prompt" 2 106 set result 0 107 break 108 } 109 -re "trying normal rlogin.*$" { 110 warning "$RSH: trying normal rlogin." 111 catch close 112 catch wait 113 break 114 } 115 -re "unencrypted connection.*$" { 116 warning "$RSH: unencrypted connection, please kinit" 117 catch close 118 catch wait 119 break 120 } 121 -re "Sorry, shell is locked.*Connection closed.*$" { 122 warning "$RSH: already connected." 123 } 124 timeout { 125 warning "$RSH: timed out trying to connect." 126 } 127 eof { 128 perror "$RSH: got EOF while trying to connect." 129 break 130 } 131 } 132 incr tries 133 } 134 135 if { $result < 0 } { 136 close -i $spawn_id 137 set spawn_id -1 138 } else { 139 set board_info($hostname,fileid) $spawn_id 140 } 141 142 return $spawn_id 143} 144 145# Download SRCFILE to DESTFILE on DESTHOST. 146# 147proc rsh_download {desthost srcfile destfile} { 148 # must be done before desthost is rewritten 149 if {[board_info $desthost exists rcp_prog]} { 150 set RCP [board_info $desthost rcp_prog] 151 } else { 152 set RCP rcp 153 } 154 155 if {[board_info $desthost exists rsh_prog]} { 156 set RSH [board_info $desthost rsh_prog] 157 } else { 158 if { [which remsh] != 0 } { 159 set RSH remsh 160 } else { 161 set RSH rsh 162 } 163 } 164 165 if {[board_info $desthost exists username]} { 166 set rsh_useropts "-l [board_info $desthost username]" 167 set rcp_user "[board_info $desthost username]@" 168 } else { 169 set rsh_useropts "" 170 set rcp_user "" 171 } 172 173 if {[board_info $desthost exists name]} { 174 set desthost [board_info $desthost name] 175 } 176 177 if {[board_info $desthost exists hostname]} { 178 set desthost [board_info $desthost hostname] 179 } 180 181 set status [catch "exec $RSH $rsh_useropts $desthost rm -f $destfile |& cat" output] 182 set status [catch "exec $RCP $srcfile $rcp_user$desthost:$destfile |& cat" output] 183 if { $status == 0 } { 184 verbose "Copied $srcfile to $desthost:$destfile" 2 185 return $destfile 186 } else { 187 verbose "Download to $desthost failed, $output." 188 return "" 189 } 190} 191 192proc rsh_upload {desthost srcfile destfile} { 193 if {[board_info $desthost exists rcp_prog]} { 194 set RCP [board_info $desthost rcp_prog] 195 } else { 196 set RCP rcp 197 } 198 199 if {[board_info $desthost exists username]} { 200 set rcp_user "[board_info $desthost username]@" 201 } else { 202 set rcp_user "" 203 } 204 205 if {[board_info $desthost exists name]} { 206 set desthost [board_info $desthost name] 207 } 208 209 if {[board_info $desthost exists hostname]} { 210 set desthost [board_info $desthost hostname] 211 } 212 213 set status [catch "exec $RCP $rcp_user$desthost:$srcfile $destfile" output] 214 if { $status == 0 } { 215 verbose "Copied $desthost:$srcfile to $destfile" 2 216 return $destfile 217 } else { 218 verbose "Upload from $desthost failed, $output." 219 return "" 220 } 221} 222 223# Execute CMD on BOARDNAME. 224# 225proc rsh_exec { boardname program pargs inp outp } { 226 global timeout 227 228 verbose "Executing on $boardname: $program $pargs < $inp" 229 230 if {![board_info $boardname exists rsh_prog]} { 231 if { [which remsh] != 0 } { 232 set RSH remsh 233 } else { 234 set RSH rsh 235 } 236 } else { 237 set RSH [board_info $boardname rsh_prog] 238 } 239 240 if {[board_info $boardname exists username]} { 241 set rsh_useropts "-l [board_info $boardname username]" 242 } else { 243 set rsh_useropts "" 244 } 245 246 if {[board_info $boardname exists name]} { 247 set boardname [board_info $boardname name] 248 } 249 250 if {[board_info $boardname exists hostname]} { 251 set hostname [board_info $boardname hostname] 252 } else { 253 set hostname $boardname 254 } 255 256 # If CMD sends any output to stderr, exec will think it failed. 257 # More often than not that will be true, but it doesn't catch the 258 # case where there is no output but the exit code is non-zero. 259 if { $inp eq "" } { 260 set inp "/dev/null" 261 } 262 263 set ret [local_exec "$RSH $rsh_useropts $hostname sh -c '$program $pargs \\; echo XYZ\\\${?}ZYX'" $inp $outp $timeout] 264 set status [lindex $ret 0] 265 set output [lindex $ret 1] 266 267 verbose "$RSH status is $status, output is $output" 268 269 # `status' doesn't mean much here other than rsh worked ok. 270 # What we want is whether $program ran ok. Return $status 271 # if the program timed out, status will be 1 indicating that 272 # rsh ran and failed. If rsh fails, we will get FAIL rather 273 # than UNRESOLVED - this will help the problem be noticed. 274 if { $status != 0 } { 275 regsub "XYZ(\[0-9\]*)ZYX\n?" $output "" output 276 return [list $status "$RSH to $boardname failed for $program, $output"] 277 } 278 if { [regexp "XYZ(\[0-9\]*)ZYX" $output junk status] == 0 } { 279 set status "" 280 } 281 verbose "rsh_exec: status:$status text:$output" 4 282 if { $status eq "" } { 283 return [list -1 "Couldn't parse $RSH output, $output."] 284 } 285 regsub "XYZ(\[0-9\]*)ZYX\n?" $output "" output 286 return [list [expr {$status != 0}] $output] 287} 288