Add support for external html docs
[maxima.git] / interfaces / xmaxima / Tkmaxima / Tryembed.tcl
blob6993e89da0a595f66f62f59a4290b9966676eaaa
1 ############################################################
2 # Tryembed.tcl #
3 # Copyright (C) 1998 William F. Schelter #
4 # For distribution under GNU public License. See COPYING. #
5 # #
6 # Time-stamp: "2024-03-25 21:13:36 villate" #
7 ############################################################
9 ## the following worked to have an entry box that spoke...
10 # % safe::interpCreate jack
11 # jack
12 # % set slave jack
13 # jack
14 # % safe::interpInit $slave
15 # jack
16 # % interp eval $slave set env(DISPLAY) $env(DISPLAY)
17 # :0.0
18 # % load {} Tk $slave
19 # % interp eval jack {entry .ja ; pack .ja}
20 # % interp eval $slave { proc policy {args } {} }
21 # % Safesock_PolicyInit $slave
22 # % setupUnknown $slave
23 # % setupPrintVariables $slave
24 # % interp eval jack plot2d -xfun {sin(x)}
26 proc makeEmbedWin { parent width height } {
27 global maxima_priv env auto_index
28 set win $parent.embed[incr maxima_priv(counter)]
29 set fr [frame $win -width $width -height $height -container 1]
30 set slave tclet$maxima_priv(counter)
31 safe::interpCreate $slave
32 # make it exist somehow the autoload stuff doesn't make it a command
33 if { [info exists auto_index(::safe::allowTk) ] } {
34 ::safe::allowTk $slave [list -use [winfo id $fr]]
35 ::safe::TkInit $slave
36 ::safe::tkInterpInit $slave [list -use [winfo id $fr]]
37 interp eval $slave [list set argv [list -use [winfo id $fr]]]
38 } else {
39 safe::interpInit $slave
40 interp eval $slave [list set argv [list -use [winfo id $fr]]]
43 if { [info exists env(DISPLAY)] } {
44 interp eval $slave set env(DISPLAY) $env(DISPLAY)
46 interp eval $slave { proc policy {args } {} }
47 # $slave alias bgerror bgerror
48 load {} Tk $slave
49 Safesock_PolicyInit $slave
50 setupUnknown $slave
51 setupPrintVariables $slave
52 oset $fr slave $slave
53 return $fr
56 proc setupUnknown { slave } {
57 interp eval $slave {rename auto_load auto_load-orig}
58 interp alias $slave auto_load1 {} auto_load1 $slave
59 interp eval $slave { proc auto_load {args} {
60 if { [eval auto_load1 $args] } { return 1 }
61 uplevel 1 auto_load-orig $args
66 proc auto_load1 { slave name {namespace ""} } {
67 if { "[info proc $name ]" != "" } {
68 set arglist [info args $name]
69 set theargs {}
70 foreach v $arglist {
71 if { [info default $name $v theDefault] } {
72 lappend theargs [list $v $theDefault]
73 } else {
74 lappend theargs $v
77 interp eval $slave [list proc $name $theargs [info body $name]]
78 return 1
80 return 0
83 proc setupPrintVariables { slave } {
84 global printOption fontSize show_balloons getOp parse_table Parser \
85 axisGray plot2dOptions plot3dOptions paperSizes printOptions \
86 doExit fontCourier8 plotdfOptions maxima_priv
87 foreach v {printOption fontSize show_balloons getOp parse_table Parser
88 axisGray plot2dOptions plot3dOptions paperSizes printOptions
89 doExit fontCourier8 plotdfOptions maxima_priv} {
90 if { [array exists $v] } {
91 interp eval $slave [list array set $v [array get $v *] ]
92 } else {interp eval $slave [list set $v [set $v ]]}}}
94 if { "[info command policy]" != "policy" } {proc policy { args } { }}
96 ## source nsafesock.tcl
98 ###### nsafesock.tcl ######
99 # The Safesock Security Policy.
100 # -----------------------------
102 # Author: Jacob Levy & Brent Welch, 3/10/97
104 # This policy allows a safe slave to connect to remote sockets under the
105 # control of a master. The URL from which the applet is classified as
106 # either "inside" or "outside" and the host is added to the set of "inside"
107 # and "outside" hosts that this Tclet is allowed to connect to. Then, on
108 # the first request to connect to a host, if the host is classified as
109 # "inside" then subsequently the Tclet is allowed to connect only to hosts
110 # that are classified as "inside" (the same for if the first attempt is to
111 # connect to a host classified as "outside").
113 # The arrays used to drive this policy are defined in safesock.data.
115 # Remember the location of the data file for the Safesock policy, so that
116 # it can be reloaded each time the policy is used, to reflect changes.
118 global safesockDataFile
119 set safesockDataFile [file join [file dirname [info script]] safesock.data]
121 proc Safesock_PolicyInit {slave {version 1.0}} {
122 global browser_state ;# Browser state
123 global safesock_inside safesock_outside
125 interp alias $slave socket {} SafesockSocketAlias $slave
126 interp alias $slave fconfigure {} SafesockFconfigureAlias $slave
128 uplevel "#0" {source $safesockDataFile}
131 # Attempt to get the URL and extract the server and port portions:
133 set server "" ; set port "" ; set url ""
134 catch {set url $browser_state($slave,url)}
135 if {[regexp -nocase {http://([^:/]+)(:([0-9]+))?/} $url \
136 x server y port]} {
137 if {[string length $port] == 0} {
138 set port 80
140 set server [string tolower $server]
141 } elseif {[string match "file:*" $url]} {
142 set server localhost
143 set port 80
146 # At this time it is unknown whether the slave will use inside
147 # or outside connections:
149 set browser_state($slave,safesock,permissions) unknown
151 # Save the homebase for this Tclet:
152 set browser_state($slave,safesock,homebase) $server
154 # Tell the slave about itself:
155 interp eval $slave [list set env(SERVER) $server]
156 interp eval $slave [list set env(PORT) $port]
157 interp eval $slave [list set env(URL) $url]
159 browser_log $slave security installed policy Safesock
162 proc SafesockDecideInsideOrOutside {slave server} {
163 global safesock_insideExclude safesock_outsideExclude
164 global safesock_inside safesock_outside
166 set status unknown
168 # If the server matches anything outside and nothing in the outside
169 # exclusion list, then it's outside:
171 foreach i [array names safesock_outside] {
172 if {[string match $i $server]} {
173 set status outside
174 break
178 if {"$status" == "outside"} {
179 foreach i [array names safesock_outsideExclude] {
180 if {[string match $i $server]} {
181 set status unknown
182 break
187 # If the status is unknown, check whether it might be inside. It is
188 # inside if the server matches anything inside and nothing in the
189 # inside exclusion list:
191 if {"$status" == "unknown"} {
192 foreach i [array names safesock_inside] {
193 if {[string match $i $server]} {
194 set status inside
195 break
199 if {"$status" == "inside"} {
200 foreach i [array names safesock_insideExclude] {
201 if {[string match $i $server]} {
202 set status unknown
203 break
209 # If the status is unknown at this point, raise an error
211 if {"$status" == "unknown"} {
212 error [concat [mc "unknown host:"] "$server"]
215 return $status
218 # This procedure is invoked when the slave is destroyed to clean up
219 # any associated state. It frees up the array of hosts and ports that
220 # the slave is allowed to connect to:
222 proc Safesock_PolicyCleanup {slave} {
223 global browser_state
225 foreach i [array names browser_state $slave,safesock,*] {
226 unset browser_state($i)
232 #-----------------------------------------------------------------
234 # SafesockServerAnswer -- will replace COMMAND in a `socket -server command'
235 # request. Checks if the incoming connection is allowed and if so
236 # invokes the original command. Allowed is based on the same criteria
237 # as the outgoing connection.
239 # Results: none
241 # Side Effects: if connect is allowed, transfer the socket to the slave
242 # and eval the original command there.
244 #----------------------------------------------------------------
246 proc SafesockServerAnswer { slave command sock host port } {
247 set peer [fconfigure $sock -peername]
248 set host [lindex $peer 1]
249 set host [string tolower $host]
250 if { [SafesockAllow $slave $host [lindex $peer 2]] > 0 } {
251 interp transfer {} $sock $slave
252 interp eval $slave $command $sock $host $port
253 } else {
254 interp eval $slave [list error [mc "connection from %s and %s disallowed" $host $port] ]
261 #-----------------------------------------------------------------
263 # SafesockAllow -- check if connection by SLAVE to HOST at PORT is allowed,
264 # based on the inside/outside history of slave and data in safesock.data
266 # Results: 1 if succeeds and 0 if it fails to allow
268 # Side Effects: set GOOD to ok port in the caller
270 #----------------------------------------------------------------
272 proc SafesockAllow { slave host port} {
273 global browser_state
274 global safesock_insideExclude safesock_outsideExclude
275 global safesock_inside safesock_outside
276 upvar 1 good good
277 set host [string tolower $host]
278 if {"$browser_state($slave,safesock,permissions)" == "unknown"} {
279 if {[catch {set this [SafesockDecideInsideOrOutside $slave $host]}]} {
280 if {"$host" == "$browser_state($slave,safesock,homebase)"} {
281 set this homebase
282 } else {
283 error [concat [mc "unknown host:"] "$host"]
286 set browser_state($slave,safesock,permissions) $this
287 browser_log $slave security $slave classified as $this
290 set portset -
291 if {"$browser_state($slave,safesock,permissions)" == "homebase"} {
292 if {"$host" == "$browser_state($slave,safesock,homebase)"} {
293 set portset $browser_state($slave,safesock,homeport)
295 } elseif {"$browser_state($slave,safesock,permissions)" == "inside"} {
296 foreach hostpat [array names safesock_inside] {
297 if {[string match $hostpat $host]} {
298 set portset $safesock_inside($hostpat)
299 break
302 if {"$portset" != "-"} {
303 foreach hostpat [array names safesock_insideExclude] {
304 if {[string match $hostpat $host]} {
305 set portset -
306 break
310 } else {
311 foreach hostpat [array names safesock_outside] {
312 if {[string match $hostpat $host]} {
313 set portset $safesock_outside($hostpat)
314 break
317 if {"$portset" != "-"} {
318 foreach hostpat [array names safesock_outsideExclude] {
319 if {[string match $hostpat $host]} {
320 set portset -
321 break
327 if {"$portset" == "-"} {
328 error [concat [mc "unknown host:"] "$host"]
331 if { [safesockPortMatches $port $portset] } {
332 set good $port
333 return 1
335 return 0
338 proc safesockPortMatches { port portset } {
339 foreach portspec $portset {
340 set low [set high ""]
341 if {[regexp {^([0-9]+)-([0-9]*)$} $portspec x low high]} {
342 if {($low <= $port && $high == "") ||
343 ($low <= $port && $high >= $port)} {
344 return 1
345 break
347 } elseif {$port == $portspec} {
348 return 1
351 return 0
354 # the following should be set in safesock.data
355 global safesockAllowedServerPorts
356 if { ![info exists safesockAllowedServerPorts ] } {
357 set safesockAllowedServerPorts { 1025-3000 }
360 proc SafesockSocketAlias {slave host port args} {
361 global safesockAllowedServerPorts
362 set option {}
363 if { "$host" == "-server" } {
364 set command $port
365 set port [lindex $args 0]
366 if { ![safesockPortMatches $port $safesockAllowedServerPorts] } {
367 error [concat [mc "bad port:"] "$port"]
369 set sock [socket -server \
370 "SafesockServerAnswer $slave [list $command]" $port]
371 interp transfer {} $sock $slave
372 browser_log $slave normal socket -server $port
373 return $sock
374 } elseif { "$host" == "-async" } {
375 set option $host
376 set host $port
377 set port [lindex $args 0]
378 } else {
379 if { [llength $args ] != 0 } {
380 error [mc "wrong args: socket host port OR socket -server command port"]
382 set serverCommand ""
384 SafesockAllow $slave $host $port
385 if [info exists good] {
386 if { "$option" != "" } {
387 set sock [interp invokehidden $slave socket $option $host $good]
388 } else {
389 set sock [interp invokehidden $slave socket $host $good]
391 browser_log $slave normal socket $host $port
392 return $sock
394 error [concat [mc "bad port:"] "$port"]
397 # This procedure handles the "fconfigure" alias from the slave:
399 proc SafesockFconfigureAlias {slave sock args} {
400 global jack
401 if {[llength $args] == 0} {
402 return [interp invokehidden $slave fconfigure $sock]
403 } elseif {[llength $args] == 1} {
404 set flag [lindex $args 0]
405 return [interp invokehidden $slave fconfigure $sock $flag]
406 } else {
407 browser_log $slave normal fconfigure $sock $args
409 array set config [interp invokehidden $slave fconfigure $sock]
410 foreach {flag value} $args {
411 switch -- $flag {
412 -peername -
413 -peerport {
414 error [concat [mc "Cannot change"] "$flag configuration"]]
416 -blocking -
417 -buffering -
418 -buffersize -
419 -eofchar -
420 -translation {
421 set config($flag) $value
423 default {
424 error [concat [mc "unknown option"] "$flag"]
428 lappend jack [list interp invokehidden $slave fconfigure $sock \
429 -blocking $config(-blocking) \
430 -buffering $config(-buffering) \
431 -buffersize $config(-buffersize) \
432 -eofchar $config(-eofchar) \
433 -translation $config(-translation)]
434 return [interp invokehidden $slave fconfigure $sock \
435 -blocking $config(-blocking) \
436 -buffering $config(-buffering) \
437 -buffersize $config(-buffersize) \
438 -eofchar $config(-eofchar) \
439 -translation $config(-translation)]
443 ## endsource nsafesock.tcl
446 ## endsource tryembed.tcl