Patch title: Release 92 bulk changes
Abstract:
File: /protocol/smtp/server.pli
Key:
    Removed line
    Added line
   
abstract
  [This is Pliant SMTP server implementation (RFC 821)]


method smtp service s
  arg_rw SmtpServer smtp ; arg_rw Stream s
  var SmtpSession session
  session:log bind smtp_trace
  session remote_ip := s query "remote_ip_address"
  var DateTime timestamp := datetime
  timestamp split (var Int year) (var Int month) (var Int da
  session:log trace "SMTP connection start at " timestamp " 
  part dialog "SMTP connection from "+session:remote_ip+" (s
    each ip mail_database:data:magic_ip
      if (session:remote_ip is_inside_ip_domain keyof:ip)
        session remote_magic := true
    if not session:remote_magic
      each ip mail_database:data:black_ip
        if (session:remote_ip is_inside_ip_domain keyof:ip)
          s writeline "559 you are blacklisted on this site.
          session:log trace "remote IP is blacklisted on thi
          leave dialog
      if (session:remote_ip parse (var Int ip1) "." (var Int
        each dns mail_database:data:black_dns
          if (dns_query string:ip4+"."+string:ip3+"."+string
            s writeline "559 you are blacklisted on "+keyof:
            session:log trace "remote IP is blacklisted on "
            leave dialog
    session local_name := this_computer:env:"pliant":"mail":
    if session:local_name=""
      session local_name := computer_fullname
    s writeline "220 "+session:local_name+" Simple Mail Tran
    session:log trace "welcome 220 "+session:local_name+" Si
    while not s:atend
      var Str l := s readline
      session:log trace "query " l
      if (l parse any:(var Str first) _ any:(var Str second2
        l := upper:first+" "+upper:second2+":"+remain
      eif (l parse any:(var Str first) _ any:(var Str remain
        l := upper:first+" "+remain
      else
        l := upper l
      var Str a
      if (l parse word:"HELO" (any session:remote_name))
        if exists:(mail_database:data:magic_name session:rem
          session remote_magic := true
          session welcome := true
        eif exists:(mail_database:data:black_name session:re
          session welcome := false
        else
          session welcome := true
        a := shunt session:welcome "250 "+session:local_name
        session reset
        plugin command_helo
      eif (l parse word:"MAIL" word:"FROM" ":" any:(var Str 
        var Str from2 := ac_real_email from
        if exists:(mail_database:data:magic_from from2)
          session magic := true
        eif exists:(mail_database:data:black_from from2)
          session rejected := true
        from2 := from2 (from2 search "@" from2:len)+1 from2:
        if exists:(mail_database:data:magic_from from2)
          session magic := true
        eif exists:(mail_database:data:black_from from2)
          session rejected := true
        var Data:MailBox b :> mailbox real_email:from
        if not exists:b
          b :> mailbox ac_real_email:from
        if not session:welcome or session:rejected
          a := "550 No mail will be accepted here"
        eif session:from<>""
          session rejected := true
          a := "503 Bad sequence of commands"
        eif computer_fullname=b:computer and b:smtp_ip<>"" a
          # out mail from the mailbox owner
          session from := from
          session outmail := b out_path
          var Pointer:SmtpFile file :> session add_file b:ou
          file forward := true
          if b:archive and session:remote_name<>computer_ful
            session add_file b:archive_path+string:year+(rig
          session check_from_to b
          a := "250 OK"
        eif computer_fullname=b:relay_computer and session:r
          # out mail in the relay computer from the mailbox 
          session from := from
          session outmail := b relay_path
          var Pointer:SmtpFile file :> session add_file b:re
          file forward := true
          if b:relay_archive and session:remote_name<>comput
            session add_file b:archive_path+string:year+(rig
          session check_from_to b
          a := "250 OK"
        else
          session from := from
          a := "250 OK"
        plugin command_from
      eif (l parse word:"RCPT" word:"TO" ":" any:(var Str to
        var Data:MailBox b :> mailbox real_email:to
        if not exists:b
          b :> mailbox ac_real_email:to
        if not session:welcome or session:rejected
          a := "550 No mail will be accepted here"
        eif computer_fullname=b:computer
          if b:list
            # mailing list
            session accepted := true
            if b:subscriber:size>0
              var Pointer:SmtpFile file :> session add_file 
              each ms b:subscriber
                file to += ms
              file forward := true
              file push := true
            if b:archive
              session add_file b:archive_path+string:year+(r
            session check_from_to b
            a := "250 OK"
          else
            # in mail
            session accepted := true
            session add_file b:in_path+session:id to
            if b:archive
              session add_file b:archive_path+string:year+(r
            session check_from_to b
            if use_spam_filter and (file_query (b smart_path
              session spam_filters += (b smart_path "")+"spa
            a := "250 OK"
            if b:auto_answer<>""
              session auto_to += " "+b:name+" <"+keyof:b+">"
        eif computer_fullname=b:relay_computer
          # in mail in the relay computer
          session accepted := true
          var Pointer:SmtpFile file :> session add_file b:re
          file to += to
          file forward := true
          if b:relay_archive
            session add_file b:archive_path+string:year+(rig
          session check_from_to b
          a := "250 OK"
          if b:auto_answer<>""
            session auto_to += " "+b:name+" <"+keyof:b+">" ;
        eif session:outmail<>""
          if session:remote_name<>computer_fullname
            session accepted := true
            var Pointer:SmtpFile file :> session add_file se
            file to += to
            a := "250 OK"
          else
            a := "550 the target mailbox is probably wrong (
        else
          a := "550 Mails to "+to+" are not accepted here"
        plugin command_to
      eif l="DATA"
        if not session:welcome or session:rejected
          a := "550 No mail will be accepted here"
        eif not session:accepted
          a := "503 Bad sequence of commands"
        else
          a := session receive_mail s
          if a="250 OK" and session:auto_answer<>"" and sess
abstract
  [This is Pliant SMTP server implementation (RFC 821)]


method smtp service s
  arg_rw SmtpServer smtp ; arg_rw Stream s
  var SmtpSession session
  session:log bind smtp_trace
  session remote_ip := s query "remote_ip_address"
  var DateTime timestamp := datetime
  timestamp split (var Int year) (var Int month) (var Int da
  session:log trace "SMTP connection start at " timestamp " 
  part dialog "SMTP connection from "+session:remote_ip+" (s
    each ip mail_database:data:magic_ip
      if (session:remote_ip is_inside_ip_domain keyof:ip)
        session remote_magic := true
    if not session:remote_magic
      each ip mail_database:data:black_ip
        if (session:remote_ip is_inside_ip_domain keyof:ip)
          s writeline "559 you are blacklisted on this site.
          session:log trace "remote IP is blacklisted on thi
          leave dialog
      if (session:remote_ip parse (var Int ip1) "." (var Int
        each dns mail_database:data:black_dns
          if (dns_query string:ip4+"."+string:ip3+"."+string
            s writeline "559 you are blacklisted on "+keyof:
            session:log trace "remote IP is blacklisted on "
            leave dialog
    session local_name := this_computer:env:"pliant":"mail":
    if session:local_name=""
      session local_name := computer_fullname
    s writeline "220 "+session:local_name+" Simple Mail Tran
    session:log trace "welcome 220 "+session:local_name+" Si
    while not s:atend
      var Str l := s readline
      session:log trace "query " l
      if (l parse any:(var Str first) _ any:(var Str second2
        l := upper:first+" "+upper:second2+":"+remain
      eif (l parse any:(var Str first) _ any:(var Str remain
        l := upper:first+" "+remain
      else
        l := upper l
      var Str a
      if (l parse word:"HELO" (any session:remote_name))
        if exists:(mail_database:data:magic_name session:rem
          session remote_magic := true
          session welcome := true
        eif exists:(mail_database:data:black_name session:re
          session welcome := false
        else
          session welcome := true
        a := shunt session:welcome "250 "+session:local_name
        session reset
        plugin command_helo
      eif (l parse word:"MAIL" word:"FROM" ":" any:(var Str 
        var Str from2 := ac_real_email from
        if exists:(mail_database:data:magic_from from2)
          session magic := true
        eif exists:(mail_database:data:black_from from2)
          session rejected := true
        from2 := from2 (from2 search "@" from2:len)+1 from2:
        if exists:(mail_database:data:magic_from from2)
          session magic := true
        eif exists:(mail_database:data:black_from from2)
          session rejected := true
        var Data:MailBox b :> mailbox real_email:from
        if not exists:b
          b :> mailbox ac_real_email:from
        if not session:welcome or session:rejected
          a := "550 No mail will be accepted here"
        eif session:from<>""
          session rejected := true
          a := "503 Bad sequence of commands"
        eif computer_fullname=b:computer and b:smtp_ip<>"" a
          # out mail from the mailbox owner
          session from := from
          session outmail := b out_path
          var Pointer:SmtpFile file :> session add_file b:ou
          file forward := true
          if b:archive and session:remote_name<>computer_ful
            session add_file b:archive_path+string:year+(rig
          session check_from_to b
          a := "250 OK"
        eif computer_fullname=b:relay_computer and session:r
          # out mail in the relay computer from the mailbox 
          session from := from
          session outmail := b relay_path
          var Pointer:SmtpFile file :> session add_file b:re
          file forward := true
          if b:relay_archive and session:remote_name<>comput
            session add_file b:archive_path+string:year+(rig
          session check_from_to b
          a := "250 OK"
        else
          session from := from
          a := "250 OK"
        plugin command_from
      eif (l parse word:"RCPT" word:"TO" ":" any:(var Str to
        var Data:MailBox b :> mailbox real_email:to
        if not exists:b
          b :> mailbox ac_real_email:to
        if not session:welcome or session:rejected
          a := "550 No mail will be accepted here"
        eif computer_fullname=b:computer
          if b:list
            # mailing list
            session accepted := true
            if b:subscriber:size>0
              var Pointer:SmtpFile file :> session add_file 
              each ms b:subscriber
                file to += ms
              file forward := true
              file push := true
            if b:archive
              session add_file b:archive_path+string:year+(r
            session check_from_to b
            a := "250 OK"
          else
            # in mail
            session accepted := true
            session add_file b:in_path+session:id to
            if b:archive
              session add_file b:archive_path+string:year+(r
            session check_from_to b
            if use_spam_filter and (file_query (b smart_path
              session spam_filters += (b smart_path "")+"spa
            a := "250 OK"
            if b:auto_answer<>""
              session auto_to += " "+b:name+" <"+keyof:b+">"
        eif computer_fullname=b:relay_computer
          # in mail in the relay computer
          session accepted := true
          var Pointer:SmtpFile file :> session add_file b:re
          file to += to
          file forward := true
          if b:relay_archive
            session add_file b:archive_path+string:year+(rig
          session check_from_to b
          a := "250 OK"
          if b:auto_answer<>""
            session auto_to += " "+b:name+" <"+keyof:b+">" ;
        eif session:outmail<>""
          if session:remote_name<>computer_fullname
            session accepted := true
            var Pointer:SmtpFile file :> session add_file se
            file to += to
            a := "250 OK"
          else
            a := "550 the target mailbox is probably wrong (
        else
          a := "550 Mails to "+to+" are not accepted here"
        plugin command_to
      eif l="DATA"
        if not session:welcome or session:rejected
          a := "550 No mail will be accepted here"
        eif not session:accepted
          a := "503 Bad sequence of commands"
        else
          a := session receive_mail s
          if a="250 OK" and session:auto_answer<>"" and sess
            console "auto answering to " session:from eol
            (var Stream answer) open "smtp:"+session:auto_fr
            answer writeline "Here is an automatic answer re
            answer writeline ""
            answer writechars session:auto_answer
            answer close  
          session reset
      eif pattern_matching and (l parse word:"VRFY" any:(var
        var Data:MailBox b :> mailbox real_email:pattern
        if exists:b
          a := "250 "+b:name+" <"+keyof:b+">"
        else
          var Int count := 0
          each b mailbox
            if ((lower b:name+" <"+keyof:b+">") search lower
              count += 1
              a := "250 "+b:name+" <"+keyof:b+">"
          if count=0
            a := "550 String does not match anything"
          eif count>1
            a := "553 User ambiguous"
        plugin command_vrfy
      eif l="RSET"
        session reset
        a := "250 OK"
      eif l="NOOP"
        a := "250 OK"
      eif l="QUIT"
        a := "221 "+session:local_name+" Service closing tra
      else
        a := "502 Command not implemented"
        plugin not_implemented
      s writeline a
      session:log trace "answer " a
      if l="QUIT"
        leave dialog
  session:log trace "SMTP connection stop at " datetime " fr
  


            (var Stream answer) open "smtp:"+session:auto_fr
            answer writeline "Here is an automatic answer re
            answer writeline ""
            answer writechars session:auto_answer
            answer close  
          session reset
      eif pattern_matching and (l parse word:"VRFY" any:(var
        var Data:MailBox b :> mailbox real_email:pattern
        if exists:b
          a := "250 "+b:name+" <"+keyof:b+">"
        else
          var Int count := 0
          each b mailbox
            if ((lower b:name+" <"+keyof:b+">") search lower
              count += 1
              a := "250 "+b:name+" <"+keyof:b+">"
          if count=0
            a := "550 String does not match anything"
          eif count>1
            a := "553 User ambiguous"
        plugin command_vrfy
      eif l="RSET"
        session reset
        a := "250 OK"
      eif l="NOOP"
        a := "250 OK"
      eif l="QUIT"
        a := "221 "+session:local_name+" Service closing tra
      else
        a := "502 Command not implemented"
        plugin not_implemented
      s writeline a
      session:log trace "answer " a
      if l="QUIT"
        leave dialog
  session:log trace "SMTP connection stop at " datetime " fr