Patch title: Release 85 bulk changes
Abstract:
File: /pliant/appli/file_browser.pli
Key:
    Removed line
    Added line
   
module "/pliant/protocol/http/server.pli"
module "/pliant/protocol/http/style/default.style"
module "/pliant/protocol/common/mime.pli"
module "/pliant/language/context.pli"
module "/pliant/language/compiler.pli"
module "/pliant/language/stream.pli"
module "/pliant/admin/file.pli"
module "/pliant/admin/execute.pli"
module "/pliant/protocol/http/server.pli"
module "/pliant/protocol/http/style/default.style"
module "/pliant/protocol/common/mime.pli"
module "/pliant/language/context.pli"
module "/pliant/language/compiler.pli"
module "/pliant/language/stream.pli"
module "/pliant/admin/file.pli"
module "/pliant/admin/execute.pli"
module "/pliant/util/encoding/neutral.pli"
module "/pliant/util/encoding/http.pli"
module "/pliant/protocol/http/webdav.pli"



plugin timeout
  constant tar_timeout 3600 # the downgrade.tgz should be pa
  constant upgrade_timeout 7200 # the downgrade.tgz should h



plugin timeout
  constant tar_timeout 3600 # the downgrade.tgz should be pa
  constant upgrade_timeout 7200 # the downgrade.tgz should h



method page apply_uploaded_file src dest fileoptions0
  arg_rw HtmlPage page ; arg Str src dest fileoptions0
method page apply_uploaded_file src dest fileoptions0 -> status
  arg_rw HtmlPage page ; arg Str src dest fileoptions0 ; arg Status status
  var Str ext := dest (dest search "." dest:len) dest:len
  if ext=".pdb" and (data_file_switch src dest)=success
  var Str ext := dest (dest search "." dest:len) dest:len
  if ext=".pdb" and (data_file_switch src dest)=success
    return
    return success
  if fullpliant and ext=".tgz" and file_os_name:dest=file_os
    file_delete "file:/boot/downgrade.tgz"  
    execute "pliant module /pliant/fullpliant/recover.pli co
    var Float remain := tar_timeout
    while remain>0 and (file_query "file:/boot/downgrade.tgz
      sleep 1
    if remain>0
      var Array:FileInfo files := file_list "file:/pliant/bi
      for (var Int i) 0 files:size-1
        if files:i:extension=".dump"
          file_delete files:i:name
      file_move src dest
      file_extract dest "file:/"
      file_delete dest
      page shutdown 120 "restart"
  eif fullpliant and ext=".tgz" and file_os_name:dest=file_o
    var Array:FileInfo files := file_list "file:/pliant/bina
    for (var Int i) 0 files:size-1
      if files:i:extension=".dump"
        file_delete files:i:name
    file_move src dest
    file_extract dest "file:/"
    file_delete dest
    page shutdown 120 "restart"
  eif fullpliant and os_api="linux" and ext=".tgz" and (file
    var Array:FileInfo files := file_list "file:/pliant/bina
    for (var Int i) 0 files:size-1
      if files:i:extension=".dump"
        file_delete files:i:name
    file_move src dest
    page shutdown 120 ""
    file_move "security:/" "file:/pliant_security.backup/"
    file_extract dest "file:/"
    file_tree_delete "security:/"
    file_move "file:/pliant_security.backup/" "security:/"
    pliant_load_module "/pliant/appli/file_browser/lilo.pli"
    if file_os_name:dest=file_os_name:"file:/boot/kernel.tgz
      file_tree_delete "file:/sbin/"
      file_tree_delete "file:/etc/"
      file_tree_delete "file:/usr/"
      file_tree_delete "file:/var/"
      file_delete "file:/boot/modules.tgz"
      file_move dest "file:/boot/modules.tgz"
    else
      file_delete dest
    kernel_shutdown true
  var Str fileoptions := shunt fileoptions0<>"" fileoptions0
  if fullpliant and ext=".tgz" and file_os_name:dest=file_os
    file_delete "file:/boot/downgrade.tgz"  
    execute "pliant module /pliant/fullpliant/recover.pli co
    var Float remain := tar_timeout
    while remain>0 and (file_query "file:/boot/downgrade.tgz
      sleep 1
    if remain>0
      var Array:FileInfo files := file_list "file:/pliant/bi
      for (var Int i) 0 files:size-1
        if files:i:extension=".dump"
          file_delete files:i:name
      file_move src dest
      file_extract dest "file:/"
      file_delete dest
      page shutdown 120 "restart"
  eif fullpliant and ext=".tgz" and file_os_name:dest=file_o
    var Array:FileInfo files := file_list "file:/pliant/bina
    for (var Int i) 0 files:size-1
      if files:i:extension=".dump"
        file_delete files:i:name
    file_move src dest
    file_extract dest "file:/"
    file_delete dest
    page shutdown 120 "restart"
  eif fullpliant and os_api="linux" and ext=".tgz" and (file
    var Array:FileInfo files := file_list "file:/pliant/bina
    for (var Int i) 0 files:size-1
      if files:i:extension=".dump"
        file_delete files:i:name
    file_move src dest
    page shutdown 120 ""
    file_move "security:/" "file:/pliant_security.backup/"
    file_extract dest "file:/"
    file_tree_delete "security:/"
    file_move "file:/pliant_security.backup/" "security:/"
    pliant_load_module "/pliant/appli/file_browser/lilo.pli"
    if file_os_name:dest=file_os_name:"file:/boot/kernel.tgz
      file_tree_delete "file:/sbin/"
      file_tree_delete "file:/etc/"
      file_tree_delete "file:/usr/"
      file_tree_delete "file:/var/"
      file_delete "file:/boot/modules.tgz"
      file_move dest "file:/boot/modules.tgz"
    else
      file_delete dest
    kernel_shutdown true
  var Str fileoptions := shunt fileoptions0<>"" fileoptions0
  var FileInfo old := file_query dest extended
  if (file_move src dest)=failure
  status := file_move src dest
  if status=failure
    file_delete dest
    file_delete dest
    file_move src dest
    status := file_move src dest
  file_configure dest fileoptions



method page browse_directory path options write
  arg_rw HtmlPage page ; arg Str path options ; arg CBool wr
  implicit page
    if options="delete" and write
      [Are you sure that you want to delete directory] ; fix
      button "yes" noeol
        file_tree_delete path
        goto_backward
      button "no"
        goto_backward
    eif options="list"
      var Array:FileInfo files := file_list path standard+re
      for (var Int i) 0 files:size-1
        html "<pfile name=[dq]"+(html_encode files:i:name)+"
    else
  file_configure dest fileoptions



method page browse_directory path options write
  arg_rw HtmlPage page ; arg Str path options ; arg CBool wr
  implicit page
    if options="delete" and write
      [Are you sure that you want to delete directory] ; fix
      button "yes" noeol
        file_tree_delete path
        goto_backward
      button "no"
        goto_backward
    eif options="list"
      var Array:FileInfo files := file_list path standard+re
      for (var Int i) 0 files:size-1
        html "<pfile name=[dq]"+(html_encode files:i:name)+"
    else
      head "<meta name=[dq]robots[dq] content=[dq]noindex,nofollow[dq]>[lf]"
      var CBool detailed := (options option "detailed") and 
      title path
      table columns 2 border 0
        cell [Path:]
        cell (fixed text:path)
      if not detailed and allowed:"administrator"
        link "compute disk usage" "./" options "detailed"
      var Array:FileInfo files := file_list path standard+re
      var Int total_count := 0 ; var Intn total_size := 0 
      table columns (shunt detailed 6 5)
        cell header
          bold [name]
        if detailed
          cell header
            bold [count]
        cell header
          bold [size]
        cell header
          bold [date ]
          note "*"
            title "Pliant date format"
            [The date is displayed using] ; fixed [ ] ; ital
        cell header
          void
        cell header
          void
        for (var Int i) 0 files:size-1
          var Pointer:FileInfo f :> files i
          html "<pfile name=[dq]"+(html_encode f:name)+"[dq]
          if f:is_directory
            cell
              bold
      var CBool detailed := (options option "detailed") and 
      title path
      table columns 2 border 0
        cell [Path:]
        cell (fixed text:path)
      if not detailed and allowed:"administrator"
        link "compute disk usage" "./" options "detailed"
      var Array:FileInfo files := file_list path standard+re
      var Int total_count := 0 ; var Intn total_size := 0 
      table columns (shunt detailed 6 5)
        cell header
          bold [name]
        if detailed
          cell header
            bold [count]
        cell header
          bold [size]
        cell header
          bold [date ]
          note "*"
            title "Pliant date format"
            [The date is displayed using] ; fixed [ ] ; ital
        cell header
          void
        cell header
          void
        for (var Int i) 0 files:size-1
          var Pointer:FileInfo f :> files i
          html "<pfile name=[dq]"+(html_encode f:name)+"[dq]
          if f:is_directory
            cell
              bold
                link f:name (neutral_encode f:name)
                link f:name (replace (http_encode f:name) "%2F" "/")
            if detailed
              path_size path+f:name (var Int count) (var Int
              cell
                italic (text string:count)
              cell
                if (options option "byte")
                  italic (text string:size)
                else
                  italic (text (string size\2^20)+" MB")
              total_count += count ; total_size += size
            else
              cell void
            cell void
            cell
              small
                if (file_list path+f:name standard+directori
            if detailed
              path_size path+f:name (var Int count) (var Int
              cell
                italic (text string:count)
              cell
                if (options option "byte")
                  italic (text string:size)
                else
                  italic (text (string size\2^20)+" MB")
              total_count += count ; total_size += size
            else
              cell void
            cell void
            cell
              small
                if (file_list path+f:name standard+directori
                  link "delete" (neutral_encode f:name) opti
                  link "delete" (http_encode f:name) no_extension options "delete"
            cell void
          else
            cell
            cell void
          else
            cell
              # link f:name neutral_encode:(shunt f:extensio
              link f:name (neutral_encode f:name) no_extensi
              link f:name (http_encode f:name) no_extension
            if detailed
              cell void
            cell
              text (string f:size "separated [dq]"+character
            cell
              text (string f:datetime)
            cell
              small
                var Str mime := query_mime_type f:extension
                if not (mime parse "binary/" any) and not (m
            if detailed
              cell void
            cell
              text (string f:size "separated [dq]"+character
            cell
              text (string f:datetime)
            cell
              small
                var Str mime := query_mime_type f:extension
                if not (mime parse "binary/" any) and not (m
                  link "view" (neutral_encode f:name) no_ext
                  link "view" (http_encode f:name) no_extension options "view" ; fixed [ ]
                  if write
                  if write
                    link "edit" (neutral_encode f:name) no_e
                link "download" (neutral_encode f:name) no_e
                    link "edit" (http_encode f:name) no_extension options "edit" ; fixed [ ]
                link "download" (http_encode f:name) no_extension options "download" ; fixed [ ] 
                if write
                if write
                  link "copy" (neutral_encode f:name) no_ext
                  link "delete" (neutral_encode f:name) no_e
                  link "copy" (http_encode f:name) no_extension options "copy" ; fixed [ ] 
                  link "delete" (http_encode f:name) no_extension options "delete"
            cell
              var Str vp := virtual_path
              virtual_path := path+f:name
              execute_dynamic_page "pliant:/pliant/appli/fil
              virtual_path := vp
            total_count += 1 ; total_size += f size
        if detailed
          cell header
            [total]
          cell
            italic (text string:total_count)
          cell
            if (options option "byte")
              italic (text string:total_size)
            else
              italic (text (string total_size\2^20)+" MB")
          cell void
          cell void
          cell void
      if write
        file_upload "" (var Str filename) noeol
        button "Upload"
          if (file_query filename standard)=defined
            var Str remote := filename option "remote_name" 
            if remote<>""
              apply_uploaded_file filename path+remote ""
              reload_page
            else
              [I have not received the file name !]
          else
            [I have not received the file !]
            para
              [The explaination might be that your browser d
              [If you wonder what browsers supports uploadin
        input "" (var Str filename2) noeol
        button "Create file" noeol
          (var Stream s) open path+filename2 out+safe ; s cl
          reload_page
        button "Create directory"
          file_tree_create path+filename2+"/"
          reload_page
        # input "Target computer: " (var Str target) noeol
        # input "Password: " (var Str passwd) password noeol
        # button "Synchronize"
        #   void
      table columns 1
        cell
          table columns 2 border 0
            cell
              input "Name pattern: " (var Str name_pattern)
              if allowed:"administrator"
                input "Content pattern: " (var Str content_p
                select "Case sensitive: " (var Str case_sens
                  option "no" ""
                  option "yes" "yes"
            cell
              button "Search"
                title "Files search report"
                table columns 2 border 0
                  cell [Path:]
                  cell (fixed text:path)
                  if name_pattern<>""
                    cell [Name pattern:]
                    cell (fixed text:name_pattern)
                  if content_pattern<>""
                    cell [Content pattern:]
                    cell (fixed text:content_pattern)
                var Array:FileInfo all_files := file_list pa
                var CBool case := case_sensitive="yes"
                if content_pattern<>"" and allowed:"administ
                  table columns 2
                    for (var Int i) 0 all_files:size-1
                      if name_pattern="" or (all_files:i:nam
                        (var Stream s) open path+all_files:i
                        while not s:atend
                          var Str l := s readline
                          var CBool matching
                          if case
                            matching := (l search content_pa
                          else
                            matching := (upper:l search uppe
                          if matching
                            cell
                              link all_files:i:name all_file
                            cell
                              small
                                fixed text:l ; eol
                                while not s:atend
                                  var Str l := s readline
                                  if case
                                    matching := (l search co
                                  else
                                    matching := (upper:l sea
                                  if matching
                                    fixed text:l ; eol
                else
                  for (var Int i) 0 all_files:size-1
                    if name_pattern="" or (all_files:i:name_
                      link all_files:i:name all_files:i:path



method page file_browser path options write
  arg_rw HtmlPage page ; arg Str path options ; arg CBool wr
  implicit page
            cell
              var Str vp := virtual_path
              virtual_path := path+f:name
              execute_dynamic_page "pliant:/pliant/appli/fil
              virtual_path := vp
            total_count += 1 ; total_size += f size
        if detailed
          cell header
            [total]
          cell
            italic (text string:total_count)
          cell
            if (options option "byte")
              italic (text string:total_size)
            else
              italic (text (string total_size\2^20)+" MB")
          cell void
          cell void
          cell void
      if write
        file_upload "" (var Str filename) noeol
        button "Upload"
          if (file_query filename standard)=defined
            var Str remote := filename option "remote_name" 
            if remote<>""
              apply_uploaded_file filename path+remote ""
              reload_page
            else
              [I have not received the file name !]
          else
            [I have not received the file !]
            para
              [The explaination might be that your browser d
              [If you wonder what browsers supports uploadin
        input "" (var Str filename2) noeol
        button "Create file" noeol
          (var Stream s) open path+filename2 out+safe ; s cl
          reload_page
        button "Create directory"
          file_tree_create path+filename2+"/"
          reload_page
        # input "Target computer: " (var Str target) noeol
        # input "Password: " (var Str passwd) password noeol
        # button "Synchronize"
        #   void
      table columns 1
        cell
          table columns 2 border 0
            cell
              input "Name pattern: " (var Str name_pattern)
              if allowed:"administrator"
                input "Content pattern: " (var Str content_p
                select "Case sensitive: " (var Str case_sens
                  option "no" ""
                  option "yes" "yes"
            cell
              button "Search"
                title "Files search report"
                table columns 2 border 0
                  cell [Path:]
                  cell (fixed text:path)
                  if name_pattern<>""
                    cell [Name pattern:]
                    cell (fixed text:name_pattern)
                  if content_pattern<>""
                    cell [Content pattern:]
                    cell (fixed text:content_pattern)
                var Array:FileInfo all_files := file_list pa
                var CBool case := case_sensitive="yes"
                if content_pattern<>"" and allowed:"administ
                  table columns 2
                    for (var Int i) 0 all_files:size-1
                      if name_pattern="" or (all_files:i:nam
                        (var Stream s) open path+all_files:i
                        while not s:atend
                          var Str l := s readline
                          var CBool matching
                          if case
                            matching := (l search content_pa
                          else
                            matching := (upper:l search uppe
                          if matching
                            cell
                              link all_files:i:name all_file
                            cell
                              small
                                fixed text:l ; eol
                                while not s:atend
                                  var Str l := s readline
                                  if case
                                    matching := (l search co
                                  else
                                    matching := (upper:l sea
                                  if matching
                                    fixed text:l ; eol
                else
                  for (var Int i) 0 all_files:size-1
                    if name_pattern="" or (all_files:i:name_
                      link all_files:i:name all_files:i:path



method page file_browser path options write
  arg_rw HtmlPage page ; arg Str path options ; arg CBool wr
  implicit page
    if path:len>0 and (path path:len-1)="/"
      browse_directory neutral_decode:path options write
    var Str answer := ""
    if virtual_command="GET" or virtual_command="POST"
      if path:len>0 and (path path:len-1)="/"
        browse_directory http_decode:path options write
      else
        browse_file http_decode:path options write
    eif virtual_command="HEAD"
      var FileInfo info := file_query http_decode:path extended
      if info=success
        reset_http_answer
        if not info:is_directory
          http_request answer_size := info size
          http_request answer_datetime := info datetime
        http_request answer_is_dynamic := false
        http_request send_header
        http_request send_footer
      else
        answer := "404 Not found"
    eif virtual_command="PUT"
      if not write
        reset_http_answer
        http_request send_authentification_request
        return
      var Str opt := ""
      var Pointer:Arrow c :> http_request:query_log first
      while c<>null
        var Pointer:Str s :> c map Str
        if (s parse word:"Pliant-Options" ":" any:(var Str value))
          opt := http_decode value
        c :> http_request:query_log next c
      var Str temp := file_temporary
      http_request read_data_file undefined temp
      answer := shunt (apply_uploaded_file temp http_decode:path opt)=success "200 OK" "500 Could not write file"
      file_delete temp
    eif virtual_command="OPTIONS"
      answer := "200 OK"
      http_request:answer_extra append addressof:(new Str "Allow: OPTIONS, PROPFIND, MKCOL")
      http_request:answer_extra append addressof:(new Str "DAV: 1")
    eif virtual_command="PROPFIND"
      var Str slash ; var FileInfo info
      if path:len=0 or (path path:len-1)<>"/"
        slash := "/"
        info := file_query http_decode:path+slash extended
        if info=failure
          slash := ""
          info := file_query http_decode:path extended
      else
        slash := ""
        info := file_query http_decode:path extended
      if info=success
        var Int depth := undefined
        var Pointer:Arrow c :> http_request:query_log first
        while c<>null
          var Pointer:Str s :> c map Str
          if (s parse acword:"Depth" ":" (var Int i))
            depth := i
          c :> http_request:query_log next c
        var Array:FileInfo files
        if depth>0
          files := file_list http_decode:path+slash extended+directories+relative
        else
          files size := 1
          files 0 := info
          files:0 name := ""
        http_request read_data_string 2^16 (var Str query)
        var List:Str query_list ; query_list += query
        webdav_list http_request:url_path+slash files query_list (var List:Str answer_list)
        var Int size := 0
        var Pointer:Str l :> answer_list first
        while exists:l
          size += l:len+2
          l :> answer_list next l
        reset_http_answer
        http_request answer_status := "207 Multi-Status"
        http_request answer_mime_type := ""
        http_request answer_size := size
        http_request answer_is_dynamic := false
        http_request answer_datetime := undefined
        http_request send_header
        var Pointer:Str l :> answer_list first
        while exists:l
          http_request:stream writechars l
          http_request:stream writechars "[cr][lf]"
          l :> answer_list next l
        http_request send_footer
        if true
          (var Stream log) open "embedded:/tmp/webdav.txt" out+safe
          var Pointer:Str l :> query_list first
          while exists:l
            log writeline l
            l :> query_list next l
          log writeline ""
          var Pointer:Str l :> answer_list first
          while exists:l
            log writeline l
            l :> answer_list next l
          log close
      else
        answer := "404 Not found"
    eif virtual_command="MKCOL"
      if not write
        reset_http_answer
        http_request send_authentification_request
        return
      var Str slash := shunt path:len=0 or (path path:len-1)<>"/" "/" ""
      answer := shunt (file_tree_create http_decode:path+slash)=success "200 OK" "500 Could not create directory"
    eif virtual_command="MOVE"
      answer := "403 Forbidden"
      var Str src := "http://"+http_request:site_name+http_request:url_path
      var Str dest := ""
      var Pointer:Arrow c :> http_request:query_log first
      while c<>null
        if ((c map Str) parse acword:"Destination" ":" any:(var Str value))
          dest := value
        c :> http_request:query_log next c
      if (dest 0 (dest search_last "/" dest:len)+1)=(src 0 (src search_last "/" src:len)+1)
        var Status status := file_move path (path 0 (path search_last "/" path:len)+1)+(dest (dest search_last "/" dest:len)+1 dest:len)
        if status=success
          answer := "200 OK"
    eif virtual_command="DELETE"
      if not write
        reset_http_answer
        http_request send_authentification_request
        return
      answer := shunt (file_delete http_decode:path)=success "200 OK" "404 No such file"
    else
    else
      browse_file neutral_decode:path options write
      answer := "501 Not implemented"
    if answer<>""
      reset_http_answer
      http_request answer_status := answer
      http_request answer_mime_type := ""
      http_request answer_size := 0
      if virtual_command="OPTIONS"
        http_request answer_is_dynamic := false
        http_request answer_datetime := undefined
      http_request send_header
      http_request send_footer