personal.tcl

Go to the documentation of this file.
00001 /* ! /bin/sh*/
00002 /*  -*- tcl -*- \*/
00003 exec tclsh "$0" ${1+"$@"}
00004 
00005 /*  personal.tcl - process personal mail*/
00006 /* */
00007 /*  (c) 1999 Marshall T. Rose*/
00008 /*  Hold harmless the author, and any lawful use is allowed.*/
00009 /* */
00010 /*  The original version was written in 1994!*/
00011 /* */
00012 
00013 package require Tcl 8.3
00014 
00015 global options
00016 
00017 
00018 /*  begin of routines that may be redefined in configFile*/
00019 
00020 ret  impersonalMail (type originator) {}
00021 
00022 ret  adminP (type local , type domain) {
00023     set local [string tolower $local]
00024 
00025     foreach lhs [list administrator       \
00026                       archive-server      \
00027                       daemon              \
00028                       failrepter          \
00029                       faxmaster           \
00030                       gateway             \
00031                       listmaster          \
00032                       listproc            \
00033                       lotus_mail_exchange \
00034                       m400                \
00035                       *mailer*            \
00036                       *maiser*            \
00037                       mmdf                \
00038                       mrgate              \
00039                       mx-mailer-daemon    \
00040                       numbers-info-forw   \
00041                       postman*            \
00042                       *postmast*          \
00043                       pp                  \
00044                       smtp                \
00045                       sysadmin            \
00046                       ucx_smtp            \
00047                       uucp] {
00048         if {[string match $lhs $local]} {
00049             return 1
00050         }
00051     }
00052 
00053     return 0
00054 }
00055 
00056 ret  friendP (type local , type domain) {
00057     global options
00058 
00059     if {![info exists options(friendlyDomains)]} {
00060         return 0
00061     }
00062 
00063     set domain [string tolower $domain]
00064 
00065     foreach rhs $options(friendlyDomains) {
00066         if {(![string compare $rhs $domain]) \
00067                 || ([string match *.$rhs $domain])} {
00068             return 1
00069         }
00070     }
00071 
00072     return 0
00073 }
00074 
00075 ret  ownerP (type local , type domain) {
00076     global options
00077 
00078     foreach mailbox {myMailbox pdaMailboxes remoteMailboxes} {
00079         if {![info exists options($mailbox)]} {
00080             continue
00081         }
00082 
00083         foreach addr [mime::parseaddress $options($mailbox)] {
00084             catch { unset aprops }
00085 
00086             array set aprops $addr
00087             if {![string compare [string tolower $local@$domain] \
00088                          [string tolower $aprops(local)@$aprops(domain)]]} {
00089                 return 1
00090             }
00091         }
00092     }
00093 
00094     return 0
00095 }
00096 
00097 /*  the algorithm below is for systems that use the MMDF/MH convention*/
00098 
00099 ret  saveMessage (type inF , optional outF ="") {
00100     global errorCode errorInfo
00101     global options
00102 
00103     set inC [open $inF { RDONLY }]
00104 
00105     if {![string compare $outF ""]} {
00106         set outF $options(defaultMaildrop)
00107     }
00108     mutl::exclfile [set lockF $outF.lock]
00109 
00110     set code [catch { set outC [open $outF { WRONLY CREAT APPEND }] } result]
00111     set ecode $errorCode
00112     set einfo $errorInfo
00113 
00114     if {!$code} {
00115         set code [catch {
00116             puts $outC [set boundary "\001\001\001\001"]
00117             puts $outC "Delivery-Date: [mime::parsedatetime -now proper]"
00118 
00119             while {[gets $inC line] >= 0} {
00120                 if {[string compare $boundary $line]} {
00121                     puts $outC $line
00122                 } else {
00123                     puts $outC "\002\001\001\001"
00124                 }
00125             }
00126 
00127             puts $outC $boundary
00128         } result]
00129         set ecode $errorCode
00130         set einfo $errorInfo
00131 
00132         if {[catch { close $outC } result2]} {
00133             tclLog $result2
00134         }
00135     }
00136 
00137     file delete -- $lockF
00138 
00139     if {[catch { close $inC } result2]} {
00140         tclLog $result2
00141     }
00142 
00143     return -code $code -errorinfo $einfo -errorcode $ecode $result
00144 }
00145 
00146 ret  findPhrase (type subject) {
00147     global options
00148 
00149     set subject [string toupper $subject]
00150 
00151     foreach file [glob -nocomplain [file join $options(dataDirectory) \
00152                                          phrases *]] {
00153         if {[catch { otp_words -mode encode \
00154                               [base64 -mode decode -- \
00155                                       [join [split [file tail $file] _] /]] } \
00156                     phrase]} {
00157             tclLog "$file: $phrase"
00158         } elseif {[string first $phrase $subject] >= 0} {
00159             if {[catch { file delete -- $file } result]} {
00160                 tclLog $result
00161             }
00162 
00163             return 1
00164         }
00165     }
00166 
00167     return 0
00168 }
00169 
00170 ret  makePhrase () {
00171     global options
00172 
00173     if {![file isdirectory \
00174                [set phraseD [file join $options(dataDirectory) phrases]]]} {
00175         file mkdir $phraseD
00176     } else {
00177         pruneDir $phraseD phrase
00178     }
00179 
00180     set key [mime::uniqueID]
00181     set seqno 8
00182     while {[incr seqno -1] >= 0} {
00183         set key [otp_md5 -- $key]
00184     }
00185 
00186     set phraseF [file join $phraseD \
00187                       [join [split [string trim \
00188                                            [base64 -mode encode -- $key]] /] _]]
00189     if {[catch { close [open $phraseF { WRONLY CREAT TRUNC }] } result]} {
00190         tclLog $result
00191     }
00192 
00193     return [otp_words -mode encode -- $key]
00194 }
00195 
00196 ret  pruneDir (type dir , type type) {
00197     switch -- $type {
00198         addr {
00199             set days 14
00200         }
00201 
00202         msgid {
00203             set days 28
00204         }
00205 
00206         phrase {
00207             set days 7
00208         }
00209     }
00210 
00211     set then [expr {[clock seconds]-($days*86400)}]
00212 
00213     foreach file [glob -nocomplain [file join $dir *]] {
00214         if {(![catch { file mtime $file } result]) \
00215                 && ($result < $then) \
00216                 && ([catch { file delete -- $file } result])} {
00217             tclLog $result
00218         }
00219     }
00220 }
00221 
00222 ret  tclLog (type message) {
00223     global options
00224 
00225     if {([info exists options(debugP)]) && ($options(debugP) > 0)} {
00226         puts stderr $message
00227     }
00228 
00229     if {([string first "DEBUG " $message] == 0) \
00230             || ([catch { set fd [open $options(logFile) \
00231                                       { WRONLY CREAT APPEND }] }])} {
00232         return
00233     }
00234 
00235     regsub -all "\n" $message " " message
00236 
00237     catch { puts -nonewline $fd \
00238                  [format "%s %-8.8s %06d %s\n" \
00239                          [clock format [clock seconds] -format "%m/%d %T"] \
00240                          personal [expr {[pid]%65535}] $message] }
00241 
00242     catch { close $fd }
00243 }
00244 
00245 /*  end of routines that may be redefined in configFile*/
00246 
00247 
00248 global deleteFiles
00249 
00250  deleteFiles =  {}
00251 
00252 ret  cleanup (optional message ="" , optional status =75) {
00253     global deleteFiles
00254 
00255     foreach file $deleteFiles {
00256         if {[catch { file delete -- $file } result]} {
00257             tclLog $result
00258         }
00259     }
00260 
00261     if {[string compare $message ""]} {
00262         tclLog $message
00263         exit $status
00264     }
00265 
00266     exit 0
00267 }
00268 
00269 ret  dofolder (type folder , type inF) {
00270     global options
00271 
00272     catch { unset aprops }
00273 
00274     array set aprops [lindex [mime::parseaddress $folder] 0]
00275     set folder [join [split $aprops(local) /] _]
00276 
00277     if {[set folderN [llength [set folderL [split $folder .]]]] <= 1} {
00278         cleanup "invalid folder: $folder"
00279     }
00280 
00281     foreach f $folderL {
00282         if {![string compare $f ""]} {
00283             cleanup "invalid folder: $folder" 67
00284         }
00285     }
00286 
00287     if {![file isdirectory \
00288                [set articleD [eval [list file join \
00289                                          $options(foldersDirectory)] \
00290                                    [lrange $folderL 0 \
00291                    [expr {$folderN-2}]]]]]} {
00292         file mkdir $articleD
00293     }
00294     if {![file exists [set articleF [file join $articleD \
00295                                           [lindex $folderL \
00296                       [expr {$folderN-1}]]]]]} {
00297         set newP 1
00298     } else {
00299         set newP 0
00300     }
00301 
00302     set fd [open $options(foldersFile) { RDWR CREAT }]
00303     set fl "\n[read $fd]"
00304 
00305     set dir [lindex [file split $options(foldersDirectory)] end]
00306     if {[string first "\n$dir\n" $fl] < 0} {
00307         puts $fd $dir
00308     }
00309     foreach f $folderL {
00310         set dir [file join $dir $f]
00311         if {[string first "\n$dir\n" $fl] < 0} {
00312             puts $fd $dir
00313         }
00314     }
00315 
00316     close $fd
00317 
00318     if {[catch { saveMessage $inF $articleF } result]} {
00319         cleanup "unable to save message in $articleF: $result"
00320     }
00321 
00322     if {($newP) && ([info exists options(announceMailboxes)])} {
00323         if {[catch { smtp::sendmessage \
00324                          [mime::initialize \
00325                               -canonical text/plain \
00326                               -param {charset us-ascii} \
00327                               -string ""] \
00328                          -atleastone true \
00329                          -originator "" \
00330                          -header [list From    $options(myMailbox)] \
00331                          -header [list To      $options(announceMailboxes)] \
00332                          -header [list Subject "new folder $folder"] } \
00333                    result]} {
00334             tclLog $result
00335         }
00336     }
00337 }
00338 
00339 ret  alladdrs (type mime , type keys) {
00340     set result {}
00341 
00342     foreach key $keys {
00343         foreach value [mutl::getheader $mime $key] {
00344             foreach addr [mime::parseaddress $value] {
00345         lappend result $addr
00346         }
00347     }
00348     }
00349 
00350     return $result
00351 }
00352 
00353 ret  anyfriend (type outD , type addrs) {
00354     global options
00355 
00356     if {!$options(friendlyFire)} {
00357     return ""
00358     }
00359 
00360     foreach addr $addrs {
00361         catch { unset aprops }
00362 
00363         array set aprops $addr
00364     if {[catch { string tolower $aprops(local)@$aprops(domain) } \
00365            recipient]} {
00366         continue
00367     }
00368 
00369     if {[ownerP $aprops(local) $aprops(domain)]} {
00370         tclLog "DEBUG: skipping $recipient"
00371         continue
00372     }
00373 
00374     set outF [file join $outD [join [split $recipient /] _]]
00375     if {[file exists $outF]} {
00376         return $recipient
00377     }
00378 
00379     tclLog "DEBUG: unknown recipient $recipient"
00380     }
00381 
00382     return ""
00383 }
00384 
00385 
00386 if {[catch {
00387 
00388      program =  personal
00389 
00390     package require mutl 1.0
00391     package require smtp 1.1
00392     package require Tclx 8.0
00393 
00394 
00395 /*  parse arguments and initialize environment*/
00396 
00397      program =  [file tail [file rootname $argv0]]
00398 
00399      configFile =  .${program}-config.tcl
00400 
00401      debugP =  0
00402 
00403      messageFile =  -
00404 
00405      originatorAddress =  ""
00406 
00407      userName =  ""
00408 
00409     for { argx =  0} {$argx < $argc} {incr argx} {
00410          option =  [lindex $argv $argx]
00411         if {[incr argx] >= $argc} {
00412             cleanup "missing argument to $option"
00413         }
00414          value =  [lindex $argv $argx]
00415 
00416         switch -- $option {
00417             -config {
00418                  configFile =  $value
00419             }
00420 
00421             -debug {
00422                  options = (debugP) [ debugP =  [smtp::boolean $value]]
00423             }
00424 
00425             -file {
00426                  messageFile =  $value
00427             }
00428 
00429             -originator {
00430                  originatorAddress =  $value
00431             }
00432 
00433             -user {
00434                  userName =  $value
00435             }
00436 
00437             default {
00438                 cleanup "unknown option $option"
00439             }
00440         }
00441     }
00442 
00443     if {![string compare $messageFile -]} {
00444         array  tmp =  [mutl::tmpfile personal]
00445 
00446         lappend deleteFiles [ messageFile =  $tmp(file)]
00447 
00448         catch { file attributes $messageFile -permissions 0600 }
00449 
00450         if {[gets stdin line] <= 0} {
00451             cleanup "empty message"
00452         }
00453         if {[string first "From " $line] == 0} {
00454             if {![string compare $originatorAddress ""]} {
00455                  line =  [string range $line 5 end]
00456                 if {[ x =  [string first " " $line]] > 0} {
00457                      originatorAddress =  [string range $line 0 [expr {$x-1}]]
00458                 }
00459             }
00460         } else {
00461             puts $tmp(fd) $line
00462         }
00463         fcopy stdin $tmp(fd)
00464         close $tmp(fd)
00465     }
00466 
00467     if {[string compare $userName ""]} {
00468         if {[catch { id convert user $userName }]} {
00469             cleanup "userName doesn't exist: $userName"
00470         }
00471         if {([catch { file isdirectory ~$userName } result]) \
00472                 || (!$result)} {
00473             cleanup "userName doesn't have a home directory: $userName"
00474         }
00475 
00476         umask 0077
00477         cd ~$userName
00478     }
00479 
00480     if {![file exists $configFile]} {
00481         cleanup "configFile file doesn't exist: $configFile"
00482     }
00483     source $configFile
00484 
00485      options = (debugP) $debugP
00486 
00487     foreach {k v} [array get options] {
00488         if {![string compare $v ""]} {
00489             un options = ($k)
00490         }
00491     }
00492 
00493     foreach k [list dataDirectory defaultMaildrop] {
00494         if {![info exists options($k)]} {
00495             cleanup "configFile didn't define $k: $configFile"
00496         }
00497     }
00498 
00499     if {![file isdirectory $options(dataDirectory)]} {
00500         file mkdir $options(dataDirectory)
00501     }
00502 
00503     if {![info exists options(myMailbox)]} {
00504          options = (myMailbox) [id user]
00505     }
00506 
00507     if {![info exists options(friendlyFire)]} {
00508          options = (friendlyFire) 0
00509     }
00510 
00511 
00512 /*  crack the message*/
00513 
00514     if {[catch {  mime =  [mime::initialize -file $messageFile] } result]} {
00515 /*         global errorCode errorInfo*/
00516 /* */
00517 /*         set ecode $errorCode*/
00518 /*         set einfo $errorInfo*/
00519 /* */
00520 /*         if {![catch {*/
00521 /*             smtp::sendmessage \*/
00522 /*                 [mime::initialize \*/
00523 /*                      -canonical multipart/mixed \*/
00524 /*                      -parts [list [mime::initialize \*/
00525 /*                                         -canonical text/plain \*/
00526 /*                                         -param  {charset us-ascii} \*/
00527 /*                                         -string "$result\n\nerrorCode: $ecode\n\n$einfo"] \*/
00528 /*                                   [mime::initialize \*/
00529 /*                                         -canonical application/octet-stream \*/
00530 /*                                         -file $messageFile]]] \*/
00531 /*                 -originator "" \*/
00532 /*                 -header [list From    $options(myMailbox)] \*/
00533 /*                 -header [list To      $options(myMailbox)] \*/
00534 /*                 -header [list Subject "[info hostname] alert $program"]*/
00535 /*         }]} {*/
00536 /*             set result ""*/
00537 /*         }*/
00538 
00539     if {[info exists options(auditInFile)]} {
00540         saveMessage $messageFile $options(auditInFile)
00541         tclLog "invalid, but saved: $result"
00542         cleanup
00543     }
00544 
00545         cleanup "re-queued: $result"
00546     }
00547 
00548      origProper =  ""
00549     foreach key {From Sender Return-Path} {
00550         if {[string compare \
00551                     [ origProper =  [mutl::firstaddress \
00552                                          [mutl::getheader $mime $key]]] \
00553                     ""]} {
00554             break
00555         }
00556     }
00557     if {![string compare $origProper ""]} {
00558          origProper =  [mutl::firstaddress [list $originatorAddress]]
00559     }
00560 
00561     catch { un aprops =  }
00562 
00563     array  aprops =  [list local "" domain ""]
00564     array  aprops =  [lindex [mime::parseaddress $origProper] 0]
00565      origLocal =  $aprops(local)
00566      origDomain =  $aprops(domain)
00567 
00568     regsub -all "  *" \
00569            [ subject =  [string trim \
00570                                 [lindex [mutl::getheader $mime Subject] 0]]] \
00571            " " subject
00572 
00573 
00574     if {[catch {  folderTarget =  [impersonalMail $origLocal@$origDomain] }]} {
00575          folderTarget =  ""
00576     }
00577     if {[ impersonalP =  [string compare $folderTarget ""]]} {
00578         if {![info exists options(foldersDirectory)]} {
00579             cleanup "configFile didn't define folderTarget: $configFile"
00580         }
00581     } elseif {[info exists options(auditInFile)]} {
00582 /*  keep an audit copy of personal mail*/
00583 
00584         saveMessage $messageFile $options(auditInFile)
00585     }
00586 
00587 
00588 /*  perform duplicate supression*/
00589 
00590      messageID =  [lindex [concat [mutl::getheader $mime Resent-Message-ID] \
00591                                   [mutl::getheader $mime Message-ID]] 0]
00592     if {[string compare $messageID ""]} {
00593         if {![file isdirectory \
00594                    [ idD =  [file join $options(dataDirectory) msgids]]]} {
00595             file mkdir $idD
00596         } else {
00597             pruneDir $idD msgid
00598         }
00599 
00600         if {[ len =  [string length $messageID]] > 2} {
00601              messageID =  [string range $messageID 1 [expr {$len-2}]]
00602         }
00603         if {$impersonalP} {
00604              prefix =  X-
00605 
00606             catch { un aprops =  }
00607 
00608             array  aprops =  [lindex [mime::parseaddress $folderTarget] 0]
00609              prefix =  \
00610                 X-[lindex [split [join [split $aprops(local) /] _] .] 0]-
00611         } else {
00612              prefix =  ""
00613         }
00614 
00615          idF =  [file join $idD $prefix[join [split $messageID /] _]]
00616         if {[file exists $idF]} {
00617             tclLog "duplicate ID: $origProper $messageID ($subject)"
00618 
00619             cleanup
00620         }
00621 
00622         if {[catch { close [open $idF { WRONLY CREAT TRUNC }] } result]} {
00623             tclLog $result
00624         }
00625     }
00626 
00627 
00628 /*  record information about the originator*/
00629 
00630     if {![string compare \
00631                  [ origAddress =  \
00632                       [string tolower $origLocal@$origDomain]] \
00633                  @]} {
00634         tclLog "no originator"
00635 
00636         if {!$impersonalP} {
00637             saveMessage $messageFile
00638         }
00639 
00640         cleanup
00641     }
00642 
00643     tclLog "DEBUG ret essing: $origProper <$messageID> ($subject)"
00644 
00645     if (![type file , type isdirectory \
00646                    [, type set , type inD [, type file , type join $, type options(, type dataDirectory) , type inaddrs]]]) {
00647         file mkdir $inD
00648     }
00649 
00650      inF =  [file join $inD [join [split $origAddress /] _]]
00651     if {[catch {  fd =  [open $inF { WRONLY CREAT TRUNC }] } result]} {
00652         tclLog $result
00653     } else {
00654         catch { puts $fd $origProper }
00655         if {[catch { close $fd } result]} {
00656             tclLog $result
00657         }
00658     }
00659 
00660 
00661 /*  store impersonal mail in private folder area*/
00662 
00663     if {$impersonalP} {
00664         if {![string compare $messageID ""]} {
00665             cleanup "no Message-ID"
00666         }
00667 
00668         if {![file isdirectory $options(foldersDirectory)]} {
00669             file mkdir $foldersDirectory
00670         }
00671 
00672         array  mapping =  {}
00673 
00674         if {![catch {  fd =  [open $options(mappingFile) { RDONLY }] }]} {
00675             while {[gets $fd line] >= 0} {
00676                 if {([llength [ map =  [split $line :]]] == 2) \
00677                         && ([string length \
00678                                     [ k =  [string trim [lindex $map 0]]]] \
00679                                 > 0) \
00680                         && ([string length \
00681                                     [ v =  [string trim [lindex $map 1]]]] \
00682                                 > 0)} {
00683                      mapping = ($k) $v
00684                 }
00685             }
00686 
00687             if {[catch { close $fd } result]} {
00688                 tclLog $result
00689             }
00690         }
00691 
00692         if {![info exists mapping($folderTarget)]} {
00693              mapping = ($folderTarget) store
00694         }
00695         if {![string compare $mapping($folderTarget) ret ess]} (
00696             type catch , optional set =mapping($folderTarget) \
00697                         =[processFolder $folderTarget =$mime] 
00698         )
00699         switch -- $mapping($folderTarget) {
00700             store {
00701                 dofolder $folderTarget $messageFile
00702             }
00703 
00704             ignore {
00705                 tclLog "ignoring message for $folderTarget"
00706             }
00707 
00708             bounce {
00709                 cleanup "rejecting message for $folderTarget" 67
00710             }
00711 
00712             default {
00713                 if {[catch { smtp::sendmessage $mime \
00714                                  -atleastone true \
00715                                  -originator "" \
00716                                  -recipients $mapping($folderTarget) } \
00717                             result]} {
00718                     tclLog $result
00719                 }
00720             }
00721         }
00722 
00723         cleanup
00724     }
00725 
00726 
00727 /*  perform originator supression and guest list maintenance*/
00728 
00729     if {[string compare \
00730                 [ resentProper =  \
00731                      [mutl::firstaddress \
00732                           [mutl::getheader $mime Resent-From]]] \
00733                 ""]} {
00734         catch { un aprops =  }
00735 
00736         array  aprops =  [lindex [mime::parseaddress $resentProper] 0]
00737          resentLocal =  $aprops(local)
00738          resentDomain =  $aprops(domain)
00739 
00740         if {[string compare \
00741                     [ resentAddress =  \
00742                          [string tolower $resentLocal@$resentDomain]] \
00743                     @]} {
00744             foreach p {Proper Local Domain Address} {
00745                  orig = $p [ resent = $p]
00746             }
00747         }
00748     }
00749 
00750     foreach p {out tmp bad} {
00751         if {![file isdirectory [ ${p = }D [file join $options(dataDirectory) \
00752                                                 ${p}addrs]]]} {
00753             file mkdir [ ${p = }D]
00754         }
00755 
00756          ${p = }F [file join [ ${p = }D] [join [split $origAddress /] _]]
00757     }
00758 
00759     pruneDir $tmpD addr
00760 
00761 
00762 /*  deal with Klez-inspired nonsense*/
00763     if {([info exists options(dropNames)]) && ([catch { 
00764         foreach part [mime::getproperty $mime parts] {
00765             catch { un params =  }
00766             array  params =  [mime::getproperty $part params]
00767             if {[info exists params(name)]} {
00768         foreach name $options(dropNames) {
00769             if {[string match $name $params(name)]} {
00770                         tclLog "rejecting: $origProper <$messageID> ($subject) $params(name)"
00771                         cleanup
00772             }
00773         }
00774             }
00775         }
00776     } result])} {
00777     tclLog "Klez-check: $result"
00778     }
00779 
00780      friend =  ""
00781     if {[adminP $origLocal $origDomain]} {
00782         tclLog "DEBUG admin check: $origProper <$messageID> ($subject)"
00783 
00784 /*  if DSNs were the rule, it would make sense to parse it... no such luck*/
00785 
00786          fd =  [open $messageFile { RDONLY }]
00787          text =  [read $fd]
00788         if {[catch { close $fd } result]} {
00789             tclLog $result
00790         }
00791 
00792         foreach file [glob -nocomplain [file join $badD *]] {
00793              addr =  [file tail $file]
00794             if {([string match *$addr* $text]) \
00795                     || (([ x =  [string first @ $addr]] > 0) \
00796                             && ([string match \
00797                 *[string range $addr 0 [expr {$x-1}]]* \
00798                                         $text]))} {
00799                 tclLog "failure notice: $origProper ($addr)"
00800 
00801                 cleanup
00802             }
00803         }
00804 
00805         tclLog "DEBUG admin continue: $origProper <$messageID> ($subject)"
00806     } elseif {(![ownerP $origLocal $origDomain]) \
00807                     && (![friendP $origLocal $origDomain]) \
00808                     && (![file exists $outF]) \
00809                     && (![file exists $tmpF]) \
00810                     && (![string compare ""\
00811                       [ friend =  [anyfriend $outD \
00812                                   [alladdrs $mime {To cc}]]]]) \
00813                     && (![findPhrase $subject]) \
00814                     && ([info exists options(noticeFile)])} {
00815         if {[file exists $badF]} {
00816             catch { file delete -- $badF }
00817         } elseif {[catch {
00818              fd =  [open $options(noticeFile) { RDONLY }]
00819              text =  [read $fd]
00820             if {[catch { close $fd } result]} {
00821                 tclLog $result
00822             }
00823 
00824             regsub -all %passPhrase% $text [makePhrase] text
00825             for { rsubject =  $subject} \
00826                     {[regexp -nocase ^re: $rsubject]} \
00827                     { rsubject =  [string trimleft \
00828                                            [string range $rsubject 3 end]]} {
00829             }
00830             regsub -all %subject% $text $rsubject text
00831 
00832             smtp::sendmessage \
00833                 [mime::initialize \
00834                      -canonical multipart/mixed \
00835                      -parts [list [mime::initialize \
00836                                        -canonical text/plain \
00837                                        -param {char us = -ascii} \
00838                                        -string $text] \
00839                                   [mime::initialize \
00840                                         -canonical message/rfc822 \
00841                                         -parts [list $mime]]]] \
00842                 -originator "" \
00843                 -header [list From    $options(myMailbox)] \
00844                 -header [list To      $origProper] \
00845                 -header [list Subject "Re: $rsubject"]
00846 
00847               fd =  [open $badF { WRONLY CREAT TRUNC }]
00848         } result]} {
00849             tclLog $result
00850         } else {
00851             catch { puts $fd $origProper }
00852             if {[catch { close $fd } result]} {
00853                 tclLog $result
00854             }
00855         }
00856         tclLog "rejecting: $origProper <$messageID> ($subject)"
00857 
00858         cleanup
00859     } elseif {[string compare $friend ""]} {
00860         tclLog "accepting: $origProper because of $friend"
00861     } else {
00862         if {[ownerP $origLocal $origDomain]} {
00863              addrD =  $outD
00864         } else {
00865              addrD =  $tmpD
00866         }
00867 
00868     foreach addr [alladdrs $mime \
00869                        {From To cc Resent-From Resent-To Resent-cc}] {
00870             catch { un aprops =  }
00871 
00872             array  aprops =  $addr
00873              addrLocal =  $aprops(local)
00874              addrDomain =  $aprops(domain)
00875 
00876             if {[string compare \
00877                         [ addrAddress =  \
00878                              [string tolower $addrLocal@$addrDomain]] @]} {
00879                  addrF =  [file join $addrD [join [split $addrAddress /] _]]
00880 
00881                 if {[file exists $addrF]} {
00882                     continue
00883                 }
00884 
00885                 if {[catch {  fd =  [open $addrF { WRONLY CREAT TRUNC }] } \
00886                            result]} {
00887                     tclLog $result
00888                 } else {
00889                     catch { puts $fd $aprops(proper) }
00890                     if {[catch { close $fd } result]} {
00891                         tclLog $result
00892                     }
00893                 }
00894         }
00895         }
00896     }
00897 
00898 
00899 /*  perform final actions, if we're the originator*/
00900 
00901     if {[ownerP $origLocal $origDomain]} {
00902         if {[info exists options(auditOutFile)]} {
00903             saveMessage $messageFile $options(auditOutFile)
00904         }
00905 
00906         cleanup
00907     }
00908 
00909 
00910 /*  send a copy to the pda*/
00911 
00912     if {([info exists options(pdaMailboxes)]) \
00913             && ([string compare [ text =  [mutl::gathertext $mime]] ""])} {
00914         if {[info exists options(pdaMailsize)]} {
00915              text =  [string range $text 0 [expr {$options(pdaMailsize)-1}]]
00916         }
00917          pda =  [mime::initialize \
00918                      -canonical text/plain \
00919                      -param {char us = -ascii} \
00920                      -string $text]
00921 
00922         foreach key {From To cc Subject Date Reply-To} {
00923             foreach value [mutl::getheader $mime $key] {
00924                 mime::header =  $pda $key $value -mode append
00925             }
00926         }
00927 
00928         if {[catch { smtp::sendmessage $pda \
00929                          -atleastone true \
00930                          -originator "" \
00931                          -recipients $options(pdaMailboxes) } result]} {
00932             tclLog $result
00933         }
00934     }
00935 
00936 
00937 /*  send a copy to the remote mailbox*/
00938 
00939     if {[info exists options(remoteMailboxes)]} {
00940         if {[catch { smtp::sendmessage $mime \
00941                          -atleastone true \
00942                          -originator "" \
00943                          -recipients $options(remoteMailboxes) } result]} {
00944             tclLog $result
00945         } else {
00946             cleanup
00947         }
00948     }
00949 
00950     saveMessage $messageFile
00951 
00952 
00953     cleanup
00954 
00955 
00956 } result]} {
00957     global errorCode errorInfo
00958 
00959      ecode =  $errorCode
00960      einfo =  $errorInfo
00961 
00962     if {(![catch { info body tclLog } result2]) \
00963             && ([string compare [string trim $result2] \
00964                         {catch {puts stderr $string}}])} {
00965         catch { tclLog $result }
00966     }
00967 
00968     catch {
00969         smtp::sendmessage \
00970             [mime::initialize \
00971                  -canonical text/plain \
00972                  -param  {char us = -ascii} \
00973                  -string "$result\n\nerrorCode: $ecode\n\n$einfo"] \
00974             -originator "" \
00975             -header [list From    [id user]@[info hostname]]       \
00976             -header [list To      operator@[info hostname]]        \
00977             -header [list Subject "[info hostname] fatal $program"]
00978     }
00979 
00980     cleanup $result
00981 }
00982 
00983 
00984 exit 75
00985 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1