Patch title: Release 90 bulk changes
Abstract:
File: /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/date.pli"
module "/pliant/util/encoding/http.pli"
module "/pliant/util/encoding/qp.pli"
module "/pliant/util/crypto/random.pli"
module "/pliant/language/schedule/resourcesem.pli"
module "/pliant/protocol/smtp/mime.pli"
module "/pliant/protocol/common/mime.pli"


method page mail_edit user
  arg_rw HtmlPage page ; arg Str user
  mail_database2:data:current create user
  var Data:MailCurrent current :> mail_database2:data:curren
  implicit page
    title "Send a mail"
    table columns 3 border 0
      cell [From]
      cell
        each umb user:user:mailbox
          if current:from=""
            current:from := umb
        select "" current:from
          each umb user:user:mailbox
            option umb umb
      cell void
      each t current:target
        if t:box<>"" and keyof:t<>""
          cell
            text t:mode
          cell
            text t:box
          cell
            button "Delete"
              current:target delete keyof:t
              reload_page
      current:target create ""
      cell
        select "" current:target:"":mode
          option "To" "to"
          option "Cc" "cc"
      cell
        var Str cvalue := current:target:"":box
        select "" current:target:"":box noeol
          option "" ""
          var CBool already := false
          each ubm user_database2:data:user:user:bookmark fi
            var Str blabel := (shunt ubm:first_name<>"" ubm:
            var Str bvalue := blabel+" <"+ubm:mailbox+">"
            option blabel bvalue
          if current:keyword<>""
            option "all "+current:keyword "all "+current:key
        input "" current:target:"":box length 30 noeol
      cell
        button "One more line"
          var Str id := string datetime:seconds
          current:target create id
          data_copy current:target:"" current:target:id
          current:target delete ""
          reload_page
      cell [Subject]
      cell
        input "" current:subject length 40
      cell void
    text_input "Message:[lf]" current:body columns 80 rows 2
    var Array:FileInfo files := file_list mail_path+"attach/
    if files:size>0
      var Intn total := 0
      table columns 3
        cell header [Attached file]
        cell header [Size in bytes]
        cell void
        for (var Int i) 0 files:size-1
          cell
            text files:i:name
          cell
            text (string files:i:size)
          cell
            var Str attached_file := files:i:name
            small
              button "discard"
                file_delete mail_path+"attach/"+user+"/"+att
                reload_page
          total += files:i:size
        cell header [Total]
        cell
          text string:total+" ("+(string (total+2^19)\2^20)+
        cell void
    file_upload "File name: " (var Str attach) noeol
    button "Attach the file"
      var Str remote := attach option "remote_name" Str
      file_move attach mail_path+"attach/"+user+"/"+remote
      reload_page
    para
      button "Reset the mail" noeol
        title "Reset the mail"
        [Are you sure you want to reset the mail content wit
        button "Yes" noeol
          mail_reset user
          goto_backward
        button "No"
          goto_backward
      button "Save the current content" noeol
        reload_page
      button "Preview then send"
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/date.pli"
module "/pliant/util/encoding/http.pli"
module "/pliant/util/encoding/qp.pli"
module "/pliant/util/crypto/random.pli"
module "/pliant/language/schedule/resourcesem.pli"
module "/pliant/protocol/smtp/mime.pli"
module "/pliant/protocol/common/mime.pli"


method page mail_edit user
  arg_rw HtmlPage page ; arg Str user
  mail_database2:data:current create user
  var Data:MailCurrent current :> mail_database2:data:curren
  implicit page
    title "Send a mail"
    table columns 3 border 0
      cell [From]
      cell
        each umb user:user:mailbox
          if current:from=""
            current:from := umb
        select "" current:from
          each umb user:user:mailbox
            option umb umb
      cell void
      each t current:target
        if t:box<>"" and keyof:t<>""
          cell
            text t:mode
          cell
            text t:box
          cell
            button "Delete"
              current:target delete keyof:t
              reload_page
      current:target create ""
      cell
        select "" current:target:"":mode
          option "To" "to"
          option "Cc" "cc"
      cell
        var Str cvalue := current:target:"":box
        select "" current:target:"":box noeol
          option "" ""
          var CBool already := false
          each ubm user_database2:data:user:user:bookmark fi
            var Str blabel := (shunt ubm:first_name<>"" ubm:
            var Str bvalue := blabel+" <"+ubm:mailbox+">"
            option blabel bvalue
          if current:keyword<>""
            option "all "+current:keyword "all "+current:key
        input "" current:target:"":box length 30 noeol
      cell
        button "One more line"
          var Str id := string datetime:seconds
          current:target create id
          data_copy current:target:"" current:target:id
          current:target delete ""
          reload_page
      cell [Subject]
      cell
        input "" current:subject length 40
      cell void
    text_input "Message:[lf]" current:body columns 80 rows 2
    var Array:FileInfo files := file_list mail_path+"attach/
    if files:size>0
      var Intn total := 0
      table columns 3
        cell header [Attached file]
        cell header [Size in bytes]
        cell void
        for (var Int i) 0 files:size-1
          cell
            text files:i:name
          cell
            text (string files:i:size)
          cell
            var Str attached_file := files:i:name
            small
              button "discard"
                file_delete mail_path+"attach/"+user+"/"+att
                reload_page
          total += files:i:size
        cell header [Total]
        cell
          text string:total+" ("+(string (total+2^19)\2^20)+
        cell void
    file_upload "File name: " (var Str attach) noeol
    button "Attach the file"
      var Str remote := attach option "remote_name" Str
      file_move attach mail_path+"attach/"+user+"/"+remote
      reload_page
    para
      button "Reset the mail" noeol
        title "Reset the mail"
        [Are you sure you want to reset the mail content wit
        button "Yes" noeol
          mail_reset user
          goto_backward
        button "No"
          goto_backward
      button "Save the current content" noeol
        reload_page
      button "Preview then send"
        goto_url "preview" no_extension
        var CBool some := false
        each t current:target
          if t:box<>""
            some := true
        if not some
          [You have not set any recipient for the mail !]
        else
          goto_url "preview" no_extension
    para
      input "Keyword: " current:keyword noeol
      button "Select bookmarks matching the keyword"
        reload_page
      


method page mail_display user box filename buttons back_leve
  arg_rw HtmlPage page ; arg Str user ; arg Data:MailBox box
  implicit page
    var CBool detailed := http_options="detailed"
    var Str subject
    var Str from
    var List:Str tos
    var List:Str ccs
    var Str date
    var List:Str extras
    var List:Str boundaries
    var CBool quoted := false
    var CBool spam := false
    (var Stream s) open filename in+safe+anyeol
    (var MimeStream ms) bind s true
    while (ms header_line (var Str l))
      if (l parse acword:"subject" ":" any:(var Str value))
        ms_decode value
        subject := value
      eif (l parse acword:"from" ":" any:(var Str value))
        ms_decode value
        from := value
      eif (l parse acword:"to" ":" any:(var Str value))
        ms_decode value
        tos += value
      eif (l parse acword:"cc" ":" any:(var Str value))
        ms_decode value
        ccs += value
      eif (l parse acword:"date" ":" any:(var Str value))
        date := value
      eif (l parse acword:"spam" any)
        spam := true
      if detailed
        extras += l
    table columns 1
      cell color (color hsl 60 5 75)
        table columns 2 border 0
          if from<>""
            cell [From:]
            cell
              if (from parse "[dq]" any:(var Str realname) "
                 bold text:realname ; text " <"+remain
              eif (from parse any:(var Str realname) "<" any
                 bold text:realname ; text "<"+remain
              else
                text from
          if (exists tos:first)
            cell [To:]
            cell
              var Pointer:Str to :> tos first
              while exists:to
                text to ; eol
                to :> tos next to
          if (exists ccs:first)
            cell [Cc:]
            cell
              var Pointer:Str cc :> ccs first
              while exists:cc
                text cc ; eol
                cc :> ccs next cc
          if subject<>""
            cell [Subject:]
            cell (bold text:subject)
          if date<>""
            cell [Date:]
            cell text:date
          cell void
          cell
            if http_options<>"detailed"
    para
      input "Keyword: " current:keyword noeol
      button "Select bookmarks matching the keyword"
        reload_page
      


method page mail_display user box filename buttons back_leve
  arg_rw HtmlPage page ; arg Str user ; arg Data:MailBox box
  implicit page
    var CBool detailed := http_options="detailed"
    var Str subject
    var Str from
    var List:Str tos
    var List:Str ccs
    var Str date
    var List:Str extras
    var List:Str boundaries
    var CBool quoted := false
    var CBool spam := false
    (var Stream s) open filename in+safe+anyeol
    (var MimeStream ms) bind s true
    while (ms header_line (var Str l))
      if (l parse acword:"subject" ":" any:(var Str value))
        ms_decode value
        subject := value
      eif (l parse acword:"from" ":" any:(var Str value))
        ms_decode value
        from := value
      eif (l parse acword:"to" ":" any:(var Str value))
        ms_decode value
        tos += value
      eif (l parse acword:"cc" ":" any:(var Str value))
        ms_decode value
        ccs += value
      eif (l parse acword:"date" ":" any:(var Str value))
        date := value
      eif (l parse acword:"spam" any)
        spam := true
      if detailed
        extras += l
    table columns 1
      cell color (color hsl 60 5 75)
        table columns 2 border 0
          if from<>""
            cell [From:]
            cell
              if (from parse "[dq]" any:(var Str realname) "
                 bold text:realname ; text " <"+remain
              eif (from parse any:(var Str realname) "<" any
                 bold text:realname ; text "<"+remain
              else
                text from
          if (exists tos:first)
            cell [To:]
            cell
              var Pointer:Str to :> tos first
              while exists:to
                text to ; eol
                to :> tos next to
          if (exists ccs:first)
            cell [Cc:]
            cell
              var Pointer:Str cc :> ccs first
              while exists:cc
                text cc ; eol
                cc :> ccs next cc
          if subject<>""
            cell [Subject:]
            cell (bold text:subject)
          if date<>""
            cell [Date:]
            cell text:date
          cell void
          cell
            if http_options<>"detailed"
              small (link "detailed header" "" options "deta
              small (link "detailed header" "" options "detailed" relative no_extension)
            if http_options<>"text"
            if http_options<>"text"
              fixed [ ] ; small (link "raw text" "" options 
              fixed [ ] ; small (link "raw text" "" options "text" relative no_extension)
            if (exists boundaries:first)
              fixed [ ] ; small [(this is a multipart messag
            fixed [ ]
            small
              if spam
                note "not a spam"
                  set_spam_mark filename false
                  reload_page
              else
                note "a spam"
                  set_spam_mark filename true
                  reload_page
            fixed [ ]
            small
              page note "spam rating"
            if (exists boundaries:first)
              fixed [ ] ; small [(this is a multipart messag
            fixed [ ]
            small
              if spam
                note "not a spam"
                  set_spam_mark filename false
                  reload_page
              else
                note "a spam"
                  set_spam_mark filename true
                  reload_page
            fixed [ ]
            small
              page note "spam rating"
                spam_load_dictionary (box smart_path "")+"sp
                var Float rating := spam_filter filename fil
                spam_load_dictionary (box smart_path "")+"spam_filter.txt" (var (Dictionary Str Float) filter) (var Float html_adust) (var Float suspicious_adjust) (var Float unknown_threshold) (var Float spam_threshold)
                var Float rating := spam_filter filename filter html_adust suspicious_adjust (var Str report)
                text "Spam probability for this mail is aval
                text "Spam probability for this mail is aval
                text "Your current unknown threshold is "+(s
                text "and your current spam threshold is "+(
                text "Your current unknown threshold for is "+(string unknown_threshold*100 "fixed 0")+"%, "
                text "and your current spam threshold is "+(string spam_threshold*100 "fixed 0")+"%, " ; eol
                text "so this one would be "+(shunt rating>s
                para
                  [Detailed spam filter report:] ; eol
                  fixed text:report
      cell
        if detailed
          small
            var Pointer:Str extra :> extras first
            while exists:extra
              text extra ; eol
              extra :> extras next extra
        if (buttons search "R" -1)<>(-1)
          button "reply" noeol
            mail_reply user keyof:box filename false
            goto_url (repeat back_level "../")+"send" no_ext
          button "reply to all" noeol
            mail_reply user keyof:box filename true
            goto_url (repeat back_level "../")+"send" no_ext
        if (buttons search "D" -1)<>(-1)
          button "delete" noeol
            file_delete filename
            file_hook filename
            goto_backward
        if (buttons search "B" -1)<>(-1)
          var Str mailbox := stripped_name from
          var (Data Set:UserBookmark) bookmark :> user_datab
          var CBool already := false
          each b2 bookmark
            if b2:mailbox=mailbox
              already := true
          if not already 
            page button "Add to bookmarks" noeol
              bookmark create mailbox
              var Data:UserBookmark b :> bookmark mailbox
              b name := smart_name from
              b mailbox := mailbox
              title "New bookmark"
              table columns 2
                cell [Name: ]
                cell (input "" b:name length 40)
                cell [Abstract: ]
                cell (text_input "" b:abstract columns 60 ro
                cell [Mailbox: ]
                cell (input "" b:mailbox length 40)
                cell [Home page / URL: ]
                cell (input "" b:url length 40)
                cell [Contact: ]
                cell (text_input "" b:contact columns 60 row
                cell [Keywords: ]
                cell (input "" b:keywords length 60)
              button "Record" noeol
                goto_backward
              button "Cancel bookmark creation"
                bookmark delete mailbox
                goto_backward
        if (buttons search "M" -1)<>(-1)
          var Array:FileInfo areas := file_list box:area_pat
          if areas:size<>0     
            fixed [  ]
            select "Area: " (var Str area) noeol
              for (var Int i) 0 areas:size-1
                var Str area := areas:i:name
                area := area 0 (area search "/" area:len)
                option area area
            button "move to area" noeol
              var Str base := filename (filename search_last
              file_move filename box:area_path+area+"/"+base
              goto_backward
    if http_options="text" or spam
      fixed
        (var Stream s) open filename in+safe
        while not s:atend
          s read_available (var Address adr) (var Int size) 
          (var Str chars) set adr size false
          text chars
    eif ms:html
      while (ms body_line l)
        html l
    eif  ms:multipart
      while (ms body_line l)
        void
      while not s:atend
        var List:Str extras := var List:Str empty_list
        ms bind s false
        while (ms header_line l)
          if detailed
            extras += l
        if ms:name<>""
          if ms:mime<>"application/applefile"
            table columns (shunt detailed 3 2)
              cell
                if (ms:name (ms:name search_last "." ms:name
                text "so this one would be "+(shunt rating>s
                para
                  [Detailed spam filter report:] ; eol
                  fixed text:report
      cell
        if detailed
          small
            var Pointer:Str extra :> extras first
            while exists:extra
              text extra ; eol
              extra :> extras next extra
        if (buttons search "R" -1)<>(-1)
          button "reply" noeol
            mail_reply user keyof:box filename false
            goto_url (repeat back_level "../")+"send" no_ext
          button "reply to all" noeol
            mail_reply user keyof:box filename true
            goto_url (repeat back_level "../")+"send" no_ext
        if (buttons search "D" -1)<>(-1)
          button "delete" noeol
            file_delete filename
            file_hook filename
            goto_backward
        if (buttons search "B" -1)<>(-1)
          var Str mailbox := stripped_name from
          var (Data Set:UserBookmark) bookmark :> user_datab
          var CBool already := false
          each b2 bookmark
            if b2:mailbox=mailbox
              already := true
          if not already 
            page button "Add to bookmarks" noeol
              bookmark create mailbox
              var Data:UserBookmark b :> bookmark mailbox
              b name := smart_name from
              b mailbox := mailbox
              title "New bookmark"
              table columns 2
                cell [Name: ]
                cell (input "" b:name length 40)
                cell [Abstract: ]
                cell (text_input "" b:abstract columns 60 ro
                cell [Mailbox: ]
                cell (input "" b:mailbox length 40)
                cell [Home page / URL: ]
                cell (input "" b:url length 40)
                cell [Contact: ]
                cell (text_input "" b:contact columns 60 row
                cell [Keywords: ]
                cell (input "" b:keywords length 60)
              button "Record" noeol
                goto_backward
              button "Cancel bookmark creation"
                bookmark delete mailbox
                goto_backward
        if (buttons search "M" -1)<>(-1)
          var Array:FileInfo areas := file_list box:area_pat
          if areas:size<>0     
            fixed [  ]
            select "Area: " (var Str area) noeol
              for (var Int i) 0 areas:size-1
                var Str area := areas:i:name
                area := area 0 (area search "/" area:len)
                option area area
            button "move to area" noeol
              var Str base := filename (filename search_last
              file_move filename box:area_path+area+"/"+base
              goto_backward
    if http_options="text" or spam
      fixed
        (var Stream s) open filename in+safe
        while not s:atend
          s read_available (var Address adr) (var Int size) 
          (var Str chars) set adr size false
          text chars
    eif ms:html
      while (ms body_line l)
        html l
    eif  ms:multipart
      while (ms body_line l)
        void
      while not s:atend
        var List:Str extras := var List:Str empty_list
        ms bind s false
        while (ms header_line l)
          if detailed
            extras += l
        if ms:name<>""
          if ms:mime<>"application/applefile"
            table columns (shunt detailed 3 2)
              cell
                if (ms:name (ms:name search_last "." ms:name
                  link ms:name ms:name options "html" no_ext
                  link ms:name ms:name options "html" relative no_extension
                else
                else
                  link ms:name ms:name no_extension
                  link ms:name ms:name relative no_extension
              cell
              cell
                small (link "view" ms:name options "text" no
                fixed [ ] ; small (link "download" ms:name o
                small (link "view" ms:name options "text" relative no_extension)
                fixed [ ] ; small (link "download" ms:name options "binary" relative no_extension)
              if detailed
                cell
                  small
                    var Pointer:Str extra :> extras first
                    while exists:extra
                      text extra ; eol
                      extra :> extras next extra
            while (ms body_line l)
              void
          else
            while (ms body_line l)
              void
        eif ms:mime="text/html"
          table columns 2 border 0
            cell color (color hsl 0 0 90)
              var CBool body := false ; var CBool nobody := 
              while (ms body_line l)
                if (l parse "<" word:"BODY" any ">" any:(var
                  l := remain ; body := true
                if (reverse:l parse (pattern reverse:"</HTML
                  l := reverse remain
                if (reverse:l parse (pattern reverse:"</BODY
                  l := reverse remain ; nobody := true
                if body
                  html l
                if nobody
                  body := false ; nobody := false
            cell color (color hsl 0 0 90)
              if detailed
                cell
                  small
                    var Pointer:Str extra :> extras first
                    while exists:extra
                      text extra ; eol
                      extra :> extras next extra
            while (ms body_line l)
              void
          else
            while (ms body_line l)
              void
        eif ms:mime="text/html"
          table columns 2 border 0
            cell color (color hsl 0 0 90)
              var CBool body := false ; var CBool nobody := 
              while (ms body_line l)
                if (l parse "<" word:"BODY" any ">" any:(var
                  l := remain ; body := true
                if (reverse:l parse (pattern reverse:"</HTML
                  l := reverse remain
                if (reverse:l parse (pattern reverse:"</BODY
                  l := reverse remain ; nobody := true
                if body
                  html l
                if nobody
                  body := false ; nobody := false
            cell color (color hsl 0 0 90)
              small (link "view" "" options "html" no_extens
              small (link "view" "" options "html" relative no_extension)
        else
          fixed
            while (ms body_line l)
              text l
    else
      fixed
        while (ms body_line l)
          text l


method page mail_list category box filepath subpath
  arg_rw HtmlPage page ; arg Str category ; arg Data:MailBox
  implicit page
    var Array:FileInfo files := file_list filepath standard+
    if files:size>0
      if exists:box  
        text upper:(category 0 1)+(category 1 category:len)+
      table columns 3
        cell header [From]
        cell header [Subject]
        cell void
        for (var Int i) 0 files:size-1
          if files:i:extension=".mail"
            var Str filename := filepath+files:i:name
            var Str from := "" ; var Str subject := ""
            (var Stream s) open filename in+safe+anyeol
            (var MimeStream ms) bind s true
            while (ms header_line (var Str l))
              if (l parse acword:"from" ":" any:(var Str fro
                ms_decode from1
                from := from1
              if (l parse acword:"subject" ":" any:(var Str 
                ms_decode subject1
                subject := subject1
            cell
              text smart_name:from
        else
          fixed
            while (ms body_line l)
              text l
    else
      fixed
        while (ms body_line l)
          text l


method page mail_list category box filepath subpath
  arg_rw HtmlPage page ; arg Str category ; arg Data:MailBox
  implicit page
    var Array:FileInfo files := file_list filepath standard+
    if files:size>0
      if exists:box  
        text upper:(category 0 1)+(category 1 category:len)+
      table columns 3
        cell header [From]
        cell header [Subject]
        cell void
        for (var Int i) 0 files:size-1
          if files:i:extension=".mail"
            var Str filename := filepath+files:i:name
            var Str from := "" ; var Str subject := ""
            (var Stream s) open filename in+safe+anyeol
            (var MimeStream ms) bind s true
            while (ms header_line (var Str l))
              if (l parse acword:"from" ":" any:(var Str fro
                ms_decode from1
                from := from1
              if (l parse acword:"subject" ":" any:(var Str 
                ms_decode subject1
                subject := subject1
            cell
              text smart_name:from
            if category="unknown mail"
              cell color (color hsl 60 50 80)
                link (shunt subject<>"" subject "no subject") subpath+files:i:stripped_name+"/" relative no_extension
            else
              cell
                link (shunt subject<>"" subject "no subject") subpath+files:i:stripped_name+"/" relative no_extension
            cell
            cell
              link (shunt subject<>"" subject "no subject") 
            cell
              small
                note "delete"
                  file_delete filename
                  file_hook filename
                  reload_page
                fixed [ ]
                if (subpath eparse "in/" any) and (reverse:f
                  note "a spam"
                    var Str spam := reverse:head+"/spam/"+re
                    file_tree_create spam
                    file_move filename spam
                    set_spam_mark spam true
                    file_hook filename
                    file_hook spam
                    reload_page
                eif ( (subpath eparse "unknown/" any) and (r
                  note "not a spam"
                    var Str normal := reverse:head+"/in/"+re
                    file_tree_create normal
                    file_move filename normal
                    set_spam_mark normal false
                    file_hook filename
                    file_hook normal
                    reload_page


method page mail_search user
  arg_rw HtmlPage page ; arg Str user
  var Data:MailCurrent current :> mail_database2:data:curren
  implicit page
    title "Search in the mail archives"
    table columns 2 border 0
      cell [From]
      cell (input "" (var Str from) length 30)
      cell [To/Cc]
      cell (input "" (var Str to) length 30)
      cell [Subject]
      cell (input "" (var Str subject) length 30)
      cell [Content]
      cell (text_input "" (var Str content) columns 30 rows 
      cell [Raw content]
      cell (text_input "" (var Str raw) columns 30 rows 3)
      cell [Days]
      var Int days := 30
      cell (input "" days length 5)
    button "Search now"
      part search "search mail archives"
        title "Mail archives search result"
        var Array:Str contents ; var Array:CBool content_oks
        while content<>""
          if not (content parse any:(var Str first) "[lf]" a
            first := content ; remain := ""
          if first<>""
            contents += lower first ; content_oks += false
          content := remain
        var Array:Str raws ; var Array:CBool raw_oks
        while raw<>""
          if not (raw parse any:(var Str first) "[lf]" any:(
            first := raw ; remain := ""
          if first<>""
            raws += lower first ; raw_oks += false
          raw := remain
        para
          [Search for mails:]
          list
            if from<>""
              item
                [containing] ; fixed (text " "+from+" ") ; [
            if to<>""
              item
                [containing] ; fixed (text " "+to+" ") ; [in
            if subject<>""
              item
                [containing] ; fixed (text " "+subject+" ") 
            for (var Int i) 0 contents:size-1
              item
                [containing] ; fixed (text " "+contents:i+" 
            for (var Int i) 0 raws:size-1
              item
                [containing] ; fixed (text " "+raws:i+" ") ;
            item
              [received at most] ; fixed (text " "+string:da
        table columns 4
          cell header [Date]
          cell header [From]
          cell header [To]
          cell header [Subject]
          var Date today := datetime date
          for (var Int j) days 0 step -1
            today-j split (var Int year) (var Int month) (va
            each umb user:user:mailbox
              var Data:MailBox m :> mailbox umb
              if exists:m and (keyof:m parse any:(var Str bo
                var Str apath := m:archive_path+string:year+
                var Array:FileInfo files := file_list apath 
                for (var Int i) 0 files:size-1
                  part scan_one "scan mail "+files:i:name
                    var Str from2 := "" ; var Str to2 := "" 
                    var CBool from_ok := false
                    var CBool to_ok := false
                    var CBool subject_ok := false
                    (var Stream s) open files:i:name in+safe
                    (var MimeStream ms) bind s true
                    while (ms header_line (var Str l))
                      if (l parse acword:"from" ":" any:(var
                        ms_decode value
                        if from<>"" and (lower:value search 
                          from_ok := true
                        from2 := value
                      eif (l parse acword:"to" ":" any:(var 
                        ms_decode value
                        if to<>"" and (lower:value search lo
                          to_ok := true
                        to2 += (shunt to2<>"" "," "")+value
                      eif (l parse acword:"subject" ":" any:
                        ms_decode value
                        if subject<>"" and (lower:value sear
                          subject_ok := true
                        subject2 := value
                    if (from<>"" and not from_ok) or (to<>""
                      leave scan_one
                    if contents:size>0
                      for (var Int u) 0 content_oks:size-1
                        content_oks u := false
                      if not ms:multipart
                        while (ms body_line l)
                          l := lower l
                          for (var Int u) 0 content_oks:size
                            if (l search contents:u -1)<>(-1
                              content_oks u := true
                      else
                        part scan_mime_parts
                          while (ms body_line l)
                            void
                          while not s:atend
                            ms bind s false
                            while (ms header_line l)
                              void
                            if ms:name="" and ms:mime="text/
                              while (ms body_line l)
                                l := lower l
                                for (var Int u) 0 content_ok
                                  if (l search contents:u -1
                                    content_oks u := true
                            eif ms:name<>""
                              leave scan_mime_parts
                            else
                              while (ms body_line l)
                                void
                      for (var Int u) 0 content_oks:size-1
                        if not content_oks:u
                          leave scan_one
                    if raws:size>0
                      for (var Int u) 0 raw_oks:size-1
                        raw_oks u := false
                      s configure "seek 0"
                      while not s:atend
                        var Str l := lower s:readline
                        for (var Int u) 0 raw_oks:size-1
                          if (l search raws:u -1)<>(-1)
                            raw_oks u := true
                      for (var Int u) 0 raw_oks:size-1
                        if not raw_oks:u
                          leave scan_one
                    cell
                      text (string today-j)
                    cell
                      text smart_name:from2
                    cell
                      small
                        while to2<>""
                          if not (to2 parse any:(var Str val
                            value := to2 ; remain := ""
                          text smart_name:value ; eol
                          to2 := remain
                    cell
              small
                note "delete"
                  file_delete filename
                  file_hook filename
                  reload_page
                fixed [ ]
                if (subpath eparse "in/" any) and (reverse:f
                  note "a spam"
                    var Str spam := reverse:head+"/spam/"+re
                    file_tree_create spam
                    file_move filename spam
                    set_spam_mark spam true
                    file_hook filename
                    file_hook spam
                    reload_page
                eif ( (subpath eparse "unknown/" any) and (r
                  note "not a spam"
                    var Str normal := reverse:head+"/in/"+re
                    file_tree_create normal
                    file_move filename normal
                    set_spam_mark normal false
                    file_hook filename
                    file_hook normal
                    reload_page


method page mail_search user
  arg_rw HtmlPage page ; arg Str user
  var Data:MailCurrent current :> mail_database2:data:curren
  implicit page
    title "Search in the mail archives"
    table columns 2 border 0
      cell [From]
      cell (input "" (var Str from) length 30)
      cell [To/Cc]
      cell (input "" (var Str to) length 30)
      cell [Subject]
      cell (input "" (var Str subject) length 30)
      cell [Content]
      cell (text_input "" (var Str content) columns 30 rows 
      cell [Raw content]
      cell (text_input "" (var Str raw) columns 30 rows 3)
      cell [Days]
      var Int days := 30
      cell (input "" days length 5)
    button "Search now"
      part search "search mail archives"
        title "Mail archives search result"
        var Array:Str contents ; var Array:CBool content_oks
        while content<>""
          if not (content parse any:(var Str first) "[lf]" a
            first := content ; remain := ""
          if first<>""
            contents += lower first ; content_oks += false
          content := remain
        var Array:Str raws ; var Array:CBool raw_oks
        while raw<>""
          if not (raw parse any:(var Str first) "[lf]" any:(
            first := raw ; remain := ""
          if first<>""
            raws += lower first ; raw_oks += false
          raw := remain
        para
          [Search for mails:]
          list
            if from<>""
              item
                [containing] ; fixed (text " "+from+" ") ; [
            if to<>""
              item
                [containing] ; fixed (text " "+to+" ") ; [in
            if subject<>""
              item
                [containing] ; fixed (text " "+subject+" ") 
            for (var Int i) 0 contents:size-1
              item
                [containing] ; fixed (text " "+contents:i+" 
            for (var Int i) 0 raws:size-1
              item
                [containing] ; fixed (text " "+raws:i+" ") ;
            item
              [received at most] ; fixed (text " "+string:da
        table columns 4
          cell header [Date]
          cell header [From]
          cell header [To]
          cell header [Subject]
          var Date today := datetime date
          for (var Int j) days 0 step -1
            today-j split (var Int year) (var Int month) (va
            each umb user:user:mailbox
              var Data:MailBox m :> mailbox umb
              if exists:m and (keyof:m parse any:(var Str bo
                var Str apath := m:archive_path+string:year+
                var Array:FileInfo files := file_list apath 
                for (var Int i) 0 files:size-1
                  part scan_one "scan mail "+files:i:name
                    var Str from2 := "" ; var Str to2 := "" 
                    var CBool from_ok := false
                    var CBool to_ok := false
                    var CBool subject_ok := false
                    (var Stream s) open files:i:name in+safe
                    (var MimeStream ms) bind s true
                    while (ms header_line (var Str l))
                      if (l parse acword:"from" ":" any:(var
                        ms_decode value
                        if from<>"" and (lower:value search 
                          from_ok := true
                        from2 := value
                      eif (l parse acword:"to" ":" any:(var 
                        ms_decode value
                        if to<>"" and (lower:value search lo
                          to_ok := true
                        to2 += (shunt to2<>"" "," "")+value
                      eif (l parse acword:"subject" ":" any:
                        ms_decode value
                        if subject<>"" and (lower:value sear
                          subject_ok := true
                        subject2 := value
                    if (from<>"" and not from_ok) or (to<>""
                      leave scan_one
                    if contents:size>0
                      for (var Int u) 0 content_oks:size-1
                        content_oks u := false
                      if not ms:multipart
                        while (ms body_line l)
                          l := lower l
                          for (var Int u) 0 content_oks:size
                            if (l search contents:u -1)<>(-1
                              content_oks u := true
                      else
                        part scan_mime_parts
                          while (ms body_line l)
                            void
                          while not s:atend
                            ms bind s false
                            while (ms header_line l)
                              void
                            if ms:name="" and ms:mime="text/
                              while (ms body_line l)
                                l := lower l
                                for (var Int u) 0 content_ok
                                  if (l search contents:u -1
                                    content_oks u := true
                            eif ms:name<>""
                              leave scan_mime_parts
                            else
                              while (ms body_line l)
                                void
                      for (var Int u) 0 content_oks:size-1
                        if not content_oks:u
                          leave scan_one
                    if raws:size>0
                      for (var Int u) 0 raw_oks:size-1
                        raw_oks u := false
                      s configure "seek 0"
                      while not s:atend
                        var Str l := lower s:readline
                        for (var Int u) 0 raw_oks:size-1
                          if (l search raws:u -1)<>(-1)
                            raw_oks u := true
                      for (var Int u) 0 raw_oks:size-1
                        if not raw_oks:u
                          leave scan_one
                    cell
                      text (string today-j)
                    cell
                      text smart_name:from2
                    cell
                      small
                        while to2<>""
                          if not (to2 parse any:(var Str val
                            value := to2 ; remain := ""
                          text smart_name:value ; eol
                          to2 := remain
                    cell
                      link (shunt subject2<>"" subject2 "no 
                      link (shunt subject2<>"" subject2 "no subject") "archive/"+domain+"/"+box+"/"+string:year+(right string:month 2 "0")+"/"+(right string:day 2 "0")+"/"+files:i:stripped_name+"/" relative no_extension
    para
      [A search on the raw content is slow.]
                


method page set_spam_filter user
  arg_rw HtmlPage page ; arg Str user
  implicit page
    title "Set the spam filter"
    var Str box := "all"
    select "Set spam filter for " box
      each umb user:user:mailbox
        option "mailbox "+umb umb
      option "all mailboxes" "all"
    var Int days := 120
    input "studying " days length 3 noeol ; [ days mail arch
    para
      [A search on the raw content is slow.]
                


method page set_spam_filter user
  arg_rw HtmlPage page ; arg Str user
  implicit page
    title "Set the spam filter"
    var Str box := "all"
    select "Set spam filter for " box
      each umb user:user:mailbox
        option "mailbox "+umb umb
      option "all mailboxes" "all"
    var Int days := 120
    input "studying " days length 3 noeol ; [ days mail arch
    var Float html_adjust100 := 50
    input "assuming HTML mails spam probablity is " html_adjust100 length 4 noeol ; [%] ; eol
    var Float suspicious_adjust100 := 50
    input "and suspicious mails spam probability is " suspicious_adjust100 length 4 noeol ; [%] ; eol
    var Float unknown_threshold100 := 50
    input "using an unknown threshold of " unknown_threshold
    var Float spam_threshold100 := 90
    input "and a spam threshold of " spam_threshold100 lengt
    var Int vdays := 120
    input "then test the filter against " vdays length 3 noe
    page button "set spam filter" noeol
      var Array:Str mailboxes paths
      each umb1 user:user:mailbox
        var Data:MailBox m1 :> mailbox umb1
        if exists:m1 and (keyof:m1=box or box="all")
          mailboxes += keyof m1 ; paths += m1 archive_path
      var Str temp := file_temporary
      var DateTime since := datetime ; since seconds -= days
    var Float unknown_threshold100 := 50
    input "using an unknown threshold of " unknown_threshold
    var Float spam_threshold100 := 90
    input "and a spam threshold of " spam_threshold100 lengt
    var Int vdays := 120
    input "then test the filter against " vdays length 3 noe
    page button "set spam filter" noeol
      var Array:Str mailboxes paths
      each umb1 user:user:mailbox
        var Data:MailBox m1 :> mailbox umb1
        if exists:m1 and (keyof:m1=box or box="all")
          mailboxes += keyof m1 ; paths += m1 archive_path
      var Str temp := file_temporary
      var DateTime since := datetime ; since seconds -= days
      spam_study paths since unknown_threshold100/100 spam_t
      spam_study paths since html_adjust100/100 suspicious_adjust100/100 unknown_threshold100/100 spam_threshold100/100 temp
      for (var Int i) 0 mailboxes:size-1
        var Data:MailBox m1 :> mailbox mailboxes:i
        file_copy temp (m1 smart_path "")+"spam_filter.txt"
        file_delete (m1 smart_path "")+"spam_ip.txt" # old o
        file_delete (m1 smart_path "")+"spam_word.txt"
      for (var Int i) 0 mailboxes:size-1
        var Data:MailBox m1 :> mailbox mailboxes:i
        file_copy temp (m1 smart_path "")+"spam_filter.txt"
        file_delete (m1 smart_path "")+"spam_ip.txt" # old o
        file_delete (m1 smart_path "")+"spam_word.txt"
      spam_load_dictionary temp (var (Dictionary Str Float) 
      spam_load_dictionary temp (var (Dictionary Str Float) filter) (var Float html_adjust) (var Float suspicious_adjust) (var Float unknown_threshold) (var Float spam_threshold)
      file_delete temp
      var DateTime since := datetime ; since seconds -= vday
      var Int count := 0
      for (var Int p) 0 paths:size-1
        var Array:FileInfo files := file_list paths:p standa
        for (var Int i) 0 files:size-1
          if files:i:datetime>=since
            count += 1
      var Int spam_rejected := 0 ; var Int spam_unknown := 0
      var Int valid_rejected := 0 ; var Int valid_unknown :=
      table columns 5
        cell header [Date]
        cell header [From]
        cell header [To]
        cell header [Subject]
        cell header [Rating]
        var Int current := 0
        for (var Int p) 0 paths:size-1
          var Array:FileInfo files := file_list paths:p stan
          for (var Int i) 0 files:size-1
            if files:i:datetime>=since
              current += 1
              part test "test mail filter "+string:current+"
                (var Stream s) open paths:p+files:i:name in+
                var CBool spam := s:readline parse acword:"s
                s close
      file_delete temp
      var DateTime since := datetime ; since seconds -= vday
      var Int count := 0
      for (var Int p) 0 paths:size-1
        var Array:FileInfo files := file_list paths:p standa
        for (var Int i) 0 files:size-1
          if files:i:datetime>=since
            count += 1
      var Int spam_rejected := 0 ; var Int spam_unknown := 0
      var Int valid_rejected := 0 ; var Int valid_unknown :=
      table columns 5
        cell header [Date]
        cell header [From]
        cell header [To]
        cell header [Subject]
        cell header [Rating]
        var Int current := 0
        for (var Int p) 0 paths:size-1
          var Array:FileInfo files := file_list paths:p stan
          for (var Int i) 0 files:size-1
            if files:i:datetime>=since
              current += 1
              part test "test mail filter "+string:current+"
                (var Stream s) open paths:p+files:i:name in+
                var CBool spam := s:readline parse acword:"s
                s close
                var Float rating := spam_filter paths:p+file
                var Float rating := spam_filter paths:p+files:i:name filter html_adjust suspicious_adjust (var Str report)
                var Int level := shunt rating>spam_threshold
                if spam
                  if level>0
                    spam_rejected += 1
                  eif level=0
                    spam_unknown += 1
                  else
                    spam_accepted += 1
                else
                  if level>0
                    valid_rejected += 1
                  eif level=0
                    valid_unknown += 1
                  else
                    valid_accepted += 1
                if (spam and level<0) or (not spam and level
                  var Str from2 := "" ; var Str to2 := "" ; 
                  (var Stream s) open paths:p+files:i:name i
                  (var MimeStream ms) bind s true
                  while (ms header_line (var Str l))
                    if (l parse acword:"from" ":" any:(var S
                      ms_decode value
                      from2 := value
                    eif (l parse acword:"to" ":" any:(var St
                      ms_decode value
                      to2 += (shunt to2<>"" "," "")+value
                    eif (l parse acword:"subject" ":" any:(v
                      ms_decode value
                      subject2 := value
                  cell
                    text (string files:i:datetime:date)
                  cell
                    text smart_name:from2
                  cell
                    small
                      while to2<>""
                        if not (to2 parse any:(var Str value
                          value := to2 ; remain := ""
                        text smart_name:value ; eol
                        to2 := remain
                  cell color (color hsl (shunt level>0 and n
                    if (mailboxes:p parse any:(var Str mailb
                var Int level := shunt rating>spam_threshold
                if spam
                  if level>0
                    spam_rejected += 1
                  eif level=0
                    spam_unknown += 1
                  else
                    spam_accepted += 1
                else
                  if level>0
                    valid_rejected += 1
                  eif level=0
                    valid_unknown += 1
                  else
                    valid_accepted += 1
                if (spam and level<0) or (not spam and level
                  var Str from2 := "" ; var Str to2 := "" ; 
                  (var Stream s) open paths:p+files:i:name i
                  (var MimeStream ms) bind s true
                  while (ms header_line (var Str l))
                    if (l parse acword:"from" ":" any:(var S
                      ms_decode value
                      from2 := value
                    eif (l parse acword:"to" ":" any:(var St
                      ms_decode value
                      to2 += (shunt to2<>"" "," "")+value
                    eif (l parse acword:"subject" ":" any:(v
                      ms_decode value
                      subject2 := value
                  cell
                    text (string files:i:datetime:date)
                  cell
                    text smart_name:from2
                  cell
                    small
                      while to2<>""
                        if not (to2 parse any:(var Str value
                          value := to2 ; remain := ""
                        text smart_name:value ; eol
                        to2 := remain
                  cell color (color hsl (shunt level>0 and n
                    if (mailboxes:p parse any:(var Str mailb
                      link (shunt subject2<>"" subject2 "no 
                      link (shunt subject2<>"" subject2 "no subject") "archive/"+domain+"/"+mailbox+"/"+(replace files:i:name ".mail" "")+"/" options "text" relative no_extension
                    else
                      text (shunt subject2<>"" subject2 "no 
                  cell
                    text (string 100*rating "fixed 0")+"%"
      var Int total := spam_rejected+spam_unknown+spam_accep
      para
        text "Rejected spams: "
        font color (color hsl 120 100 50)
          text (string 100.0*spam_rejected/total "fixed 0")+
        text " ("+string:spam_rejected+")" ; eol
        text "Unknown spams: "
        font color (color hsl 240 100 50)
          text (string 100.0*spam_unknown/total "fixed 0")+"
        text " ("+string:spam_unknown+")" ; eol
        text "Accepted spams: "
        font color (color hsl 60 100 50)
          text (string 100.0*spam_accepted/total "fixed 0")+
        text" ("+string:spam_accepted+")" ; eol
      para
        text "Rejected valid mails: "
        font color (color hsl 0 100 50)
          text (string 100.0*valid_rejected/total "fixed 0")
        text " ("+string:valid_rejected+")" ; eol
        text "Unknown valid mails: "
        font color (color hsl 240 100 50)
          text (string 100.0*valid_unknown/total "fixed 0")+
        text " ("+string:valid_unknown+")" ; eol
        text "Accepted valid mails: "
        font color (color hsl 120 100 50)
          text (string 100.0*valid_accepted/total "fixed 0")
        text " ("+string:valid_accepted+")" ; eol
    page button "remove spam filter"
      var Array:Str mailboxes paths
      each umb2 user:user:mailbox
        var Data:MailBox m2 :> mailbox umb2
        if exists:m2 and (keyof:m2=box or box="all")
          file_delete (m2 smart_path "")+"spam_filter.txt"
          file_delete (m2 smart_path "")+"spam_ip.txt"
          file_delete (m2 smart_path "")+"spam_word.txt"
      goto_backward
    para
      [A threshold of 50% will probably reject all spams, bu
      [A threshold of 99% will reject very fiew valid mails.
      [The optimal value depends on the kind of mails you re



method page mail path http_options
  arg_rw HtmlPage page ; arg Str path http_options
  implicit page
    requires "mail"
    if path="/"
      mail_list user_name
      para
        link "send a mail" "send" no_extension ; eol
        link "search in the archives" "search" no_extension 
      para
        each umb user:user_name:mailbox
          var Data:MailBox m :> mailbox umb
          if (keyof:m parse any:(var Str box) "@" any:(var S
            var Array:FileInfo areas := file_list m:area_pat
            if areas:size<>0
              [Areas for mailbox] ; fixed (text " "+keyof:m)
            for (var Int i) 0 areas:size-1
              var Str area := areas:i:name
              area := area 0 (area search "/" area:len)
                    else
                      text (shunt subject2<>"" subject2 "no 
                  cell
                    text (string 100*rating "fixed 0")+"%"
      var Int total := spam_rejected+spam_unknown+spam_accep
      para
        text "Rejected spams: "
        font color (color hsl 120 100 50)
          text (string 100.0*spam_rejected/total "fixed 0")+
        text " ("+string:spam_rejected+")" ; eol
        text "Unknown spams: "
        font color (color hsl 240 100 50)
          text (string 100.0*spam_unknown/total "fixed 0")+"
        text " ("+string:spam_unknown+")" ; eol
        text "Accepted spams: "
        font color (color hsl 60 100 50)
          text (string 100.0*spam_accepted/total "fixed 0")+
        text" ("+string:spam_accepted+")" ; eol
      para
        text "Rejected valid mails: "
        font color (color hsl 0 100 50)
          text (string 100.0*valid_rejected/total "fixed 0")
        text " ("+string:valid_rejected+")" ; eol
        text "Unknown valid mails: "
        font color (color hsl 240 100 50)
          text (string 100.0*valid_unknown/total "fixed 0")+
        text " ("+string:valid_unknown+")" ; eol
        text "Accepted valid mails: "
        font color (color hsl 120 100 50)
          text (string 100.0*valid_accepted/total "fixed 0")
        text " ("+string:valid_accepted+")" ; eol
    page button "remove spam filter"
      var Array:Str mailboxes paths
      each umb2 user:user:mailbox
        var Data:MailBox m2 :> mailbox umb2
        if exists:m2 and (keyof:m2=box or box="all")
          file_delete (m2 smart_path "")+"spam_filter.txt"
          file_delete (m2 smart_path "")+"spam_ip.txt"
          file_delete (m2 smart_path "")+"spam_word.txt"
      goto_backward
    para
      [A threshold of 50% will probably reject all spams, bu
      [A threshold of 99% will reject very fiew valid mails.
      [The optimal value depends on the kind of mails you re



method page mail path http_options
  arg_rw HtmlPage page ; arg Str path http_options
  implicit page
    requires "mail"
    if path="/"
      mail_list user_name
      para
        link "send a mail" "send" no_extension ; eol
        link "search in the archives" "search" no_extension 
      para
        each umb user:user_name:mailbox
          var Data:MailBox m :> mailbox umb
          if (keyof:m parse any:(var Str box) "@" any:(var S
            var Array:FileInfo areas := file_list m:area_pat
            if areas:size<>0
              [Areas for mailbox] ; fixed (text " "+keyof:m)
            for (var Int i) 0 areas:size-1
              var Str area := areas:i:name
              area := area 0 (area search "/" area:len)
              link area "area/"+domain+"/"+box+"/"+area+"/"
              link area "area/"+domain+"/"+box+"/"+area+"/" relative
              var Int n := (file_list m:area_path+areas:i:na
              if n>0
                fixed [  ] ; small (text string:n+" mail"+(s
              eol
      para
        link "edit your bookmarks" "bookmarks" no_extension 
        link "create a new area" "create_area" no_extension
        fixed [ ] ; link "delete an area" "delete_area" no_e
        link "set auto answer messages" "auto_answer" no_ext
        each umb user:user_name:mailbox
          var Data:MailBox m :> mailbox umb
          if m:auto_answer<>""
            fixed [ ] ; highlight keyof:m
        eol 
        link "set spams filter" "spam_filter" no_extension ;
      spam_list user_name
    eif path="/send"
      mail_edit user_name
    eif path="/preview"
      mail_preview user_name
    eif path="/search"
      mail_search user_name
    eif path="/bookmarks"
      mail_bookmarks user_name
    eif path="/create_area"
      mail_create_area user_name
    eif path="/delete_area"
      mail_delete_area user_name
    eif path="/spam_filter"
      set_spam_filter user_name
    eif path="/auto_answer"
      set_auto_answer_messages user_name
    eif (path parse "/in/" any:(var Str domain) "/" any:(var
      var Data:MailBox b :> mailbox box+"@"+domain
      var Str filename := b:in_path+id+".mail"
      if part<>"" or http_options="html"
        send_mime_part filename part http_options false
      else
        mail_display user_name b filename "RBMD" 4 http_opti
    eif (path parse "/unknown/" any:(var Str domain) "/" any
      var Data:MailBox b :> mailbox box+"@"+domain
      var Str filename := b:unknown_path+id+".mail"
      if part<>"" or http_options="html"
        send_mime_part filename part http_options false
      else
        mail_display user_name b filename "RBMD" 4 http_opti
    eif (path parse "/spam/" any:(var Str domain) "/" any:(v
      var Data:MailBox b :> mailbox box+"@"+domain
      var Str filename := b:spam_path+id+".mail"
      if part<>"" or http_options="html"
        send_mime_part filename part http_options false
      else
        mail_display user_name b filename "RBMD" 4 http_opti
    eif (path parse "/area/" any:(var Str domain) "/" any:(v
      var Data:MailBox b :> mailbox box+"@"+domain
      if (remain parse any:(var Str id) "/"  any:(var Str pa
        var Str filename := b:area_path+area+"/"+id+".mail"
        if part<>"" or http_options="html"
          send_mime_part filename part http_options false
        else
          mail_display user_name b filename "RBMD" 5 http_op
      else
        title "'"+area+"' area"
        mail_list "mail" (var Data:MailBox no_box) b:area_pa
    eif (path parse "/archive/" any:(var Str domain) "/" any
      var Data:MailBox b :> mailbox box+"@"+domain
      var Str filename := b:archive_path+month+"/"+day+"/"+i
      if part<>"" or http_options="html"
        send_mime_part filename part http_options false
      else
        mail_display user_name b filename "RB" 6 http_option



              var Int n := (file_list m:area_path+areas:i:na
              if n>0
                fixed [  ] ; small (text string:n+" mail"+(s
              eol
      para
        link "edit your bookmarks" "bookmarks" no_extension 
        link "create a new area" "create_area" no_extension
        fixed [ ] ; link "delete an area" "delete_area" no_e
        link "set auto answer messages" "auto_answer" no_ext
        each umb user:user_name:mailbox
          var Data:MailBox m :> mailbox umb
          if m:auto_answer<>""
            fixed [ ] ; highlight keyof:m
        eol 
        link "set spams filter" "spam_filter" no_extension ;
      spam_list user_name
    eif path="/send"
      mail_edit user_name
    eif path="/preview"
      mail_preview user_name
    eif path="/search"
      mail_search user_name
    eif path="/bookmarks"
      mail_bookmarks user_name
    eif path="/create_area"
      mail_create_area user_name
    eif path="/delete_area"
      mail_delete_area user_name
    eif path="/spam_filter"
      set_spam_filter user_name
    eif path="/auto_answer"
      set_auto_answer_messages user_name
    eif (path parse "/in/" any:(var Str domain) "/" any:(var
      var Data:MailBox b :> mailbox box+"@"+domain
      var Str filename := b:in_path+id+".mail"
      if part<>"" or http_options="html"
        send_mime_part filename part http_options false
      else
        mail_display user_name b filename "RBMD" 4 http_opti
    eif (path parse "/unknown/" any:(var Str domain) "/" any
      var Data:MailBox b :> mailbox box+"@"+domain
      var Str filename := b:unknown_path+id+".mail"
      if part<>"" or http_options="html"
        send_mime_part filename part http_options false
      else
        mail_display user_name b filename "RBMD" 4 http_opti
    eif (path parse "/spam/" any:(var Str domain) "/" any:(v
      var Data:MailBox b :> mailbox box+"@"+domain
      var Str filename := b:spam_path+id+".mail"
      if part<>"" or http_options="html"
        send_mime_part filename part http_options false
      else
        mail_display user_name b filename "RBMD" 4 http_opti
    eif (path parse "/area/" any:(var Str domain) "/" any:(v
      var Data:MailBox b :> mailbox box+"@"+domain
      if (remain parse any:(var Str id) "/"  any:(var Str pa
        var Str filename := b:area_path+area+"/"+id+".mail"
        if part<>"" or http_options="html"
          send_mime_part filename part http_options false
        else
          mail_display user_name b filename "RBMD" 5 http_op
      else
        title "'"+area+"' area"
        mail_list "mail" (var Data:MailBox no_box) b:area_pa
    eif (path parse "/archive/" any:(var Str domain) "/" any
      var Data:MailBox b :> mailbox box+"@"+domain
      var Str filename := b:archive_path+month+"/"+day+"/"+i
      if part<>"" or http_options="html"
        send_mime_part filename part http_options false
      else
        mail_display user_name b filename "RB" 6 http_option