发信人: vcc()
整理人: wenbobo(2002-12-27 15:54:18), 站内信件
|
【 在 love1974 (<marquee>令狐冲</) 的大作中提到: 】
好久不见你了,怎么你的主页去不了?
你可以去codeguru.com找,我记得有。
对了,我贴个tcl/tk写的,我想应该很简单吧,可是用脚本语言实现的。我想c
应该不会比他更复杂吧,何况tcl/tk可以很容易集成到c程序中。
#! /usr/bin/tclsh8.0
#set DEBUG(Mail) 0
#@ Scans for Options. opvar is a array with possible options. I t may contain defaults.
#@ Takes options from args lists
proc bs_ScanOpts1 {optsvar} {
#puts "Got var: $optsvar"
#set arglist [split [string trim $args {\{\} }]]
#set args [list $args]
upvar args args
if {[llength $args]==1} {eval set args $args}
#puts "Got args: $args [lindex $args 3]"
set i 0; set count 0
while { $i < [llength $args]} {
set token [lindex $args $i]
#puts "Scan: $token"
if {[string index $token 0] == "-"} {
set argname [string range $token 1 end]
incr i
set argval [lindex $args $i]
uplevel set ${optsvar}($argname) \"$argval\"
#puts "set ${optsvar}($argname) to \"$argval\""
incr i
incr count;
continue
}
break
# no more args!
}
set body [lrange $args $i end]
if {[llength $body] > 1 } {
set body [list $body]
}
#uplevel set ${optsvar}(body) \"[eval set x [lrange $args $i end]] \"
uplevel set ${optsvar}(body) \"[eval set x $body]\"
# tell me if you understand this...
return $count
}
#@ Debug output if context matches
proc bs_Debug {context txt} {
global DEBUG
if {$DEBUG(Mail) || $DEBUG(All)} {
puts "HF Debug ($context): $txt"
}
}
#@ Private. Build full address.
proc bs_GetAdr { fulladr } {
return "<[lindex $fulladr 1]>"
}
#@ Private. Returns first part.
proc bs_GetName { fulladr } {
return "[lindex $fulladr 0]"
}
#@ Private. Builds a full address.
proc bs_GetFullAdr { fulladr } {
return "[lindex $fulladr 0] <[lindex $fulladr 1]>"
}
#@ Send Mail to a SendMail deamon.<br>
#@ examples<pre>
#@ set fr {{Bob Schulze} {[email protected]}}
#@ set k {{Katrin S} {[email protected]}}
#@ set h {Hans [email protected]}
#@ tSMTPmail -debug 1 -from $fr -toList [list $k $h] fdf
#@
#@ tSMTPmaill -debug 1 -from $fr -toList {{{Bob Schulze} {[email protected] }}} \
#@ -Subject "Test tSMTPMail" \
#@ -Reply-To [email protected] "This is a test of
#@ some mail"
#@
#@ set fr [list "tSMTPmail Tester"]
#@ set to {{Bob {[email protected]}}}
#@ tSMTPmail -debug 1 -from $fr -toList $to -Subject "tSMTPmail Test" {
#@ ----------------------------------------------------
#@ I'am Testing tSMTPmail. Please tell me if it worked!
#@ ----------------------------------------------------}
#@
#@ Note how the (one element) list is build. Using list is probably mo st straighforeward.
#@ </pre>
#@ note: You may use any allowed header as command line arg, su ch as Reply-To etc. But thestring must conform exactly to the standard , means not reply-TO etc. There is not explicit check for this.<br>
#@ Addresses are in form {{Bob Schulze} {<[email protected]>}<br>
#@ note: The name-address Syntax is fitting to most sendmail se tups, in strange cases it might fail. You'll have to dig into the code then.<br>
#@ option -smtphost Optional. Uses localhost otherwise. IP Addr . or name.<br>
#@ option -authuser HELO Connection user. Sometimes rebuild as "Sender".<br>
#@ option -toList,ccList,bccList Lists of Names/Addresses. See Examples.<br>
#@ option -port Sendmail port<br>
#@ option -debug 1|0 overrides global DEBUG(Mail) (if exists). 1 Means verbose debug output on.<br>
#@ option -Timeout Defaults to 5 Seconds. This is sendmails all owed response delay. An Error will be thrown otherwise.<br>
#@ option -blocking 0|1 On windows systems the fblocking call i s not working well; you may disable the timeout check by setting this to 1. Default is 0.<br>
#@ returns -1 on Error , Total Response time if all goes ok.<br >
#@ error Throws tcl errors if something goes wrong (Unexpected replies from sendmail or Timeout).<br>
#@ <br><br>
#@ How to Test: Check if the first line of this file points to tclsh8.0, make it executable and start it. A dialog with sendmail will appear. The code for this test is at the end of the file. Remove it i f you start using it for production!1
proc tSMTPmail args {
# handles a complete smtp transaction
proc bs_TalkToSm { what should } {
upvar sock sock
upvar op op
upvar rtime rtime
upvar tout tout
puts $sock $what
flush $sock
bs_Debug Mail "Send: <$what>"
if {$should != 0} {
if [catch {
bs_CheckMailResponse $should
} e_info] {
error "Response Err When sending -- $what -- : $e_info"
}
}
}
# looks for returns within timeout. fblocking might show up strang e
# on some platforms...
proc bs_CheckMailResponse should {
upvar op op
upvar sock sock
upvar rtime rtime
upvar tout tout
set res ""
set ttime 0
while 1 {
set ttt [time {set res [gets $sock]}]
if { $res != "" } break
incr ttime 100
after 100
if {$ttime > $tout } {
error "tSMTPmail: Err When Sending: Exceeded Timeout of $op(Timeout) Sec."
break
}
}
incr rtime [expr [lindex $ttt 0]/1000 + $ttime]
bs_Debug Mail "Response: <$res>"
#bs_Debug Mail "Response time: $rtime ms"
if { [lindex $res 0] != $should } {
bs_Debug Mail "Wrong Response: Should be $should, is [lindex $res 0]"
error "Wrong Response: Should be $should, is [lindex $res 0]\n"
return 1
}
return 0
}
#
# Main Procedure.
#
if [catch {
global DEBUG
set rtime 0
# read options
set op(smtphost) 127.0.0.1
set op(authuser) tSMTPmail
set op(from) tSMTPmail
set op(toList) ""
set op(debug) -1
set op(ccList) ""
set op(bccList) ""
set op(port) 25
set op(Timeout) 5
set op(blocking) 0
bs_ScanOpts1 op
set tout [expr $op(Timeout) * 1000]
#set tout 5000
# handle DEBUGGING, option overrides
if {! [info exists DEBUG(Mail)]} {
set DEBUG(Mail) 0
}
if {! [info exists DEBUG(All)]} {
set DEBUG(All) 0
}
set olddebug $DEBUG(Mail)
if {$op(debug) != -1} {
set DEBUG(Mail) $op(debug)
}
# exclude list for header fields
set donotsend "Timeout smtphost body authuser port debug from toList ccList bccList blocking"
#
bs_Debug Mail "Read Options:"
#bs_Debug Mail "[parray op]"
#bs_Debug Mail " ---end Options array---"
#
set sock [socket $op(smtphost) $op(port)]
fconfigure $sock -blocking $op(blocking)
bs_Debug Mail "Connected to $op(smtphost):$op(port)"
bs_CheckMailResponse 220
# authenticate..
bs_TalkToSm "HELO $op(authuser)" 250
bs_TalkToSm "MAIL FROM: <[bs_GetName $op(from)]>" 250
# to's
bs_Debug Mail "SMTP To's..."
foreach t $op(toList) {
bs_TalkToSm "RCPT TO: [bs_GetAdr $t]" 250
}
# cc's
bs_Debug Mail "SMPT CC's..."
foreach t $op(ccList) {
bs_TalkToSm "RCPT TO: [bs_GetAdr $t]" 250
}
# bcc's
bs_Debug Mail "SMPT BCC's..."
foreach t $op(bccList) {
bs_TalkToSm "RCPT TO: [bs_GetAdr $t]" 250
}
# data
bs_TalkToSm "DATA" 354
# header
bs_Debug Mail "Writing Header..."
# to's
bs_Debug Mail "Header To's..."
foreach t $op(toList) {
bs_TalkToSm "To: [bs_GetFullAdr $t]" 0
}
# cc's
bs_Debug Mail "Header cc's..."
foreach t $op(ccList) {
bs_TalkToSm "Cc: [bs_GetFullAdr $t]" 0
}
# bcc's NOT
# other fields
foreach f [array name op] {
#puts "$donotsend -- [lsearch -exact $donotsend $f] --"
if {[lsearch -exact $donotsend $f] > -1} {
continue
}
bs_Debug Mail "Header $f"
bs_TalkToSm "$f: $op($f)" 0
}
# text
bs_Debug Mail "Text Body..."
# escape leading .
bs_TalkToSm "$op(body)" 0
# close
bs_TalkToSm "." 250
bs_TalkToSm "QUIT" 221
catch {close $sock}
# restore debug
set DEBUG(Mail) $olddebug
#return 0
} e_info] {
catch {close $sock}
catch {set DEBUG(Mail) $olddebug}
error "tSMTPmail: $e_info"
return -1
}
return [expr $rtime / 1000.0]
}
# Test code. REMOVE after testing! You will get an reply each time you send mail with it.
if [info exists env(USER)] {
set fr [list $env(USER)]
} else {
set fr [list "tSMTPmail Tester"]
}
set fr {{vcc} {[email protected]}}
set to {{vcc} {[email protected]}}
tSMTPmail -debug 1 -from $fr -toList $to -Subject "tSMTPmail Test" {
----------------------------------------------------
I'am Testing tSMTPmail. Please tell me if it worked!
----------------------------------------------------}
-- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.103.146.3]
|
|