| 1 | #!/usr/bin/env tclsh |
|---|
| 2 | |
|---|
| 3 | ############################################################################### |
|---|
| 4 | # |
|---|
| 5 | # tolsh.tcl -- |
|---|
| 6 | # |
|---|
| 7 | ############################################################################### |
|---|
| 8 | |
|---|
| 9 | package provide tolsh 1.0 |
|---|
| 10 | |
|---|
| 11 | ############################################################################### |
|---|
| 12 | # |
|---|
| 13 | # Tol_HciWriter -- |
|---|
| 14 | # |
|---|
| 15 | # This file will be invoked by TOL if HCI output is enabled |
|---|
| 16 | # |
|---|
| 17 | ############################################################################### |
|---|
| 18 | proc Tol_HciWriter { msg } { |
|---|
| 19 | puts [string trim $msg] |
|---|
| 20 | } |
|---|
| 21 | |
|---|
| 22 | ############################################################################### |
|---|
| 23 | # |
|---|
| 24 | # namespace tolsh -- encapsulate tolsh functionality |
|---|
| 25 | # |
|---|
| 26 | ############################################################################### |
|---|
| 27 | namespace eval ::tolsh { |
|---|
| 28 | variable options |
|---|
| 29 | |
|---|
| 30 | # By default load initLibrary |
|---|
| 31 | # |
|---|
| 32 | set options(lang) "" |
|---|
| 33 | set options(initlib) 1 |
|---|
| 34 | set options(iniproject) 1 |
|---|
| 35 | set options(defaultpackages) 1 |
|---|
| 36 | set options(compile) "" |
|---|
| 37 | set options(vmode) "" |
|---|
| 38 | set options(out,enabled) no |
|---|
| 39 | set options(runmode) "" |
|---|
| 40 | set options(tolversion) "" |
|---|
| 41 | } |
|---|
| 42 | |
|---|
| 43 | ############################################################################### |
|---|
| 44 | # |
|---|
| 45 | # getoptions -- process the command line |
|---|
| 46 | # |
|---|
| 47 | # The command line accepted by tolsh is: |
|---|
| 48 | # |
|---|
| 49 | # -i --> do not include initLibrary |
|---|
| 50 | # -np --> do not load _iniproject.tol |
|---|
| 51 | # -c"..." --> compile a tol expression |
|---|
| 52 | # -c "..." --> compile a tol expression |
|---|
| 53 | # -v?A? --> enable all output |
|---|
| 54 | # -vE --> enable error output |
|---|
| 55 | # -vS --> enable system output |
|---|
| 56 | # -vU --> enable user output |
|---|
| 57 | # -vT --> enable trace output |
|---|
| 58 | # -m?A? --> disable all output |
|---|
| 59 | # -mE --> disable error output |
|---|
| 60 | # -mS --> disable system output |
|---|
| 61 | # -mU --> disable user output |
|---|
| 62 | # -mT --> disable trace output |
|---|
| 63 | # -d --> start in dialog mode |
|---|
| 64 | # -e?n? --> use english language |
|---|
| 65 | # -s?p? --> use spanish language |
|---|
| 66 | # -tolversion ver --> specify an strict tol version to start with |
|---|
| 67 | # -server [port] --> start tol as a server tolsvc.<pid>.log will be the log |
|---|
| 68 | # [port] is the port number where the serve will be listening. |
|---|
| 69 | # |
|---|
| 70 | # Any other value will be considered a file to compile |
|---|
| 71 | # |
|---|
| 72 | # Arguments: |
|---|
| 73 | # |
|---|
| 74 | ############################################################################### |
|---|
| 75 | proc ::tolsh::getoptions { cmdline } { |
|---|
| 76 | variable options |
|---|
| 77 | |
|---|
| 78 | logtmp "entering ::tolsh::getoptions $cmdline" |
|---|
| 79 | |
|---|
| 80 | # cmdline could be a bad list so the next sentence could fail. |
|---|
| 81 | # try to test it in front of bugs situations. |
|---|
| 82 | set num [llength $cmdline] |
|---|
| 83 | set delayed_msg "" |
|---|
| 84 | set i 0 |
|---|
| 85 | while {$i < $num} { |
|---|
| 86 | logtmp "set item [lindex $cmdline $i]" |
|---|
| 87 | set item [lindex $cmdline $i] |
|---|
| 88 | if {[string index $item 0] eq "-"} { |
|---|
| 89 | set opt [string range $item 1 end] |
|---|
| 90 | if {$opt eq "e" || $opt eq "en"} { |
|---|
| 91 | set options(lang) "en" |
|---|
| 92 | } elseif {$opt eq "s" || $opt eq "sp"} { |
|---|
| 93 | set options(lang) "es" |
|---|
| 94 | } elseif {$opt eq "i"} { |
|---|
| 95 | # initLibrary should not be loaded |
|---|
| 96 | # |
|---|
| 97 | set options(initlib) 0 |
|---|
| 98 | } elseif {$opt eq "ndp"} { |
|---|
| 99 | set options(defaultpackages) 0 |
|---|
| 100 | } elseif {$opt eq "np"} { |
|---|
| 101 | set options(iniproject) 0 |
|---|
| 102 | } elseif {[string index $opt 0] eq "c"} { |
|---|
| 103 | if {[string length $opt]>1} { |
|---|
| 104 | # The tol expression is part of the option |
|---|
| 105 | # |
|---|
| 106 | set expr [string range $opt 1 end] |
|---|
| 107 | } else { |
|---|
| 108 | # Next argument is the expression to compile |
|---|
| 109 | # |
|---|
| 110 | incr i |
|---|
| 111 | set expr [lindex $cmdline $i] |
|---|
| 112 | } |
|---|
| 113 | # Put expr in the list of "things" to compile |
|---|
| 114 | # |
|---|
| 115 | lappend options(compile) [list expr $expr] |
|---|
| 116 | } elseif {[string index $opt 0] eq "v"} { |
|---|
| 117 | if {[regexp {^[A|S|U|T|E|W]*$} [string range $opt 1 end] mode]} { |
|---|
| 118 | if {$mode eq ""} { |
|---|
| 119 | set mode A |
|---|
| 120 | } |
|---|
| 121 | if {[regexp {[A|S]} $mode]} { |
|---|
| 122 | set options(out,enabled) yes |
|---|
| 123 | } |
|---|
| 124 | append options(vmode) "v$mode " |
|---|
| 125 | } else { |
|---|
| 126 | append delayed_msg "\nignoring unknown verbose mode: '$opt'" |
|---|
| 127 | } |
|---|
| 128 | } elseif {[string index $opt 0] eq "m"} { |
|---|
| 129 | if {[regexp {^[A|S|U|T|E|W]*$} [string range $opt 1 end] mode]} { |
|---|
| 130 | if {$mode eq ""} { |
|---|
| 131 | set mode A |
|---|
| 132 | } |
|---|
| 133 | if {[regexp {[A|S]} $mode]} { |
|---|
| 134 | set options(out,enabled) no |
|---|
| 135 | } |
|---|
| 136 | append options(vmode) "m$mode " |
|---|
| 137 | } else { |
|---|
| 138 | append delayed_msg "\nignoring unknown mute mode: '$opt'" |
|---|
| 139 | } |
|---|
| 140 | } elseif {$opt eq "d"} { |
|---|
| 141 | if {$options(runmode) ne "" && $options(runmode) ne "interactive"} { |
|---|
| 142 | puts "Replacing previous run mode '$options(runmode)' with 'interactive'" |
|---|
| 143 | } |
|---|
| 144 | set options(runmode) "interactive" |
|---|
| 145 | } elseif {$opt eq "tolversion"} { |
|---|
| 146 | incr i |
|---|
| 147 | set options(tolversion) [lindex $cmdline $i] |
|---|
| 148 | } elseif {$opt eq "server"} { |
|---|
| 149 | # check if next argument is the port number |
|---|
| 150 | set port [lindex $cmdline [expr {$i+1}]] |
|---|
| 151 | if {[string is integer $port]} { |
|---|
| 152 | # $i+1 is an integer, should be considered as a port number |
|---|
| 153 | incr i |
|---|
| 154 | if {$port <= 0} { |
|---|
| 155 | puts "Could not start as a server: invalid port number '${port}'" |
|---|
| 156 | exit |
|---|
| 157 | } |
|---|
| 158 | if {$options(runmode) ne "" && $options(runmode) ne "server"} { |
|---|
| 159 | puts "Replacing previous run mode '$options(runmode)' with 'server'" |
|---|
| 160 | } |
|---|
| 161 | set options(runmode) "server" |
|---|
| 162 | set options(server,port) $port |
|---|
| 163 | } else { |
|---|
| 164 | puts "Could not start as a server: invalid port number '${port}'" |
|---|
| 165 | exit |
|---|
| 166 | } |
|---|
| 167 | } elseif {$opt eq "slave"} { |
|---|
| 168 | # the next argument is the port number |
|---|
| 169 | set options(server,port) [lindex $cmdline [expr {$i+1}]] |
|---|
| 170 | incr i |
|---|
| 171 | if {$options(runmode) ne "" && $options(runmode) ne "slave"} { |
|---|
| 172 | puts "Replacing previous run mode '$options(runmode)' with 'slave'" |
|---|
| 173 | } |
|---|
| 174 | set options(runmode) "slave" |
|---|
| 175 | } elseif {$opt eq "shared"} { |
|---|
| 176 | # the next argument is the port number |
|---|
| 177 | set options(shared,port) [lindex $cmdline [expr {$i+1}]] |
|---|
| 178 | incr i |
|---|
| 179 | if {$options(runmode) ne "" && $options(runmode) ne "shared"} { |
|---|
| 180 | puts "Replacing previous run mode '$options(runmode)' with 'shared'" |
|---|
| 181 | } |
|---|
| 182 | set options(runmode) "shared" |
|---|
| 183 | } elseif {$opt eq "shport"} { |
|---|
| 184 | # the next argument is the port number |
|---|
| 185 | set options(shared,port) [lindex $cmdline [expr {$i+1}]] |
|---|
| 186 | incr i |
|---|
| 187 | } else { |
|---|
| 188 | append delayed_msg "\nignoring unknown option: '$item'" |
|---|
| 189 | } |
|---|
| 190 | } else { |
|---|
| 191 | # Consider this option as a tol file to compile. |
|---|
| 192 | # |
|---|
| 193 | if {![file exists $item] || ![file readable $item]} { |
|---|
| 194 | puts "file $item does not exist or is not readable" |
|---|
| 195 | } else { |
|---|
| 196 | lappend options(compile) [list file $item] |
|---|
| 197 | } |
|---|
| 198 | } |
|---|
| 199 | incr i |
|---|
| 200 | } |
|---|
| 201 | if {$delayed_msg ne ""} { |
|---|
| 202 | std $delayed_msg |
|---|
| 203 | } |
|---|
| 204 | } |
|---|
| 205 | |
|---|
| 206 | ############################################################################### |
|---|
| 207 | # |
|---|
| 208 | # something_to_compile -- tell us if there is something to do |
|---|
| 209 | # |
|---|
| 210 | # Depending on the command line processing some tol expression or |
|---|
| 211 | # files needs to be compiled. All this is stored in options(compile) |
|---|
| 212 | # |
|---|
| 213 | # Return: |
|---|
| 214 | # |
|---|
| 215 | # true value if there is something to compile in $options(compile) |
|---|
| 216 | # false if $options(compile) is empty |
|---|
| 217 | # |
|---|
| 218 | ############################################################################### |
|---|
| 219 | proc ::tolsh::something_to_compile { } { |
|---|
| 220 | variable options |
|---|
| 221 | |
|---|
| 222 | llength $options(compile) |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | ############################################################################### |
|---|
| 226 | # |
|---|
| 227 | # show_usage -- show how to invoke tolsh |
|---|
| 228 | # |
|---|
| 229 | # This proc print into stdout a message that list the valid options accepted. |
|---|
| 230 | # |
|---|
| 231 | ############################################################################### |
|---|
| 232 | proc ::tolsh::show_usage { } { |
|---|
| 233 | puts "[get_app_name] \[options] filename ...\noptions:" |
|---|
| 234 | puts { |
|---|
| 235 | -i file --> include a file but not initLibrary |
|---|
| 236 | -np --> do not load _iniproject.tol |
|---|
| 237 | -c "..." --> compile a tol expression |
|---|
| 238 | -v?A? --> enable all output |
|---|
| 239 | -vE --> enable error output |
|---|
| 240 | -vS --> enable standard output |
|---|
| 241 | -vU --> enable user output |
|---|
| 242 | -vT --> enable trace output |
|---|
| 243 | -m?A? --> disable all output |
|---|
| 244 | -mE --> disable error output |
|---|
| 245 | -mS --> disable standard output |
|---|
| 246 | -mU --> disable user output |
|---|
| 247 | -mT --> disable trace output |
|---|
| 248 | -d --> start in dialog mode |
|---|
| 249 | -e?n? --> use english language |
|---|
| 250 | -s?p? --> use spanish language |
|---|
| 251 | -tolversion --> specify an strict tol version to start with |
|---|
| 252 | -server [port] --> start tol as a server tolsvc.<pid>.log will be the log |
|---|
| 253 | [port] is the port number where the serve will be listening. |
|---|
| 254 | |
|---|
| 255 | Multiple verbose mode is accepted in one option, for instance, |
|---|
| 256 | |
|---|
| 257 | -vUE |
|---|
| 258 | } |
|---|
| 259 | } |
|---|
| 260 | |
|---|
| 261 | ############################################################################### |
|---|
| 262 | # |
|---|
| 263 | # getArgv0 -- return the name of the app |
|---|
| 264 | # |
|---|
| 265 | ############################################################################### |
|---|
| 266 | proc ::tolsh::get_app_name {} { |
|---|
| 267 | global argv0 |
|---|
| 268 | |
|---|
| 269 | set name [file tail $argv0] |
|---|
| 270 | return [file rootname $name] |
|---|
| 271 | } |
|---|
| 272 | |
|---|
| 273 | ############################################################################### |
|---|
| 274 | # |
|---|
| 275 | # append_message -- save a message |
|---|
| 276 | # |
|---|
| 277 | ############################################################################### |
|---|
| 278 | proc ::tolsh::std { msg } { |
|---|
| 279 | variable options |
|---|
| 280 | |
|---|
| 281 | if {$options(out,enabled)} { |
|---|
| 282 | puts $msg |
|---|
| 283 | } |
|---|
| 284 | } |
|---|
| 285 | |
|---|
| 286 | #puts "starkit = [namespace exist ::starkit]" |
|---|
| 287 | #puts "topdir = [file dir $starkit::topdir]" |
|---|
| 288 | #puts "info script = [info script]" |
|---|
| 289 | #puts "starkit::startup = [starkit::startup]" |
|---|
| 290 | #puts "[ info commands starkit::* ]" |
|---|
| 291 | #puts "argv0 = $argv0" |
|---|
| 292 | |
|---|
| 293 | proc ::tolsh::setup_pkg { pkg } { |
|---|
| 294 | #puts ":tolsh::setup_pkg $pkg [namespace exist ::starkit] " |
|---|
| 295 | if {[lsearch [package names] $pkg]==-1} { |
|---|
| 296 | if {[namespace exist ::starkit]} { |
|---|
| 297 | set bindir [file dir $starkit::topdir] |
|---|
| 298 | set libdir [file join $bindir .. lib] |
|---|
| 299 | set pkg_dirs [glob -nocomplain -dir $libdir ${pkg}*] |
|---|
| 300 | if {[llength $pkg_dirs]} { |
|---|
| 301 | lappend ::auto_path [file normalize $libdir] |
|---|
| 302 | } elseif { $::tcl_platform(platform) eq "unix" } { |
|---|
| 303 | set activeTcl "/opt/ActiveTcl-8.4/lib" |
|---|
| 304 | if { [ file exists $activeTcl ] && |
|---|
| 305 | [ lsearch $::auto_path $activeTcl ] == -1 } { |
|---|
| 306 | lappend ::auto_path $activeTcl |
|---|
| 307 | } |
|---|
| 308 | if { [ lsearch $::auto_path "/usr/lib" ] == -1 } { |
|---|
| 309 | lappend ::auto_path "/usr/lib" |
|---|
| 310 | } |
|---|
| 311 | } else { |
|---|
| 312 | set tclsh [auto_execok tclsh] |
|---|
| 313 | if {![catch { |
|---|
| 314 | exec echo puts {$::auto_path} | $tclsh |
|---|
| 315 | } ext_auto_path]} { |
|---|
| 316 | foreach p $ext_auto_path { |
|---|
| 317 | if {[lsearch $::auto_path $p]==-1} { |
|---|
| 318 | lappend ::auto_path $p |
|---|
| 319 | } |
|---|
| 320 | } |
|---|
| 321 | } |
|---|
| 322 | } |
|---|
| 323 | tclPkgUnknown ${pkg}+1 "" |
|---|
| 324 | } else { |
|---|
| 325 | set pkg_dev_dir [file normalize [file join .. $pkg]] |
|---|
| 326 | if {[file exists $pkg_dev_dir] && [file isdir $pkg_dev_dir]} { |
|---|
| 327 | lappend ::auto_path $pkg_dev_dir |
|---|
| 328 | } |
|---|
| 329 | } |
|---|
| 330 | } |
|---|
| 331 | } |
|---|
| 332 | |
|---|
| 333 | ############################################################################### |
|---|
| 334 | # |
|---|
| 335 | # setup_autopath -- |
|---|
| 336 | # |
|---|
| 337 | # Set auto_path in order to find correctly the following packages: |
|---|
| 338 | # |
|---|
| 339 | # - toltcl |
|---|
| 340 | # - rmtps_client |
|---|
| 341 | # |
|---|
| 342 | ############################################################################### |
|---|
| 343 | proc ::tolsh::setup_autopath { } { |
|---|
| 344 | logtmp "entering ::tolsh::setup_autopath" |
|---|
| 345 | |
|---|
| 346 | setup_pkg toltcl |
|---|
| 347 | setup_pkg tolcomm |
|---|
| 348 | setup_pkg tlogger |
|---|
| 349 | setup_pkg tequila |
|---|
| 350 | setup_pkg tequilas |
|---|
| 351 | |
|---|
| 352 | logtmp "auto_path = $::auto_path" |
|---|
| 353 | logtmp "leaving ::tolsh::setup_autopath" |
|---|
| 354 | } |
|---|
| 355 | |
|---|
| 356 | proc GetHomeDir { } { |
|---|
| 357 | global env |
|---|
| 358 | # Check if we're using windows |
|---|
| 359 | if { $::tcl_platform(platform) eq "windows" } { |
|---|
| 360 | package require registry 1.0 |
|---|
| 361 | set key1 {HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders} |
|---|
| 362 | set key2 {Personal} |
|---|
| 363 | set env_home [ registry get $key1 $key2 ] |
|---|
| 364 | if {[string match %USERPROFILE%* $env_home]} { |
|---|
| 365 | set env_home [string replace $env_home 0 12 $env(USERPROFILE)] |
|---|
| 366 | } |
|---|
| 367 | } else { |
|---|
| 368 | set env_home $env(HOME) |
|---|
| 369 | } |
|---|
| 370 | return $env_home |
|---|
| 371 | } |
|---|
| 372 | |
|---|
| 373 | ############################################################################### |
|---|
| 374 | # |
|---|
| 375 | # main -- entry point for tolsh application |
|---|
| 376 | # |
|---|
| 377 | ############################################################################### |
|---|
| 378 | proc ::tolsh::run { cmdline } { |
|---|
| 379 | variable options |
|---|
| 380 | |
|---|
| 381 | #logtmp "user : [ exec whoami ]" |
|---|
| 382 | logtmp "entering run with cmdline = $cmdline" |
|---|
| 383 | # Process command line options |
|---|
| 384 | # |
|---|
| 385 | getoptions $cmdline |
|---|
| 386 | logtmp "options(compile): $options(compile)" |
|---|
| 387 | logtmp "options(runmode): $options(runmode)" |
|---|
| 388 | if {![something_to_compile] && ($options(runmode) eq "")} { |
|---|
| 389 | show_usage |
|---|
| 390 | return |
|---|
| 391 | } |
|---|
| 392 | |
|---|
| 393 | logtmp "pase getoptions" |
|---|
| 394 | |
|---|
| 395 | # Ensure Toltcl is found |
|---|
| 396 | # |
|---|
| 397 | setup_autopath |
|---|
| 398 | |
|---|
| 399 | # Load Toltcl (+tol) and initLibrary if required |
|---|
| 400 | # |
|---|
| 401 | if {$options(runmode) != "server" && $options(runmode) != "shared"} { |
|---|
| 402 | package require -exact Toltcl 3.3 |
|---|
| 403 | #puts "tol::initkernel $options(lang) $options(vmode)" |
|---|
| 404 | tol::initkernel $options(lang) $options(vmode) |
|---|
| 405 | |
|---|
| 406 | if {$options(initlib)} { |
|---|
| 407 | tol::initlibrary -initproject $options(iniproject) \ |
|---|
| 408 | -defaultpackages $options(defaultpackages) |
|---|
| 409 | } |
|---|
| 410 | # why should I do that? |
|---|
| 411 | if { $options(lang) ne "" } { |
|---|
| 412 | ::tol::language $options(lang) |
|---|
| 413 | } |
|---|
| 414 | set appdata [string trim \ |
|---|
| 415 | [lindex [::tol::info var [list Text TolAppDataPath]] 2] \"] |
|---|
| 416 | logtmp "appdata = $appdata" |
|---|
| 417 | } |
|---|
| 418 | |
|---|
| 419 | set tolcomm_dir [file join [GetHomeDir] ".tol" "tolcomm"] |
|---|
| 420 | file mkdir $tolcomm_dir |
|---|
| 421 | |
|---|
| 422 | # load rmtps_client and tolclient if required |
|---|
| 423 | # |
|---|
| 424 | if {$options(runmode) != "server" && $options(runmode) != "shared"} { |
|---|
| 425 | |
|---|
| 426 | if {[catch {package require rmtps_client} msg]} { |
|---|
| 427 | std "could not load rmtps_client: $msg" |
|---|
| 428 | } else { |
|---|
| 429 | ::rmtps_client::init [file join $tolcomm_dir "rmtps_client.log"] |
|---|
| 430 | if {[catch rmtps_client::define_TOLAPI msg]} { |
|---|
| 431 | std "could not load tol code for rmtps_client: $msg" |
|---|
| 432 | } |
|---|
| 433 | } |
|---|
| 434 | |
|---|
| 435 | if {[catch {package require tolclient} msg]} { |
|---|
| 436 | std "could not load tolclient: $msg" |
|---|
| 437 | } else { |
|---|
| 438 | ::tolclient::init [file join $tolcomm_dir "tolclient.log"] |
|---|
| 439 | if {[catch ::tolclient::define_TOLAPI msg]} { |
|---|
| 440 | std "could not load tol code for rmtps_client: $msg" |
|---|
| 441 | } |
|---|
| 442 | } |
|---|
| 443 | |
|---|
| 444 | } |
|---|
| 445 | |
|---|
| 446 | # Compile expression and tol file provided in the command line if required |
|---|
| 447 | # |
|---|
| 448 | if {$options(runmode) != "server" && $options(runmode) != "shared" \ |
|---|
| 449 | && $options(runmode) != "slave" } { |
|---|
| 450 | |
|---|
| 451 | foreach item $options(compile) { |
|---|
| 452 | if {[lindex $item 0] eq "expr"} { |
|---|
| 453 | tol::console eval [lindex $item 1] |
|---|
| 454 | } elseif {[lindex $item 0] eq "file"} { |
|---|
| 455 | tol::include [lindex $item 1] |
|---|
| 456 | } |
|---|
| 457 | } |
|---|
| 458 | |
|---|
| 459 | } |
|---|
| 460 | |
|---|
| 461 | if {$options(runmode) eq "interactive"} { |
|---|
| 462 | # assign our event handler for stdin |
|---|
| 463 | fileevent stdin readable ::tolsh::stdin_handler |
|---|
| 464 | # send a startup message and initial prompt |
|---|
| 465 | puts stdout "TOL interactive shell activated..." |
|---|
| 466 | console_prompt |
|---|
| 467 | # enter the tcl event loop |
|---|
| 468 | vwait __forever__ |
|---|
| 469 | |
|---|
| 470 | } elseif {$options(runmode) eq "server"} { |
|---|
| 471 | #puts "runmode=server" |
|---|
| 472 | run_as_server $tolcomm_dir |
|---|
| 473 | |
|---|
| 474 | } elseif {$options(runmode) eq "shared"} { |
|---|
| 475 | #puts "runmode=shared" |
|---|
| 476 | run_as_shared $tolcomm_dir |
|---|
| 477 | |
|---|
| 478 | } elseif {$options(runmode) eq "slave"} { |
|---|
| 479 | #puts "runmode=slave" |
|---|
| 480 | run_as_slave $tolcomm_dir |
|---|
| 481 | } |
|---|
| 482 | } |
|---|
| 483 | |
|---|
| 484 | proc ::tolsh::run_as_server {tolcomm_dir} { |
|---|
| 485 | variable options |
|---|
| 486 | package require tolserver |
|---|
| 487 | |
|---|
| 488 | set shared_port [ clone ] |
|---|
| 489 | tolserver::start -port $options(server,port) \ |
|---|
| 490 | -shport $shared_port \ |
|---|
| 491 | -logfile [file join $tolcomm_dir "tolserver.log"] \ |
|---|
| 492 | -compile $options(compile) |
|---|
| 493 | vwait __forever__ |
|---|
| 494 | } |
|---|
| 495 | |
|---|
| 496 | proc ::tolsh::find_shared_port { port } { |
|---|
| 497 | puts "::tolsh::find_shared_port $port" |
|---|
| 498 | set i 0 |
|---|
| 499 | while { $i < 100 } { |
|---|
| 500 | if { [ catch { socket localhost $port } fd ] } { |
|---|
| 501 | puts "find_shared_port OK = $port" |
|---|
| 502 | return $port |
|---|
| 503 | } |
|---|
| 504 | incr port |
|---|
| 505 | incr i |
|---|
| 506 | } |
|---|
| 507 | puts "find_shared_port FAIL!" |
|---|
| 508 | return 0 |
|---|
| 509 | } |
|---|
| 510 | |
|---|
| 511 | proc ::tolsh::clone {} { |
|---|
| 512 | variable options |
|---|
| 513 | |
|---|
| 514 | puts "::tolsh::clone" |
|---|
| 515 | set tolsh [list [info nameofexecutable] ] |
|---|
| 516 | if { $starkit::tolsh_mode ne "starpack" } { |
|---|
| 517 | lappend tolsh $::argv0 |
|---|
| 518 | } |
|---|
| 519 | set shared_port [ find_shared_port 20458 ] |
|---|
| 520 | if { !$shared_port } { |
|---|
| 521 | puts "::tolsh::clone: could not find a valid port for shared data" |
|---|
| 522 | exit |
|---|
| 523 | } |
|---|
| 524 | eval exec $tolsh -shared $shared_port & |
|---|
| 525 | after 5000 ;# wait for data sharing are created by 'shared' |
|---|
| 526 | puts "exec slave" |
|---|
| 527 | eval exec $tolsh -slave $options(server,port) -shport $shared_port & |
|---|
| 528 | return $shared_port |
|---|
| 529 | } |
|---|
| 530 | |
|---|
| 531 | proc ::tolsh::run_as_shared { tolcomm_dir } { |
|---|
| 532 | package require tolshared |
|---|
| 533 | variable options |
|---|
| 534 | |
|---|
| 535 | tolshared::start $options(shared,port) $tolcomm_dir |
|---|
| 536 | } |
|---|
| 537 | |
|---|
| 538 | proc ::tolsh::run_as_slave { tolcomm_dir } { |
|---|
| 539 | variable options |
|---|
| 540 | package require tolslave |
|---|
| 541 | |
|---|
| 542 | tolslave::start -port $options(server,port) -shport $options(shared,port) \ |
|---|
| 543 | -logfile [file join $tolcomm_dir "tolslave.log"] |
|---|
| 544 | vwait __forever__ |
|---|
| 545 | } |
|---|
| 546 | |
|---|
| 547 | proc ::tolsh::console_cmd { cmd } { |
|---|
| 548 | if {$cmd eq "END" || $cmd eq "QUIT" || $cmd eq "EXIT"} { |
|---|
| 549 | exit |
|---|
| 550 | } else { |
|---|
| 551 | puts stdout "unknown console command: '$cmd'" |
|---|
| 552 | } |
|---|
| 553 | } |
|---|
| 554 | |
|---|
| 555 | proc ::tolsh::console_eval { tol_stms } { |
|---|
| 556 | set con_objs0 [tol::console stack list] |
|---|
| 557 | tol::console eval $tol_stms |
|---|
| 558 | set con_objs1 [tol::console stack list] |
|---|
| 559 | if {[llength $con_objs1]>[llength $con_objs0]} { |
|---|
| 560 | puts stdout [lindex [lindex $con_objs1 end] 2] |
|---|
| 561 | } |
|---|
| 562 | } |
|---|
| 563 | |
|---|
| 564 | proc ::tolsh::console_prompt {} { |
|---|
| 565 | puts -nonewline stdout \ |
|---|
| 566 | "[clock format [clock seconds] -format %H:%M:%S] TOL> " |
|---|
| 567 | flush stdout |
|---|
| 568 | } |
|---|
| 569 | |
|---|
| 570 | proc ::tolsh::stdin_handler {} { |
|---|
| 571 | # get the data from stdin |
|---|
| 572 | # |
|---|
| 573 | gets stdin data |
|---|
| 574 | if {[string index $data 0] eq "\\"} { |
|---|
| 575 | console_cmd [string toupper [string range $data 1 end]] |
|---|
| 576 | } else { |
|---|
| 577 | console_eval $data |
|---|
| 578 | } |
|---|
| 579 | # return a new pseudo-prompt |
|---|
| 580 | console_prompt |
|---|
| 581 | return |
|---|
| 582 | } |
|---|
| 583 | |
|---|
| 584 | proc logtmp { msg } { |
|---|
| 585 | return |
|---|
| 586 | set user $::tcl_platform(user) |
|---|
| 587 | set fd [ open "/tmp/tolsh.${user}.log" a ] |
|---|
| 588 | puts $fd $msg |
|---|
| 589 | flush $fd |
|---|
| 590 | close $fd |
|---|
| 591 | } |
|---|
| 592 | |
|---|
| 593 | ::tolsh::run $argv |
|---|