personal.tcl
Go to the documentation of this file.00001
00002
00003 exec tclsh "$0" ${1+"$@"}
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 package require Tcl 8.3
00014
00015 global options
00016
00017
00018
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
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
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
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
00513
00514 if {[catch { mime = [mime::initialize -file $messageFile] } result]} {
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
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
00583
00584 saveMessage $messageFile $options(auditInFile)
00585 }
00586
00587
00588
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
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
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
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
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
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
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
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
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