cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
4901
Views
0
Helpful
25
Replies

Send MAIL TCL not working

mcamocardi
Level 1
Level 1

Hi guys, can you help me to send an email on a track event?

I am trying to send an e-mail on a track state change and I am having problems; follows some outputs:

IOS: flash:c1841-advipservicesk9-mz.151-3.T4.bin

R-1841#sh event manager version

Embedded Event Manager Version 3.20

Component Versions:

eem: (v320_rel1)1.0.8

eem-gold: (v320_rel1)1.0.0

eem-call-home: (v320_rel1)1.0.0

/**********************/

R-1841#more flash:mail2.tcl

::cisco::eem::event_register_syslog occurs 1 pattern ".*list boolean.*"

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

set mail_pre "Mailservername: marcelo@xxx.com.br:password@177.73.xxx.xxx\n"

append mail_pre "From: marcelo@xxx.com.br\n"

append mail_pre "To: marcelo.xxx@gmail.com\n"

append mail_pre "Cc: \n"

append mail_pre "Port: 587\n"

append mail_pre "Subject: LINK DOWN\n"

append mail_pre "Teste\n\n"

set mail_msg [uplevel #0 [list subst -nobackslashes -nocommands $mail_pre]]

if [catch {smtp_send_email $mail_msg} result] {

    error $result $errorInfo

}

/*****************************/

event manager directory user policy "flash:/"

event manager policy mail2.tcl

/********************************/

Dec 13 16:04:49: %TRACKING-5-STATE: 1 list boolean or Down->Up

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl: Process Forced Exit- MAXRUN timer expired.

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:     while executing

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl: "if [catch {smtp_send_email $mail_msg} result] {

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:     error $result $errorInfo

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl: }"

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:     invoked from within

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl: "$slave eval $Contents"

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:     (procedure "eval_script" line 7)

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:     invoked from within

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl: "eval_script slave $scriptname"

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:     invoked from within

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl: "if {$security_level == 1} {       #untrusted script

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:      interp create -safe slave

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:      interp share {} stdin slave

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:      interp share {} stdout slave

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl: ..."

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl:     (file "tmpsys:/lib/tcl/base.tcl" line 50)

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl: Tcl policy execute failed:

Dec 13 16:05:13: %HA_EM-6-LOG: mail2.tcl: Process Forced Exit- MAXRUN timer expired.

I removed the event manager policy and reaplyed.

I tested the smtp server on port 587 and it works.

25 Replies 25

Joe Clarke
Cisco Employee
Cisco Employee

Our code uses tcp/25 for SMTP.  Support for custom ports was not added until EEM 4.0 in 15.2(2)T.

There is no such version for 1841, the leatest version is 15.1.4M7(MD)

15.1.4M7(MD)

Yeah, the ISR platform ends at 15.1.  You can take the smtp_lib.tcl from tmpsys:/lib/tcl on your router and modify it to use 587 instead of 25.  Then you can add it back as a user library (change the function names in the library to be local such as "my_smtp_connect").  Then call your user version of the email function and it should work.

Cool, thank you Joseph! I´ll try that and let you know

Hi Joseph, I copyed the file and edited it. Now it is on flash, but I cannot copy it back to the tmpsys file:

R-1841#copy flash:smtp_lib.tcl tmpsys:/lib/tcl/

Destination filename [/lib/tcl/smtp_lib.tcl]?

%Error opening tmpsys:/lib/tcl/smtp_lib.tcl (Permission denied)

Should I change my this part of the code? How should it be?

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

No, you won't be able to.  This is why I said add it back as a user library.  You'll need to put it in a directory, then configure:

event manager directory user library DIR

Hi Joseph, sorry to bother, but I don´t understand exactly; this is what I did so far:

I copyed the custom file to flash:custom_smtp_lib.tcl


I have this:

event manager directory user policy "flash:/"

event manager directory user library "flash:/"

event manager policy mail2.tcl

Do I have to change something on my mail2.tcl?

::cisco::eem::event_register_syslog occurs 1 pattern ".*list boolean.*"

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

set mail_pre "Mailservername: marcelo@xxx.com.br:xxxxx@177.73.xxx.xxx\n"

append mail_pre "From: marcelo@xxxxxx.com.br\n"

append mail_pre "To: xxxxxx@gmail.com\n"

append mail_pre "Cc: \n"

append mail_pre "Port: 587\n"

append mail_pre "Subject: LINK DOWN\n"

append mail_pre "Teste\n\n"

set mail_msg [uplevel #0 [list subst -nobackslashes -nocommands $mail_pre]]

if [catch {smtp_send_email $mail_msg} result] {

    error $result $errorInfo

}

Well, assuming you renamed all of the procs in your mail2.tcl to my_PROC_NAME, then you need to change your final call to:

if [catch {my_smtp_send_email $mail_msg} result] {

    ...

}

Thanks Joseph,

I am still having problema, as I am not a programer I am having trouble to understand what to do. I did many variations and I am having basically this output:

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl: unknown namespace in import pattern "::custom::lib::*"

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl:     while executing

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl: "namespace import ::custom::lib::*"

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl:     invoked from within

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl: "$slave eval $Contents"

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl:     (procedure "eval_script" line 7)

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl:     invoked from within

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl: "eval_script slave $scriptname"

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl:     invoked from within

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl: "if {$security_level == 1} {       #untrusted script

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl:      interp create -safe slave

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl:      interp share {} stdin slave

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl:      interp share {} stdout slave

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl: ..."

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl:     (file "tmpsys:/lib/tcl/base.tcl" line 50)

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl: Tcl policy execute failed:

Dec 16 08:51:02: %HA_EM-6-LOG: mail2.tcl: unknown namespace in import pattern "::custom::lib::*"

In my head I have to make the code call the custom_smtp_lib.tcl file as I cannot put back in tmpsys:/lib/tcl/. I am trying something like this:

event manager directory user policy "flash:/"

event manager directory user library "flash:/"

event manager policy mail2.tcl

/************mail2.tcl********************/

::cisco::eem::event_register_syslog occurs 1 pattern ".*1 list boolean or.*"

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

source "custom_smtp_lib.tcl"

namespace import ::custom::lib::*

set mail_pre "Mailservername: marcelo@xxx.com.br:xxx@177.73.xxx.xxx\n"

append mail_pre "From: marcelo@xxx.com.br\n"

append mail_pre "To: xxx@gmail.com\n"

append mail_pre "Cc: \n"

append mail_pre "Port: 587\n"

append mail_pre "Subject: Link Virtua DOWN\n"

append mail_pre "Teste\n\n"

set mail_msg [uplevel #0 [list subst -nobackslashes -nocommands $mail_pre]]

if [catch {my_smtp_send_email $mail_msg} result] {

    error $result $errorInfo

}



You shouldn't need to source anything.  But if you change custom_smtp_lib.tcl, you need to unconfigure and reconfigure event manager directory user library so that the latest copy is synced with EEM.

Hi Joseph, how are you doing?

Well I changed the code and still having problems, as I said, in my head I need to estate somewhare that I am using the custom_smtp_lib.tcl.

I did this two variations with the following outputs:

1 - mail2.tcl

::cisco::eem::event_register_syslog occurs 1 pattern ".*1 list boolean or.*"

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

set mail_pre "Mailservername: marcelo@xxx.com.br:xxx@177.73.xxx.xxx\n"

append mail_pre "From: marcelo@xxx.com.br\n"

append mail_pre "To: xxx@gmail.com\n"

append mail_pre "Cc: \n"

append mail_pre "Port: 587\n"

append mail_pre "Subject: Link Virtua DOWN\n"

append mail_pre "Teste\n\n"

set mail_msg [uplevel #0 [list subst -nobackslashes -nocommands $mail_pre]]

if [catch {my_smtp_send_email $mail_msg} result] {

    error $result $errorInfo

}

/**********************************************************************************/

no event manager directory user policy "flash:/"

no event manager directory user library "flash:/"

no event manager policy mail2.tcl

event manager directory user policy "flash:/"

event manager directory user library "flash:/"

event manager policy mail2.tcl

int lo0

shut

Dec 19 09:10:52: %TRACKING-5-STATE: 1 list boolean or Down->Up

%HA_EM-6-LOG: mail2.tcl: invalid command name "my_smtp_send_email"

%HA_EM-6-LOG: mail2.tcl:     while executing

%HA_EM-6-LOG: mail2.tcl: "my_smtp_send_email $mail_msg"

%HA_EM-6-LOG: mail2.tcl:     invoked from within

%HA_EM-6-LOG: mail2.tcl: "$slave eval $Contents"

%HA_EM-6-LOG: mail2.tcl:     (procedure "eval_script" line 7)

%HA_EM-6-LOG: mail2.tcl:     invoked from within

%HA_EM-6-LOG: mail2.tcl: "eval_script slave $scriptname"

%HA_EM-6-LOG: mail2.tcl:     invoked from within

%HA_EM-6-LOG: mail2.tcl: "if {$security_level == 1} {       #untrusted script

%HA_EM-6-LOG: mail2.tcl:      interp create -safe slave

%HA_EM-6-LOG: mail2.tcl:      interp share {} stdin slave

%HA_EM-6-LOG: mail2.tcl:      interp share {} stdout slave

%HA_EM-6-LOG: mail2.tcl: ..."

%HA_EM-6-LOG: mail2.tcl:     (file "tmpsys:/lib/tcl/base.tcl" line 50)

%HA_EM-6-LOG: mail2.tcl: Tcl policy execute failed:

%HA_EM-6-LOG: mail2.tcl: invalid command name "my_smtp_send_email"

/**********************************************************************************/

2 - mail2.tcl

::cisco::eem::event_register_syslog occurs 1 pattern ".*1 list boolean or.*"

namespace import ::cisco::eem::*

namespace import ::cisco::lib::*

namespace import ::custom::lib::*

set mail_pre "Mailservername: marcelo@xxx.com.br:xxx@177.73.xxx.xxx\n"

append mail_pre "From: marcelo@xxx.com.br\n"

append mail_pre "To: xxx@gmail.com\n"

append mail_pre "Cc: \n"

append mail_pre "Port: 587\n"

append mail_pre "Subject: Link Virtua DOWN\n"

append mail_pre "Teste\n\n"

set mail_msg [uplevel #0 [list subst -nobackslashes -nocommands $mail_pre]]

if [catch {my_smtp_send_email $mail_msg} result] {

    error $result $errorInfo

}


/**********************************************************************************/

no event manager directory user policy "flash:/"

no event manager directory user library "flash:/"

no event manager policy mail2.tcl

event manager directory user policy "flash:/"

event manager directory user library "flash:/"

event manager policy mail2.tcl

int lo0

shut

%HA_EM-6-LOG: mail2.tcl:     while executing

%HA_EM-6-LOG: mail2.tcl: "namespace import ::custom::lib::*"

%HA_EM-6-LOG: mail2.tcl:     invoked from within

%HA_EM-6-LOG: mail2.tcl: "$slave eval $Contents"

%HA_EM-6-LOG: mail2.tcl:     (procedure "eval_script" line 7)

%HA_EM-6-LOG: mail2.tcl:     invoked from within

%HA_EM-6-LOG: mail2.tcl: "eval_script slave $scriptname"

%HA_EM-6-LOG: mail2.tcl:     invoked from within

%HA_EM-6-LOG: mail2.tcl: "if {$security_level == 1} {       #untrusted script

%HA_EM-6-LOG: mail2.tcl:      interp create -safe slave

%HA_EM-6-LOG: mail2.tcl:      interp share {} stdin slave

%HA_EM-6-LOG: mail2.tcl:      interp share {} stdout slave

%HA_EM-6-LOG: mail2.tcl: ..."

%HA_EM-6-LOG: mail2.tcl:     (file "tmpsys:/lib/tcl/base.tcl" l

%HA_EM-6-LOG: mail2.tcl: Tcl policy execute failed:

%HA_EM-6-LOG: mail2.tcl: unknown namespace in import pattern "::custom::lib::*"


Post your modified smtp_lib.tcl file.

#------------------------------------------------------------------

# SMTP client Tcl Library.

#

# Dec. 1999, Yu Zhang

#

# Copyright (c) 1999-2003, 2005-2008 by cisco Systems, Inc.

# All rights reserved.

#------------------------------------------------------------------

namespace eval ::cisco::lib {

  namespace export smtp_subst smtp_send_email

  # messages corresponding to SMTP reply codes

  variable reply_code_str

  set reply_code_str(211) "System status, or system help reply"

  set reply_code_str(214) "Help message"

  set reply_code_str(220) "Service ready"

  set reply_code_str(221) "Service closing transmission channel"

  set reply_code_str(235) "Authentication successful"

  set reply_code_str(250) "Requested mail action okay, completed"

  set reply_code_str(251) "User not local; will forward to some forward-path"

  set reply_code_str(334) "Password"

  set reply_code_str(354) "Start mail input; end with ."

  set reply_code_str(421) "Service not available, closing transmission channel"

  set reply_code_str(450) "Requested mail action not taken: mailbox unavailable"

  set reply_code_str(451) "Requested action aborted: local error in processing"

  set reply_code_str(452) "Requested action not taken: insufficient system storage"

  set reply_code_str(500) "Syntax error, command unrecognized"

  set reply_code_str(501) "Syntax error in parameters or arguments"

  set reply_code_str(502) "Command not implemented"

  set reply_code_str(503) "Bad sequence of commands"

  set reply_code_str(504) "Command parameter not implemented"

  set reply_code_str(550) "Requested action not taken: mailbox unavailable"

  set reply_code_str(551) "User not local; please try forward-path"

  set reply_code_str(552) "Requested mail action aborted: exceeded storage allocation"

  set reply_code_str(553) "Requested action not taken: mailbox name not allowed"

  set reply_code_str(554) "Transaction failed"

}

# Write a message 'msg' to the given smtp socket 'sock'.

# Possible error raised:

#           None.

proc ::cisco::lib::smtp_write { sock msg } {

  ::cisco::eem::smtp_debug "smtp_write" "$msg"

  puts $sock "$msg"

  flush $sock

  return

}

proc ::cisco::lib::smtp_write_nodebug { sock msg } {

  puts $sock "$msg"

  flush $sock

  return

}

# Synchronously read one line from the  given smtp socket 'sock'.

# Possible error raised:

#           None.

proc ::cisco::lib::smtp_read { sock } {

  set t [gets $sock k]

  if { $k == "" && $t == -1} {

      return -1

      ::cisco::eem::smtp_debug "smtp_read " "-1"

  }

  ::cisco::eem::smtp_debug "smtp_read " "$k"

  return $k

}

# Check the reply code of the given connection. If it is not successful,

# raise an error with the corresponding error message. Also used to

# synchronize the request and reply.

proc ::cisco::lib::smtp_chk_reply { sock succ_code } {

  variable reply_code_str

  set r [ smtp_read $sock ]

  if {$r == -1} {

      return -code error "Socket closed by remote server"

  }

  set k [lindex $r 0]

  if {$k != $succ_code} {

      return -code error [concat From SMTP server: $r\n$reply_code_str($k)]

  }

  return

}

# Given the text of an email template file with all global variables

# Try to open a socket to any of the candidate mail servers.

# Return the first socket successfully opened.

# Possible error raised:

# 1. $sock closed by remote server

# 2. $sock reply code is $k instead of the service ready greeting

# 3. cannot connect to all the candidate mail servers

proc ::cisco::lib::smtp_connect { svrlist srcipaddr srcintname} {

  global _username _userpass

  set num_retries 4

  set retry_delay 3000

  set l [llength $svrlist]

  for {set attempt 1} {$attempt <= [ expr $num_retries + 1 ]} {incr attempt} {

      ::cisco::eem::smtp_debug "smtp_connect" "attempt $attempt"

      for {set i 0} {$i < [ expr $l ]} {incr i} { 

          set svr [lindex $svrlist $i]

  # parse svr field which can be

  # username:password@host

  # username@host

  # host

          regexp {(.+@)?(.*)$} $svr match uidpwd svrhost

          regexp {(.+\:)?(.*)$} $uidpwd match a1 a2

          #  $a2 will be the uid if no password specified

          if { $a1 != "" } {

              set uid $a1

              set pwd $a2

          } else {

              set uid [string trimright $a2 @]

              set pwd ""

          }

  set _username [::base64::encode [string trimright $uid :] ]

  set _userpass [::base64::encode [string trimright $pwd @] ]

          if {[info exists sock]} {

              unset sock

          }

          if { $srcipaddr != "" } {

              catch [set sock [ socket -myaddr $srcipaddr $svrhost 587 ]]

          } else {

              if { $srcintname != "" } {

                  set srcipaddr [ intf_get_ip $srcintname $svrhost ]

                  catch [set sock [ socket -myaddr $srcipaddr $svrhost 587 ]]

              } else {

                  catch [set sock [ socket $svrhost 587 ]]

              }

  }

          if {![info exists sock]} {

              continue

          }

          if [catch {smtp_chk_reply $sock 220} result] {

              return -code error $result

          }

          return $sock

      }

      if {$attempt < [ expr $num_retries + 1 ]} {

          after $retry_delay

      }

  }

  return -code error "cannot connect to all the candidate mail servers"

}

# Disconnect the given socket.

# Possible error raised:

# 1. $sock closed by remote server

proc ::cisco::lib::smtp_disconnect { sock } {

  smtp_write $sock "QUIT"

  if [catch {smtp_chk_reply $sock 221} result] {

        return -code error $result

  }

  return

}

# Given an email template file 'email_template' , substitute each global

# variables in the file by its user-defined value. Return the text of the

# file after substitution.

# Possible error raised:

# 1. cannot open email template file

# 2. cannot close email template file

proc ::cisco::lib::smtp_subst { f } {

  if [catch {open $f r} result] {

      return -code error "cannot open email template file: $result"

  } else {

      set fid $result

  }

  set stxt [read $fid]

  if [catch {close $fid} result] {

      return -code error "cannot close email template file: $result"

  }

  # using subst to replace optional args

  # need to eval on top level to get the values of user defined args

  set dtxt [uplevel #0 [list subst -nobackslashes -nocommands  $stxt]]

  return $dtxt

}

# already substituted, send the email out using SMTP protocol. The

# email template specifies the candidate mail server addresses, To

# addresses, Cc addresses, From address, subject line and email body.

# Possible error raised:

# 1. wrong 1st line format

#    usage: Mailservername:

# 2. wrong 2nd line format

#    usage: From:

# 3. wrong 3rd line format

#    usage: To:

# 4. wrong 4th line format

#    usage: Cc:

# 5. error connecting to mail server:

#    $sock closed by remote server

#    (where $sock is name of the socket opened to the mail server)

# 6. error connecting to mail server:

#    $sock status code is $k instead of 220

#    (where $sock is name of the socket opened to the mail server,

#          $k is the reply code of $sock)

# 7. error connecting to mail server:

#    cannot connect to all the candidate mail servers

# 8. Host name is not configured

# 9. Domain name is not configured

#10. Any of the error message for non-OK SMTP reply code.

#11. error disconnecting from mail server:

#    $sock closed by remote server

#    (where $sock is name of the socket opened to the mail server)

proc ::cisco::lib::smtp_send_email { etxt } {

  global _domainname _username _userpass

  regsub -all "\r\n" $etxt "\n" etxt

  set linelist [split $etxt \n]

  # Below, be sure that mailsvrline, fromline, toline and

  # ccline can't have leading or trailing spaces

  # 1st line must be "Mailservername: ..."

  set svrline [string trim [lindex $linelist 0]]

  set svrlist [split $svrline { }]

  set len [llength $svrlist]

  if { [lindex $svrlist 0] != "Mailservername:" } {

        return -code error "wrong 1st line format. \nusage: Mailservername: "

  }

  #delete the first item

  set svrlist [lreplace $svrlist 0 0]

  # 2nd line must be "From: ..."

  set fromline [string trim [lindex $linelist 1]]

  set fromlist [split $fromline { }]

  set len [llength $fromlist]

  if { [lindex $fromlist 0] != "From:" || $len != 2} {

        return -code error "wrong 2nd line format. \nusage: From: "

  }

  set smtpsender [lindex $fromlist 1]

  # 3th line must be "To:" list

  set toline [string trim [lindex $linelist 2]]

  set tolist [split $toline \ ,\t]

  if { [lindex $tolist 0] != "To:" } {

        return -code error "wrong 3rd line format. \nusage: To: "

  }

  # delete the first item

  set tolist [lreplace $tolist 0 0] 

  # 4th line must be "Cc:" list

  set ccline [string trim [lindex $linelist 3]]

  set cclist [split $ccline \ ,\t]

  if { [lindex $cclist 0] != "Cc:" } {

        return -code error "wrong 4th line format. \nusage: Cc: "

  }

  #delete the first item

  set cclist [lreplace $cclist 0 0] 

  # 5th line optional. Can be "Sourceaddr:" or "Sourceintf:"

  set srcline [string trim [lindex $linelist 4]]

  set srclist [split $srcline { }]

  set srcaddr ""

  set srcintf ""

  if { [lindex $srclist 0] == "Sourceaddr:" } {

      set srcaddr [lindex $srclist 1]

      set linelist [lreplace $linelist 4 4]

  } else {

      if { [lindex $srclist 0] == "Sourceintf:" } {

          set srcintf [lindex $srclist 1]

          set linelist [lreplace $linelist 4 4]

      }

  }

  # compute receiver list

  set dest_list [concat $tolist $cclist]

  # connect to the mail servers and get a useful socket

  if [catch {smtp_connect $svrlist $srcaddr $srcintf} result] {

                return -code error "error connecting to mail server:\n$result"

  } else {

            set ssock $result

  }

  # on this sock, send mail file to all the receivers

  set l [llength $dest_list]

  set k [llength $linelist]

  set hostname [info hostname]

  if {[string match "" $hostname]} {

    return -code error "Host name is not configured"

  }

  if {![info exists _domainname]} {

    return -code error "Domain name is not configured"

  }

  smtp_write $ssock "HELO $hostname.$_domainname"

  if [catch {smtp_chk_reply $ssock 250} result] {

return -code error $result

  }

  if {[string length $_username]} {

smtp_write $ssock "AUTH LOGIN $_username"

        if [catch {smtp_chk_reply $ssock 334} result] {

      return -code error $result

}

if {[string length $_userpass]} {

      smtp_write $ssock "$_userpass"

      if [catch {smtp_chk_reply $ssock 235} result] {

            return -code error $result

              }

}

  }

  smtp_write $ssock "MAIL FROM:<$smtpsender>"

  if [catch {smtp_chk_reply $ssock 250} result] {

        return -code error $result

  }

  for {set i 0} {$i < [ expr $l ]} {incr i} { 

    set smtprcver [lindex $dest_list $i]

    smtp_write $ssock "RCPT TO:<$smtprcver>"

    if [catch {smtp_chk_reply $ssock 250} result] {

        continue

    }

  }

  smtp_write $ssock "DATA"

  if [catch {smtp_chk_reply $ssock 354} result] {

        return -code error $result

  }

  # write the body

  # write the date line

  smtp_write $ssock "Date: [clock format [clock seconds] \

-format "%d %b %Y %H:%M:%S %Z"]"

  # construct message id and write the message id line

  # Even there are multiple smtp clients running, the possibility

  # of same message ids are rare because in message id, we get

  # the time since bootup precise to nsec.

  array set stamp_since_boot [::cisco::eem::fts_get_stamp]

  set time_str [clock format [clock seconds] -format "%Y%m%d%H%M%S"]

  append time_str "." $stamp_since_boot(nsec)

  smtp_write $ssock "Message-ID: <$time_str@$hostname.$_domainname>"

  set debugbuffer ""

  # write the subject, from, to, cc and message data

  for {set j 1} {$j < [ expr $k ]} {incr j} {

     smtp_write_nodebug $ssock [lindex $linelist $j]

     append debugbuffer [lindex $linelist $j]

     append debugbuffer "\n"

  }

  ::cisco::eem::smtp_debug "smtp_write" "$debugbuffer"

  smtp_write $ssock "."

  if [catch {smtp_chk_reply $ssock 250} result] {

        return -code error $result

  }

  if [catch {smtp_disconnect $ssock} result] {

return -code error "error disconnecting from mail server:\n$result"

  }

  return

}

This file

custom_smtp_lib.tcl

is located at flash:

Should I move it somewhere else?

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community:

Innovations in Cisco Full Stack Observability - A new webinar from Cisco