liste des fichiers d'un ftp
qualop29-Jun-2006/18:02:33+2:00
Bonjour,

J'aimerai lister tout les fichiers disponibles sur un site FTP et l'exemple fourni dans la documentation ne semble pas fonctionner:


files: open ftp://ftp.site.com/pub/

forall files [
file: first files
info: info? file
print [file info/date info/size info/type]
]

lors de mes differents tests, la valeur de info est toujours a none

si je fait info: info? join ftp://ftp.site.com/pub/ file c'est OK mais lent,comment lister les fichier FTP d'une site d'une maniere efficace?

merci d'avance
GreG29-Jun-2006/22:36:31+2:00
Je crains que par defaut il n'y ait pas de moyen plus rapide... sinon ecrire ton propre protocole FTP.

J'en profite d'ailleurs pour raler un peu: les protocoles fournis sont en general un peu legers. NNTP ne tiens pas la route, FTP marche mais un peu lent, IMAP est insuffisant, ...
Philippe30-Jun-2006/5:32:10+2:00
Une demande à faire à Carl ce soir en direct ?
Reb-Kodeur30-Jun-2006/15:10:10+2:00
a noter qu'un patch pour ftp existe : le voici

rebol [
   Author: "Romano Paolo Tenca"
   Email: rotenca@telvia.it
   Purpose {Fix some bugs in the ftp handler}
   Date: 09/01/2004
   Version: 0.1.57.2
   File %ftp-patch.r
   Notes: {
      THIS VERSION WORKS ONLY FROM VIEW >= 1.2.10

       ADDED SUPPORT FOR NLST MODE
      The 'nlst algorithm is much more slower than the 'list algorithm,
      especially with long directories.
      Use it only if FTP fails in reading directories.
      Usage:
          To activate the NLST mode, set port/algorithm (local) or
          system/schemes/ftp/algorithm (global) to 'nlst, before opening the port.
          Examples:
             port/algorithm: 'nlst
          or
             system/schemes/ftp/algorithm: 'nlst
   }
   Acknowledgment: {
      Thanks to Brett Handley, Ashley Trüter, Kaj de Vos for their support.
      (#.1.# = Rebug version)
   }
   Todo: {
       - close-on-fail should cache all ports like close
   }
   History: [
    0.1.57.2 BETA 09/01/2004 {
       - ADDED SUPPORT FOR NLST
          - parse-dir-list: if port/algorithm = 'nlst, nlst-check is used instead of list-check
           and every item is tested with CWD to check if it is a dir
          - now parse-files check for type <> 'nlst (instead of = 'list)
       - moved all function inside the handler, deleted ftp-utils
       - changed connections word with conns in open
    }
    0.1.57.1 BETA 26/12/03 {
       - changed accept/listen handle
    }
    0.1.56 BETA 26/12/03 {
       - changed name of function close-sub-port to confirm-transfer
       - now close cache all cmd ports
       - removed file-list-check (now we are always on the right dir, LIST is enough)
       - changed replace in parse-cur-dir (CWD must support the syntax CWD a"b)
       - added parse-cur-dir (to make easier to change the parse rule)
       - now mkdir-check use locals/file instead of target
       - new-dir? is no more a function
       - added new? var to open
       - now fully supports url definition with a block (RT code failed if url was a block)
          * changed query and open
       - added locals shortcut to parse-dir-list
       - removed status field from locals (unuseful)
       - removed query field from cmd-port-locals (unuseful)
       - added prototype objects port-locals and cmd-port-locals
       - no more call get-cur-dir if path is empty (unuseful)
      - changed to-string # in scopy "" (more fast)
       - chdir-check changed: no more ./ (unuseful and problems with AS400)
      - added 125 to append-check
       - added 250 to transfer-check (some servers return it instead of 226)
       - added local x to data-connect (global x was overwritten)
       - removed "form type" (unuseful)
      - changed the name of error-try to error-try?
    }
    0.1.55 BETA 22/12/03 {
      - fixed mkdir-check and mk-dir code,
      - added some missing error? (after the try-catch remove)
      - added try-error
      - use close-cmd in open for wrong cached connections
   }
    0.1.54 BETA 20/12/03 "removing catch - THIS VERSION WORKS ONLY FROM VIEW >= 1.2.10"
    0.0.53 BETA 30/11/03 ""
    ]
]

;system/options/quiet: false

ftp-utils: make object! [
   ;debug option
   raw-lst: off
   make root-protocol [
      spick: sremove: scopy: sclose: sopen: sget-modes: none
      set [spick sremove scopy sclose sopen sget-modes]
      reduce bind [:pick :remove :copy :close :open :get-modes] 'system
      connections: make block! 5
   
      open-check: [none ["220" "230"] ["USER" port/user] "331" ["PASS" port/pass] "230" "SYST" "*"]
      close-check: ["QUIT" ["221" "421"]]
      write-check: ["TYPE I" "200" ["STOR" port/target] ["150" "125"]]

      active-check: [["PORT" port/locals/active-check] "200"]
      read-check: [["RETR" port/target] ["150" "125"]]
      restart-check: [["REST" port/state/index] "350"]
      chdir-check: [["CWD" port/path] ["25" "200"]]
      root-check: [["CWD" port/locals/home-dir] ["25" "200"]]
      list-check: ["TYPE A" "200" "LIST" ["150" "125"]]
      nlst-check: ["TYPE A" "200" "NLST" ["150" "125" ]]
      binary-type-check: ["TYPE I" "200"]
      append-check: ["TYPE I" "200" ["APPE" port/target] ["150" "125"]]
      mkdir-check: [["MKD" port/locals/file] "25"]
      rmdir-check: [["RMD" port/locals/file] "250"]
      rmfile-check: [["DELE" port/locals/file] "250"]
      rename-check: [["RNFR" port/locals/file] "350" ["RNTO" port/locals/to-name] "250"]
      transfer-check: [none ["226" "250"]]
      passive-check: ["PASV" "227"]
      pwd-check: ["PWD" "25"]

      port-locals: make object! [dir-cache: listen-port: passive: cmd-port: none]
      cmd-port-locals: make object! [active-check: file: to-name: home-dir: updated: tuple: none]
   
      error-try?: func [blk][error? try blk]
      confirm-cmd: func [port [port!] check [block!]] [
         net-utils/confirm/multiline port/locals/cmd-port check
      ]
      close-cmd: func [cmd-port] [
         net-utils/net-log reform ["Closing cmd port" cmd-port/local-port cmd-port/remote-port]
         error-try? [sclose cmd-port]
      ]
      close-listen: func [port] [
         if port? port/locals/listen-port [
            net-utils/net-log reform ["Closing listen port" port/locals/listen-port/local-port]
            error-try? [sclose port/locals/listen-port]
         ]
      ]
      close-on-fail: func [port blk /local res] [
         if error? set/any 'res try blk [
            if port/locals [
               close-cmd port/locals/cmd-port
               close-listen port
            ]
         ]
         all [value? 'res res]
      ]
      append-active: func [check [string!] id] [
         insert tail check rejoin ["." to-integer id / 256 "." id // 256]
         replace/all check #"." #","
      ]
      dir-read?: func [port] [empty? port/target]
      parse-cur-dir: func [str] [
         replace/all second
            parse/all
               replace/all str {""} "^/"
            " ^-"
         "^/" {"}
      ]
      parse-files: func [
         str type {none (=list) or 'nlst depending on what list op was performed}
         /local result digit char space attrs chars new-line sp ftp-list ftp-dir vars
         attr owner group size date time file pdate month info-block
         loc ftp-nlst msftp-list msftp-dir dir file-rule
         no-space nosp
         add-date digits no-newline ftp-nlist reduced
      ] [
         result: scopy []
         digit: charset "0123456789"
         char: charset [#"a" - #"z" #"A" - #"Z" #"0" - #"9" "=+-_.:&$*',"]
         space: charset " ^-"
         no-space: complement space
         nosp: [any no-space]
         no-newline: complement charset "^M^/"
         attrs: charset "-dlrwxXsStT"
         chars: [any char]
         digits: [any digit]
         new-line: [newline | "^M^/"]
         sp: [any space]
         add-date: func [] [
            month: first pdate
            sremove pdate
            insert next pdate month
            if 3 > length? pdate [
               insert tail pdate now/year
               insert tail pdate to-time time
            ]
            loop length? loc: pdate [insert loc "/" loc: skip loc 2]
            sremove pdate
            if (now + 1) < loc: to-date rejoin pdate [loc/year: loc/year - 1]
            insert tail info-block loc
         ]
         ftp-list: [
            ftp-dir
            (
               type: 'file
               reduced: reduce vars
               append result to-file rejoin [
                  either #"l" = first attr [type: 'link scopy/part file find file " ->"] [file]
                  either #"d" = first attr [type: 'directory "/"] [""]
               ]
               insert/only tail result info-block: reduce [type to-integer size]
               pdate: parse date none
               add-date
            )
            new-line
         ]
         file-rule: [copy file [some no-newline | to "^M^/"]]
         ftp-dir: [
            copy attr 10 attrs sp
            digits sp
            copy owner nosp sp
            copy group nosp sp
            copy size digits sp
            copy date [chars sp digits sp [digits some space | none]]
            copy time [[digits ":" digits sp] | none]
            file-rule
         ]
         msftp-list: [
            msftp-dir
            (
               insert tail result to-file file
               insert/only tail result info-block: reduce [type to-integer size]
               pdate: parse date "-"
               add-date
            )
            new-line
         ]
         msftp-dir: [
            copy date to " " sp
            copy time [digits ":" digits] (time: to-time time)
            copy ampm to " " sp (if ampm = "PM" [time: time + 12:00])
            [<DIR> (type: 'directory size: 0) | copy size digits (trim/tail size type: 'file)]
            sp file-rule (if type = 'directory [insert tail file "/"])
         ]
         ftp-nlist: [
            file-rule (
               insert tail result reduce [to-file file reduce ['file none none]]
            )
            new-line
         ]
         vars: [attr owner group size date time file]
         set vars none
         either type <> 'nlst [
            if not parse/all str ["total" sp digits sp new-line some ftp-list | some ftp-list] [
               parse/all str [some msftp-list]
            ]
         ] [
            parse/all str [some ftp-nlist]
         ]
         result
      ]
      get-cur-dir: func [cmd-port] [
         parse-cur-dir net-utils/confirm cmd-port pwd-check
      ]
      parse-dir-list: func [port /local file-list line dir-cache tmp] [
         file-list: make string! 2000
         while [line: spick port/sub-port 1] [insert insert tail file-list line newline]
         ;debug
         if raw-lst [print ["Raw-lst:" newline mold file-list]]
         confirm-transfer port
         port/locals/dir-cache: dir-cache: parse-files file-list port/algorithm ;none or 'nlst
         foreach item [%./ %../] [sremove/part find dir-cache item 2]
         if port/algorithm = 'nlst [
            tmp: get-cur-dir port/locals/cmd-port
            if slash <> spick tail tmp -1 [insert tail tmp slash]
            foreach [name blk] dir-cache [
               if not error? try [
                  confirm-cmd port [[join "CWD " [tmp name]] ["25" "200"]]
               ][insert tail name slash blk/1: 'directory]
            ]
            confirm-cmd port [[join "CWD " tmp] ["25" "200"]]
         ]
         (length? dir-cache) / 2
      ]
      confirm-transfer: func [port] [
         net-utils/net-log reform ["Closing data port" port/sub-port/host port/sub-port/local-port port/sub-port/remote-port]
         sclose port/sub-port
         confirm-cmd port transfer-check
      ]
      data-connect: func [
         port
         /local a-check info num tmp
         locals proxy cmd-port x
      ] [
         proxy: all [port/proxy/host port/proxy]
         locals: port/locals
         cmd-port: port/locals/cmd-port
         if any [
            all [proxy proxy/type <> 'socks5 proxy/type <> 'socks]
            all [
               not locals/passive
               not proxy
               error-try? [
                  locals/listen-port: sopen/lines [
                     scheme: 'tcp
                     port-id: 0
                     timeout: port/timeout
                  ]
                  net-utils/net-log reform ["Opening listen port" locals/listen-port/port-id]
                  a-check: form reduce either zero? locals/listen-port/local-ip [
                     cmd-port/local-ip
                  ][
                     locals/listen-port/local-ip
                  ]
                  cmd-port/locals/active-check: append-active a-check locals/listen-port/port-id
                  confirm-cmd port active-check
               ]
            ]
         ] [locals/passive: true]
         if all [proxy not locals/passive] [
            cmd-port/host: port/host
            cmd-port/proxy: proxy
            port/sub-port: net-utils/connect-proxy cmd-port 'bind
            cmd-port/locals/active-check: append-active reform port/sub-port/host port/sub-port/port-id
            if error-try? [confirm-cmd port active-check] [locals/passive: true]
         ]
         if locals/passive [
            info: make string! 16
            if not parse tmp: confirm-cmd port passive-check [
               thru #"("
               4 [copy x integer! #"," (insert insert tail info x #".")]
               (sremove back tail info)
               [copy x integer! (num: 256 * to-integer x) #"," copy x integer! (num: num + to-integer x) #")"]
               to end
            ] [
               net-error join "Invalid port or id number string: " mold tmp
            ]
            cmd-port/host: info
            cmd-port/port-id: num
            cmd-port/proxy: proxy
            port/sub-port: either all [proxy proxy/type <> 'generic] [
               net-utils/connect-proxy cmd-port 'connect
            ][
               sopen/lines [
                  scheme: 'tcp
                  host: cmd-port/host
                  port-id: num
                  timeout: port/timeout
               ]
            ]
         ]
      ]
      accept-connect: func [port type][
         if not port/locals/passive [
            either port/locals/listen-port [
               if type <> 'new-dir [port/sub-port: first port/locals/listen-port]
               close-listen port
               port/locals/listen-port: none
            ][
               net-utils/accept-proxy port/sub-port
            ]
         ]
      ]
      open: func [
         port
         /local type tmp new-dir? proxy conn
         locals conns cache-size cached
         new? cmd-port
      ] [
         close-on-fail port [
            proxy: found? port/proxy/host
            any [port/user port/user: "anonymous"]
            any [port/pass port/pass: rebol-anon@rebol.com]
            if error-try? [to-tuple tmp: port/host] [tmp: form system/words/read join dns:// port/host]
            conns: connections
            while [not empty? conns] [
               conn: first conns
               either all [conn/host = tmp conn/user = port/user] [
                  sremove conns
                  either error-try? [
                     net-utils/confirm/multiline conn root-check
                  ] [
                     close-cmd conn
                  ] [
                     port/locals: make port-locals [cmd-port: conn]
                     port/state/flags: port/state/flags or port-flags
                     net-utils/net-log reform ["Using the cached port" conn/host conn/local-port conn/remote-port]
                     break
                  ]
               ] [conns: next conns]
            ]
            locals: port/locals
            if none? locals [
               open-proto port
               locals: port/locals: make port-locals [cmd-port: port/sub-port]
               port/sub-port: none
               locals/cmd-port/locals: make cmd-port-locals [
                  tuple: tmp
                  home-dir: get-cur-dir locals/cmd-port
               ]
            ]
            locals/passive: system/schemes/ftp/passive
            cmd-port: locals/cmd-port
            cmd-port/path: port/path: any [port/path scopy ""]
            cmd-port/target: port/target: any [port/target scopy ""]
            if dir-read? port [
               all [
                  sget-modes port 'direct
                  net-error "Cannot open a dir port in direct mode"
               ]
               port/state/flags: port/state/flags or system/standard/port-flags/pass-thru
            ]
            all [
               port/state/index <> 0
               any [not sget-modes port 'binary dir-read? port]
               net-error "Cannot skip a not binary file port"
            ]
            data-connect port
            new?: port/state/flags and system/standard/port-flags/open-new <> 0
            if not empty? port/path [
               if new-dir?: all [dir-read? port new?][
                  cmd-port/path: first tmp: split-path to-file cmd-port/path
                  cmd-port/locals/file: second tmp
                  if 1 < length? cmd-port/locals/file [
                     sremove back tail cmd-port/locals/file
                  ]
               ]
               if cmd-port/path <> %./ [
                   confirm-cmd port chdir-check
               ]
            ]
            net-utils/net-log join "Type: " type: any [
               all [new-dir? 'new-dir]
               all [new? 'new]
               all [dir-read? port 'dir]
               all [port/state/flags and system/standard/port-flags/open-append <> 0 'app]
               'file
            ]
            do select [
               file [
                  confirm-cmd port either port/algorithm = 'nlst [nlst-check][list-check]
                  accept-connect port type
                  parse-dir-list port
                  if tmp: select locals/dir-cache to-file port/target [
                     port/status: first tmp
                     port/date: third tmp
                     if any [none? port/size: second tmp 1024 > port/size] [port/size: 0]
                  ]
                  data-connect port
                  confirm-cmd port binary-type-check
                  if 0 < cmd-port/state/index: port/state/index [
                     confirm-cmd port restart-check
                  ]
                  confirm-cmd port read-check
               ]
               new [confirm-cmd port write-check]
               new-dir [confirm-cmd port mkdir-check]
               dir [confirm-cmd port either port/algorithm = 'nlst [nlst-check][list-check]]
               app [confirm-cmd port append-check]
            ] type
            accept-connect port type
            if type = 'dir [
               port/size: port/state/tail: parse-dir-list port
            ]
         ]
         port
      ]
      close: func [port /local cmd-port cache-size] [
         cmd-port: port/locals/cmd-port
         if not dir-read? port [error-try? [confirm-transfer port]]
         net-utils/net-log reform ["Caching cmd-port" cmd-port/host cmd-port/local-port cmd-port/remote-port]
         cmd-port/host: cmd-port/locals/tuple
         cmd-port/locals/updated: now/time
         append connections cmd-port
         any [integer? cache-size: system/schemes/ftp/cache-size cache-size: 0]
         while [cache-size < length? connections] [
            close-cmd first connections
            sremove connections
         ]
      ]
      query: func [port /local info file path err dir-cache] [
         either not port/locals [
            if port/target [
               file: to-file port/target
               port/target: none
            ]
            open port
            close port
            dir-cache: port/locals/dir-cache
            either none? file [
               port/status: 'directory
               port/size: port/state/tail
            ] [
               either info: select dir-cache file [
                  port/status: first info
                  port/size: second info
                  port/date: third info
               ] [
                  if info: select dir-cache join file slash [
                     port/date: third info
                     port/path: join port/path file slash
                     port/target: port/locals: none
                     query port
                  ]
               ]
            ]
         ] [
            port/status: spick [directory file] dir-read? port
            port/size: port/state/tail
         ]
         none
      ]
      change: func [port new-name /local cmd-port] [
         cmd-port: port/locals/cmd-port
         cmd-port/locals/file: to-string spick port/locals/dir-cache 2 * port/state/index + 1
         cmd-port/locals/to-name: either all [
            slash = last cmd-port/locals/file
            slash <> last new-name
         ] [new-name: join new-name slash] [scopy new-name]
         close-on-fail port [confirm-cmd port rename-check]
         poke port/locals/dir-cache 2 * port/state/index + 1 to-file new-name
         port
      ]
      copy: func [port /local out num index value] [
         out: make block! num: port/state/num
         index: port/state/index
         parse port/locals/dir-cache [index [2 skip] num [set value skip skip (insert tail out scopy value)]]
         out
      ]
      pick: func [port] [
         spick port/locals/dir-cache 2 * port/state/index + 1
      ]
      remove: func [port /local cmd-port dir-cache] [
         cmd-port: port/locals/cmd-port
         dir-cache: skip port/locals/dir-cache 2 * port/state/index
         loop port/state/num [
            cmd-port/locals/file: to string! first dir-cache
            close-on-fail port [confirm-cmd port either slash = last cmd-port/locals/file [rmdir-check] [rmfile-check]]
            sremove/part dir-cache 2
            port/state/tail: port/state/tail - 1
         ]
      ]
      net-utils/net-install 'ftp self 21
   ]
]

Login required to Post.


Powered by RebelBB and REBOL 2.7.8.4.2