home *** CD-ROM | disk | FTP | other *** search
- # These proc definitions are preloaded by the MESH program
-
- # 1-21-93 weber@eitech.com added define-pattern and support in
- # invoke-service for pattern matching
-
-
- # the next three procs implement "assoc" lists for tcl; these are very
- # handy for examining service inputs and composing service outputs.
- # Yes, I know about the keylists in extended tcl, but I didn't like them
- #
- proc delfield {structname field} {
- if {[catch "upvar $structname struct"]} {return}
- set i [expr [llength $struct]-1]
- while {$i>1} {
- incr i -2
- if {[lindex $struct $i] == $field} {
- set struct [lreplace $struct $i [expr $i+1]]
- }
- }
- }
-
- proc setfield {structname field value} {
- upvar $structname struct
- lappend struct $field $value
- }
-
- proc getfield {struct field} {
- set i [llength $struct]
- while {$i>1} {
- incr i -2
- if {[lindex $struct $i] == $field} {
- return [lindex $struct [expr $i+1]]
- }
- }
- return {}
- }
-
- # The following proc is used by the services.tcl file to define
- # available services
- proc define-service {extname intname sfile} {
- global executor srcfile
- set executor($extname) $intname
- set srcfile($extname) $sfile
- }
-
- proc define-pattern {extname pattern} {
- global pats
- lappend pats [list $extname $pattern]
- }
-
- # This is the Tcl proc that called by the mesh code to invoke a service.
- # It handles error conditions like no-such-service, an incorrect
- # installation of implementations, or errors during service execution
- #
- proc invoke-service {extname switches envelope inputs} {
- global executor hmph servlog administrator errorInfo pats srcfile
-
- # if a log file is defined, log this request
- #
- if {[info exists servlog] && [catch {set fid [open $servlog a]}] == 0} {
- puts $fid $extname
- puts $fid $switches
- puts $fid $envelope
- puts $fid $inputs
- puts $fid ""
- close $fid
- }
-
- # check for matching patterns first
- #
- if {[info exists pats]} {
- foreach pat $pats {
- if [lindex $pat 1] {
- set extname [lindex $pat 0]
- break
- }
- }
- }
- # now try to execute service
- #
- if {![info exists executor($extname)]} {
- set servlist [array names executor]
- regsub -all " " $servlist "\n" servlist
- setfield response STRING \
- "Sorry, this server does not have a $extname service.
-
- Services are normally invoked by specifying their name as the first
- word in the subject line, followed by any necessary arguments.
-
- Currently available services:
-
- $servlist"
- return [mailout [turnaround $envelope] $response]
- }
- if {[catch "uplevel #0 {source $srcfile($extname)}" errstr] ||
- [catch "$executor($extname) [list $switches] [list $envelope] [list $inputs]" errstr]} {
- if {[info exists administrator]} {
- setfield response STRING \
- "The '$extname' service encountered an error on the following request:
-
- $envelope
-
- Here is a stacktrace of the problem:
-
- $errorInfo"
- setfield outenv TO $administrator
- setfield outenv SUBJECT "A ServiceMail bug"
- mailout $outenv $response
- setfield response STRING \
- "Sorry, the '$extname' service encountered a problem.
- A bug report has been automatically sent to our ServiceMail
- administrator."
- } {
- setfield response STRING \
- "Sorry, the '$extname' service encountered a problem. Please contact
- our ServiceMail administrator and report the error with the following
- stacktrace:
- $errorInfo"
- }
- set outenv [turnaround $envelope]
- return [mailout $outenv $response]
- }
- }
-
- # This proc is used to construct outgoing envelopes from incoming
- # envelopes
- proc turnaround {inenvelope} {
- set i 0
- set outenvelope {}
- while {[set f [lindex $inenvelope $i]] != ""} {
- incr i
- case $f {
- REPLYTO { setfield outenvelope TO [lindex $inenvelope $i] }
- MESSAGEID { setfield outenvelope INREPLYTO [lindex $inenvelope $i] }
- SERVICE { setfield outenvelope SUBJECT "Re: [lindex $inenvelope $i]" }
- CC { setfield outenvelope CC [lindex $inenvelope $i] }
- SPLITSIZE { setfield outenvelope SPLITSIZE [lindex $inenvelope $i] }
- }
- incr i
- }
- return $outenvelope
- }
-
- # This proc implements a crude form of security by checking the FROM
- # address to see if its local
- proc local from {
- return [regexp {^[^%@!]*$} $from]
- }
-