Patch title: Release 81 bulk changes
Abstract:
File: /pliant/appli/mail.pli
Key:
    Removed line
    Added line
   
module "/pliant/language/unsafe.pli"
module "/pliant/language/context.pli"
module "/pliant/language/stream.pli"
module "/pliant/admin/file.pli"
module "/pliant/fullpliant/this_computer.pli"
module "/pliant/fullpliant/user.pli"
module "/pliant/appli/mail/database.pli"
module "/pliant/protocol/smtp/mail.pli"
module "/pliant/protocol/smtp/meta.pli"
module "/pliant/protocol/smtp/forward.pli"
module "/pliant/protocol/smtp/spam.pli"
module "/pliant/protocol/http/server.pli"
module "/pliant/protocol/http/style/default.style"
module "/pliant/util/encoding/base64.pli"
module "/pliant/util/encoding/qp.pli"
module "/pliant/util/encoding/date.pli"
module "/pliant/util/encoding/neutral.pli"
module "/pliant/util/crypto/random.pli"
module "/pliant/language/schedule/resourcesem.pli"


function mail_send user area -> status
  arg Str user area ; arg Status status
  part build "build mail file"
    var Data:MailCurrent current :> mail_database2:data:curr
    var Data:MailBox m :> mailbox current:from
    if not exists:m
      return failure
    var DateTime timestamp := datetime
    timestamp split (var Int year) (var Int month) (var Int 
    var Str id := generate_id
    (var Stream s) open m:out_path+id+".tmp" out+cr+lf+safe+
    # console "sending message " user " in file " s:name eol
    var (Link Database:MailMeta) db :> new Database:MailMeta
    db load m:out_path+id+".pdb"
    var Data:MailMeta meta :> db data
    meta queued_on := timestamp
    var Str from := (mailbox current:from):name
    from := from+(shunt from<>"" " " "")+"<"+current:from+">
    s writeline "From: "+from
    meta from := from
    var Str tos := "" ; var Str ccs := ""
    each t current:target
      if t:box<>""
        if (t:box parse word:"all" any:(var Str keyword))
          each ubm user_database2:data:user:user:bookmark
            if ubm:mailbox<>"" and (keyword="" or (ubm:keywo
              var Str id2 := "b"+keyof:ubm
              var Str box2 := ubm:name+" <"+ubm:mailbox+">"
              meta:target create id2
              meta:target:id2:box := box2
              if t:mode<>"cc"
                tos += (shunt tos<>"" ",[lf]  " "")+box2
              else
                ccs += (shunt ccs<>"" ",[lf]  " "")+box2
        else
          var Str id2 := keyof t
          meta:target create id2
          meta:target:id2:box := t box
          if t:mode<>"cc"
            tos += (shunt tos<>"" ",[lf]  " "")+t:box
          else
            ccs += (shunt ccs<>"" ",[lf]  " "")+t:box
    if tos<>""
      s writeline "To: "+tos
    if ccs<>""
      s writeline "Cc: "+ccs
    s writeline "Subject: "+current:subject
    s writeline "Date: "+rfc1123_date:timestamp
module "/pliant/language/unsafe.pli"
module "/pliant/language/context.pli"
module "/pliant/language/stream.pli"
module "/pliant/admin/file.pli"
module "/pliant/fullpliant/this_computer.pli"
module "/pliant/fullpliant/user.pli"
module "/pliant/appli/mail/database.pli"
module "/pliant/protocol/smtp/mail.pli"
module "/pliant/protocol/smtp/meta.pli"
module "/pliant/protocol/smtp/forward.pli"
module "/pliant/protocol/smtp/spam.pli"
module "/pliant/protocol/http/server.pli"
module "/pliant/protocol/http/style/default.style"
module "/pliant/util/encoding/base64.pli"
module "/pliant/util/encoding/qp.pli"
module "/pliant/util/encoding/date.pli"
module "/pliant/util/encoding/neutral.pli"
module "/pliant/util/crypto/random.pli"
module "/pliant/language/schedule/resourcesem.pli"


function mail_send user area -> status
  arg Str user area ; arg Status status
  part build "build mail file"
    var Data:MailCurrent current :> mail_database2:data:curr
    var Data:MailBox m :> mailbox current:from
    if not exists:m
      return failure
    var DateTime timestamp := datetime
    timestamp split (var Int year) (var Int month) (var Int 
    var Str id := generate_id
    (var Stream s) open m:out_path+id+".tmp" out+cr+lf+safe+
    # console "sending message " user " in file " s:name eol
    var (Link Database:MailMeta) db :> new Database:MailMeta
    db load m:out_path+id+".pdb"
    var Data:MailMeta meta :> db data
    meta queued_on := timestamp
    var Str from := (mailbox current:from):name
    from := from+(shunt from<>"" " " "")+"<"+current:from+">
    s writeline "From: "+from
    meta from := from
    var Str tos := "" ; var Str ccs := ""
    each t current:target
      if t:box<>""
        if (t:box parse word:"all" any:(var Str keyword))
          each ubm user_database2:data:user:user:bookmark
            if ubm:mailbox<>"" and (keyword="" or (ubm:keywo
              var Str id2 := "b"+keyof:ubm
              var Str box2 := ubm:name+" <"+ubm:mailbox+">"
              meta:target create id2
              meta:target:id2:box := box2
              if t:mode<>"cc"
                tos += (shunt tos<>"" ",[lf]  " "")+box2
              else
                ccs += (shunt ccs<>"" ",[lf]  " "")+box2
        else
          var Str id2 := keyof t
          meta:target create id2
          meta:target:id2:box := t box
          if t:mode<>"cc"
            tos += (shunt tos<>"" ",[lf]  " "")+t:box
          else
            ccs += (shunt ccs<>"" ",[lf]  " "")+t:box
    if tos<>""
      s writeline "To: "+tos
    if ccs<>""
      s writeline "Cc: "+ccs
    s writeline "Subject: "+current:subject
    s writeline "Date: "+rfc1123_date:timestamp
    s writeline "Message-ID: <"+generate_id+"@"+computer_fullname+">"
    s writeline "X-Mailer: Pliant "+string:pliant_release_nu
    var Array:FileInfo attached := file_list mail_path+"atta
    if attached:size>0
      var Str boundary := (repeat 8 "-")
      for (var Int i) 1 (max 128\8\uInt:size 1)
        var uInt rnd ; memory_strong_random addressof:rnd In
        boundary += string rnd "radix 36"
      s writeline "MIME-Version: 1.0"
      s writeline "Content-Type: multipart/mixed; boundary=[
    s writeline ""
    if attached:size=0
      s writeline current:body
    else
      s writeline "This is a multi-part message in MIME form
      s writeline boundary
      s writeline "Content-Type: text/plain; charset=iso-885
      s writeline "Content-Transfer-Encoding: 8bit"
      s writeline ""
      s writeline current:body
      for (var Int i) 0 attached:size-1
        s writeline boundary
        s writeline "Content-Type: application/octet-stream;
        s writeline "Content-Transfer-Encoding: base64"
        s writeline "Content-Disposition: attachment; filena
        s writeline ""
        part attach "encode attached file"
          (var Stream a) open mail_path+"attach/"+user+"/"+a
          while not a:atend
            a read_available (var Address adr) (var Int step
            if step=54
              (var Str bytes) set adr step false
            else
              bytes set (memory_allocate step null) step tru
              memory_copy adr bytes:characters step
              while bytes:len<54 and not a:atend
                a read_available (var Address adr) (var Int 
                (var Str extra) set adr step false
                bytes += extra
            s writeline base64_encode:bytes
      s writeline boundary+"--"
    s close
    db store
  var Str apath := m:archive_path+string:year+(right string:
  file_tree_create apath
  if (file_clone m:out_path+id+".tmp" apath+id+".mail")=fail
    file_copy m:out_path+id+".tmp" apath+id+".mail"
  if area<>""
    if (file_clone m:out_path+id+".tmp" m:area_path+area+"/"
      file_copy m:out_path+id+".tmp" m:area_path+area+"/"+id
  file_move m:out_path+id+".tmp" m:out_path+id+".mail"
  file_directory_flush m:out_path+id+".mail"
  file_hook m:out_path+id+".mail"
  file_hook m:out_path+id+"pdb"
  forward_mails
  forward_mail m:out_path+id+".mail" true "forward a just po
  status := success



    s writeline "X-Mailer: Pliant "+string:pliant_release_nu
    var Array:FileInfo attached := file_list mail_path+"atta
    if attached:size>0
      var Str boundary := (repeat 8 "-")
      for (var Int i) 1 (max 128\8\uInt:size 1)
        var uInt rnd ; memory_strong_random addressof:rnd In
        boundary += string rnd "radix 36"
      s writeline "MIME-Version: 1.0"
      s writeline "Content-Type: multipart/mixed; boundary=[
    s writeline ""
    if attached:size=0
      s writeline current:body
    else
      s writeline "This is a multi-part message in MIME form
      s writeline boundary
      s writeline "Content-Type: text/plain; charset=iso-885
      s writeline "Content-Transfer-Encoding: 8bit"
      s writeline ""
      s writeline current:body
      for (var Int i) 0 attached:size-1
        s writeline boundary
        s writeline "Content-Type: application/octet-stream;
        s writeline "Content-Transfer-Encoding: base64"
        s writeline "Content-Disposition: attachment; filena
        s writeline ""
        part attach "encode attached file"
          (var Stream a) open mail_path+"attach/"+user+"/"+a
          while not a:atend
            a read_available (var Address adr) (var Int step
            if step=54
              (var Str bytes) set adr step false
            else
              bytes set (memory_allocate step null) step tru
              memory_copy adr bytes:characters step
              while bytes:len<54 and not a:atend
                a read_available (var Address adr) (var Int 
                (var Str extra) set adr step false
                bytes += extra
            s writeline base64_encode:bytes
      s writeline boundary+"--"
    s close
    db store
  var Str apath := m:archive_path+string:year+(right string:
  file_tree_create apath
  if (file_clone m:out_path+id+".tmp" apath+id+".mail")=fail
    file_copy m:out_path+id+".tmp" apath+id+".mail"
  if area<>""
    if (file_clone m:out_path+id+".tmp" m:area_path+area+"/"
      file_copy m:out_path+id+".tmp" m:area_path+area+"/"+id
  file_move m:out_path+id+".tmp" m:out_path+id+".mail"
  file_directory_flush m:out_path+id+".mail"
  file_hook m:out_path+id+".mail"
  file_hook m:out_path+id+"pdb"
  forward_mails
  forward_mail m:out_path+id+".mail" true "forward a just po
  status := success