OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [expect/] [example/] [kibitz] - Blame information for rev 1778

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
#!../expect --
2
# allow another user to share a shell (or other program) with you
3
# See kibitz(1) man page for complete info.
4
# Author: Don Libes, NIST
5
# Date written: December 5, 1991
6
# Date last editted: October 19, 1994
7
# Version: 2.11
8
exp_version -exit 5.0
9
 
10
# if environment variable "EXPECT_PROMPT" exists, it is taken as a regular
11
# expression which matches the end of your login prompt (but does not other-
12
# wise occur while logging in).
13
 
14
set prompt "(%|#|\\$) $"        ;# default prompt
15
set noproc 0
16
set tty ""                      ;# default if no -tty flag
17
set allow_escape 1              ;# allow escapes if true
18
set escape_char \035            ;# control-right-bracket
19
set escape_printable "^\]"
20
set verbose 1                   ;# if true, describe what kibitz is doing
21
 
22
set kibitz "kibitz"             ;# where kibitz lives if some unusual place.
23
                                ;# this must end in "kibitz", but can have
24
                                ;# things in front (like directory names).
25
#set proxy "kibitz"             ;# uncomment and set if you want kibitz to use
26
                                ;# some other account on remote systems
27
 
28
# The following code attempts to intuit whether cat buffers by default.
29
# The -u flag is required on HPUX (8 and 9) and IBM AIX (3.2) systems.
30
if [file exists $exp_exec_library/cat-buffers] {
31
        set catflags "-u"
32
} else {
33
        set catflags ""
34
}
35
# If this fails, you can also force it by commenting in one of the following.
36
# Or, you can use the -catu flag to the script.
37
#set catflags ""
38
#set catflags "-u"
39
 
40
# Some flags must be passed onto the remote kibitz process.  They are stored
41
# in "kibitz_flags".  Currently, they include -tty and -silent.
42
set kibitz_flags ""
43
 
44
while {[llength $argv]>0} {
45
        set flag [lindex $argv 0]
46
        switch -- $flag \
47
        "-noproc" {
48
                set noproc 1
49
                set argv [lrange $argv 1 end]
50
        } "-catu" {
51
                set catflags "-u"
52
                set argv [lrange $argv 1 end]
53
        } "-tty" {
54
                set tty [lindex $argv 1]
55
                set argv [lrange $argv 2 end]
56
                set kibitz_flags "$kibitz_flags -tty $tty"
57
        } "-noescape" {
58
                set allow_escape 0
59
                set argv [lrange $argv 1 end]
60
        } "-escape" {
61
                set escape_char [lindex $argv 1]
62
                set escape_printable $escape_char
63
                set argv [lrange $argv 2 end]
64
        } "-silent" {
65
                set verbose 0
66
                set argv [lrange $argv 1 end]
67
                set kibitz_flags "$kibitz_flags -silent"
68
        } "-proxy" {
69
                set proxy [lindex $argv 1]
70
                set argv [lrange $argv 2 end]
71
        } default {
72
                break
73
        }
74
}
75
 
76
if {([llength $argv]<1) && ($noproc==0)} {
77
        send_user "usage: kibitz \[args] user \[program ...]\n"
78
        send_user "   or: kibitz \[args] user@host \[program ...]\n"
79
        exit
80
}
81
 
82
log_user 0
83
set timeout -1
84
 
85
set user [lindex $argv 0]
86
if [string match -r $user] {
87
        send_user "KRUN"        ;# this tells user_number 1 that we're running
88
                                ;# and to prepare for possible error messages
89
        set user_number 3
90
        # need to check that it exists first!
91
        set user [lindex $argv 1]
92
} else {
93
        set user_number [expr 1+(0==[string first - $user])]
94
}
95
 
96
# at this point, user_number and user are correctly determined
97
# User who originated kibitz session has user_number == 1 on local machine.
98
# User who is responding to kibitz has user_number == 2.
99
# User who originated kibitz session has user_number == 3 on remote machine.
100
 
101
# user 1 invokes kibitz as "kibitz user[@host]"
102
# user 2 invokes kibitz as "kibitz -####" (some pid).
103
# user 3 invokes kibitz as "kibitz -r user".
104
 
105
# uncomment for debugging: leaves each user's session in a file: 1, 2 or 3
106
#exec rm -f $user_number
107
#exp_internal -f $user_number 0
108
 
109
set user2_islocal 1     ;# assume local at first
110
 
111
# later move inside following if $user_number == 1
112
# return true if x is a prefix of xjunk, given that prefixes are only
113
# valid at . delimiters
114
# if !do_if0, skip the whole thing - this is here just to make caller simpler
115
proc is_prefix {do_if0 x xjunk} {
116
        if 0!=$do_if0 {return 0}
117
        set split [split $xjunk .]
118
        for {set i [expr [llength $split]-1]} {$i>=0} {incr i -1} {
119
                if [string match $x [join [lrange $split 0 $i] .]] {return 1}
120
        }
121
        return 0
122
}
123
 
124
# get domainname.  Unfortunately, on some systems, domainname(1)
125
# returns NIS domainname which is not the internet domainname.
126
proc domainname {} {
127
        # open pops stack upon failure
128
        set rc [catch {open /etc/resolv.conf r} file]
129
        if {$rc==0} {
130
                while {-1!=[gets $file buf]} {
131
                        if 1==[scan $buf "domain %s" name] {
132
                                close $file
133
                                return $name
134
                        }
135
                }
136
                close $file
137
        }
138
 
139
        # fall back to using domainname
140
        if {0==[catch {exec domainname} name]} {return $name}
141
 
142
        error "could not figure out domainname"
143
}
144
 
145
if $user_number==1 {
146
        if $noproc==0 {
147
                if [llength $argv]>1 {
148
                        set pid [eval spawn [lrange $argv 1 end]]
149
                } else {
150
                        # if running as CGI, shell may not be set!
151
                        set shell /bin/sh
152
                        catch {set shell $env(SHELL)}
153
                        set pid [spawn $shell]
154
                }
155
                set shell $spawn_id
156
        }
157
 
158
        # is user2 remote?
159
        regexp (\[^@\]*)@*(.*) $user ignore tmp host
160
        set user $tmp
161
        if ![string match $host ""] {
162
                set h_rc [catch {exec hostname} hostname]
163
                set d_rc [catch domainname      domainname]
164
 
165
                if {![is_prefix $h_rc $host $hostname]
166
                 && ![is_prefix $d_rc $host $hostname.$domainname]} {
167
                        set user2_islocal 0
168
                }
169
        }
170
 
171
        if !$user2_islocal {
172
                if $verbose {send_user "connecting to $host\n"}
173
 
174
                if ![info exists proxy] {
175
                        proc whoami {} {
176
                                global env
177
                                if [info exists env(USER)] {return $env(USER)}
178
                                if [info exists env(LOGNAME)] {return $env(LOGNAME)}
179
                                if ![catch {exec whoami} user] {return $user}
180
                                if ![catch {exec logname} user] {return $user}
181
                                # error "can't figure out who you are!"
182
                        }
183
                        set proxy [whoami]
184
                }
185
                spawn rlogin $host -l $proxy -8
186
                set userin $spawn_id
187
                set userout $spawn_id
188
 
189
                catch {set prompt $env(EXPECT_PROMPT)}
190
 
191
                set timeout 120
192
                expect {
193
                        assword: {
194
                                stty -echo
195
                                send_user "password (for $proxy) on $host: "
196
                                set old_timeout $timeout; set timeout -1
197
                                expect_user -re "(.*)\n"
198
                                send_user "\n"
199
                                set timeout $old_timeout
200
                                send "$expect_out(1,string)\r"
201
                                # bother resetting echo?
202
                                exp_continue
203
                        } incorrect* {
204
                                send_user "invalid password or account\n"
205
                                exit
206
                        } "TERM = *) " {
207
                                send "\r"
208
                                exp_continue
209
                        } timeout {
210
                                send_user "connection to $host timed out\n"
211
                                exit
212
                        } eof {
213
                                send_user "connection to host failed: $expect_out(buffer)"
214
                                exit
215
                        } -re $prompt
216
                }
217
                if $verbose {send_user "starting kibitz on $host\n"}
218
                # the kill protects user1 from receiving user3's
219
                # prompt if user2 exits via expect's exit.
220
                send "$kibitz $kibitz_flags -r $user;kill -9 $$\r"
221
 
222
                expect {
223
                        -re "kibitz $kibitz_flags -r $user.*KRUN" {}
224
                        -re "kibitz $kibitz_flags -r $user.*(kibitz\[^\r\]*)\r" {
225
                                send_user "unable to start kibitz on $host: \"$expect_out(1,string)\"\n"
226
                                send_user "try rlogin by hand followed by \"kibitz $user\"\n"
227
                                exit
228
                        }
229
                        timeout {
230
                                send_user "unable to start kibitz on $host: "
231
                                set expect_out(buffer) "timed out"
232
                                set timeout 0; expect -re .+
233
                                send_user $expect_out(buffer)
234
                                exit
235
                        }
236
                }
237
                expect {
238
                        -re ".*\n" {
239
                                # pass back diagnostics
240
                                # should really strip out extra cr
241
                                send_user $expect_out(buffer)
242
                                exp_continue
243
                        }
244
                        KABORT exit
245
                        default exit
246
                        KDATA
247
                }
248
        }
249
}
250
 
251
if $user_number==2 {
252
        set pid [string trimleft $user -]
253
}
254
 
255
set local_io [expr ($user_number==3)||$user2_islocal]
256
if $local_io||($user_number==2) {
257
        if 0==[info exists pid] {set pid [pid]}
258
 
259
        set userinfile /tmp/exp0.$pid
260
        set useroutfile /tmp/exp1.$pid
261
}
262
 
263
proc prompt1 {} {
264
        return "kibitz[info level].[history nextid]> "
265
}
266
 
267
set esc_match {}
268
if {$allow_escape} {
269
   set esc_match {
270
      $escape_char {
271
        send_user "\nto exit kibitz, enter: exit\n"
272
        send_user "to suspend kibitz, press appropriate job control sequence\n"
273
        send_user "to return to kibitzing, enter: return\n"
274
        interpreter
275
        send_user "returning to kibitz\n"
276
      }
277
   }
278
}
279
 
280
proc prompt1 {} {
281
        return "kibitz[info level].[history nextid]> "
282
}
283
 
284
set timeout -1
285
 
286
# kibitzer executes following code
287
if $user_number==2 {
288
        # for readability, swap variables
289
        set tmp $userinfile
290
        set userinfile $useroutfile
291
        set useroutfile $tmp
292
 
293
        if ![file readable $userinfile] {
294
                send_user "Eh?  No one is asking you to kibitz.\n"
295
                exit -1
296
        }
297
        spawn -open [open "|cat $catflags < $userinfile" "r"]
298
        set userin $spawn_id
299
 
300
        spawn -open [open $useroutfile w]
301
        set userout $spawn_id
302
        # open will hang until other user's cat starts
303
 
304
        stty -echo raw
305
        if $allow_escape {send_user "Escape sequence is $escape_printable\r\n"}
306
 
307
        # While user is reading message, try to delete other fifo
308
        catch {exec rm -f $userinfile}
309
 
310
        eval interact $esc_match \
311
                -output $userout \
312
                -input $userin
313
 
314
        exit
315
}
316
 
317
# only user_numbers 1 and 3 execute remaining code
318
 
319
proc abort {} {
320
        global user_number
321
 
322
        # KABORT tells user_number 1 that user_number 3 has run into problems
323
        # and is exiting, and diagnostics have been returned already
324
        if $user_number==3 {send_user KABORT}
325
        exit
326
}
327
 
328
if $local_io {
329
    proc mkfifo {f} {
330
        if 0==[catch {exec mkfifo $f}] return           ;# POSIX
331
        if 0==[catch {exec mknod $f p}] return
332
        # some systems put mknod in wierd places
333
        if 0==[catch {exec /usr/etc/mknod $f p}] return ;# Sun
334
        if 0==[catch {exec /etc/mknod $f p}] return     ;# AIX, Cray
335
        puts "Couldn't figure out how to make a fifo - where is mknod?"
336
        abort
337
    }
338
 
339
    proc rmfifos {} {
340
        global userinfile useroutfile
341
        catch {exec rm -f $userinfile $useroutfile}
342
    }
343
 
344
    trap {rmfifos; exit} {SIGINT SIGQUIT SIGTERM}
345
 
346
    # create 2 fifos to communicate with other user
347
    mkfifo $userinfile
348
    mkfifo $useroutfile
349
    # make sure other user can access despite umask
350
    exec chmod 666 $userinfile $useroutfile
351
 
352
    if $verbose {send_user "asking $user to type:  kibitz -$pid\n"}
353
 
354
    # can't use exec since write insists on being run from a tty!
355
    set rc [catch {
356
                   system echo "Can we talk?  Run: \"kibitz -$pid\"" | \
357
                        /bin/write $user $tty
358
                }
359
        ]
360
    if $rc {rmfifos;abort}
361
 
362
    spawn -open [open $useroutfile w]
363
    set userout $spawn_id
364
    # open will hang until other user's cat starts
365
 
366
    spawn -open [open "|cat $catflags < $userinfile" "r"]
367
    set userin $spawn_id
368
    catch {exec rm $userinfile}
369
}
370
 
371
stty -echo raw
372
 
373
if $user_number==3 {
374
        send_user "KDATA"       ;# this tells user_number 1 to send data
375
 
376
        interact {
377
                -output $userout
378
                -input $userin eof {
379
                        wait -i $userin
380
                        return -tcl
381
                } -output $user_spawn_id
382
        }
383
} else {
384
        if $allow_escape {send_user "Escape sequence is $escape_printable\r\n"}
385
 
386
        if $noproc {
387
                interact {
388
                        -output $userout
389
                        -input $userin eof {wait -i $userin; return}
390
                        -output $user_spawn_id
391
                }
392
        } else {
393
                eval interact $esc_match {
394
                        -output $shell \
395
                        -input $userin eof {
396
                                wait -i $userin
397
                                close -i $shell
398
                                return
399
                        } -output $shell \
400
                        -input $shell -output "$user_spawn_id $userout"
401
                }
402
                wait -i $shell
403
        }
404
}
405
 
406
if $local_io rmfifos

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.