Multiple uploads on FTP connection

Started by Tim Johnson, March 28, 2008, 05:57:50 PM

Previous topic - Next topic

Tim Johnson

#15
I've saved it. Just got some more work orders in so I may not have

time until the weekend. I hate it when coding work gets in the

way of coding fun....

Thanks

Tim
Programmer since 1987. Unix environment.

Tim Johnson

#16
Tried it with two files. Works! I made one change:
(positive-complete-response?     (execute-command-return-code "type I"))

Removed the space after 'I' - was getting an 'unrecognized type command'

message - probably a difference in the way that the FTP server provided

responses.

Still too busy here to test further 'til weekend, but I think you

solved it.

Thanks

Good Work!
Programmer since 1987. Unix environment.

cormullion

#17
That's encouraging. At least it works - which is the first step. Look forward to seeing your improvements next week...! :)



I noticed one piece of ugly code that can be simplified:


(until (and (integer? (int (response 0)))
      (integer? (int (response 1)))
      (integer? (int (response 2)))
      (= " " (response 3)))


better as:


(until (and (int (0 2 response))
       (= " " (response 3)))

Tim Johnson

#18
My next step in building my programming platform is a dependency manager,

which will not only handle uploads to remote servers but resolve (and upload) any dependencies, so I will be giving this a run for the money.



One thought occurs to me:

I'd like to see this tested by others to verify that your code is not "server-dependent" so I would urge others to try your code.

And regardless that this is on a *n?x forum, it would be great if

it turns out to be OS - independent.

Thanks Again

Tim
Programmer since 1987. Unix environment.

cormullion

#19
The get-file function wasn't very clever when a file didn't exist. This is a bit better:


(define (get-file f (fname ""))
  ; can download f to fname to avoid overwriting local copy of f
  (local (local-file)
    (and
       (if (empty? fname)
          (set 'fname f)
          true)
       (passive)
       (unless (positive-preliminary-response? (execute-command-return-code (string "retr " f)))
           (begin
              (pp "file not found")
              (net-close connection-socket2)
              (execute-command-return-code  "stat"))
           (begin
             (set 'local-file (open fname "w"))
             (while (net-receive connection-socket2 'buffer 512)
                  (begin
                      (write-buffer local-file buffer)
                      (print ".")))
             (close local-file) ; close file
             (net-close connection-socket2)
             ; get status of transfer
             (positive-complete-response? (get-full-server-reply)))))))


starting to get lots of 'begins' though, which is usually the first sign that my code is getting out of hand ("Begin the Beguine")...



There can also be a download function:


(define (download host user-name password working-dir)
  (and
     (connect host)
     (login user-name password working-dir)
     (map get-files (args))
     (logout)
     (disconnect)))


but I'm not sure whether you can use get-file's double argument (for choosing a different name for the downloaded file)...

Tim Johnson

#20
Hi cormullion:

This code
(until (and (int (0 2 response))
       (= " " (response 3)))
I didn't trouble shoot it, just left the original in.

I've done documentation, added reporting for the data transfer,

seperated from the command reporting and newlisp doc syntax.

I'll shoot you a copy of the changed file "end of business" tomorrow.

I'm going to implement it as part of a remote server updating scheme,

that should provide some more testing.

Here's a piece of what I added. Sort of pythonish:

(set 'connection-socket1 nil
     'logged-in? nil
     'quiet true
'report true
     'history nil
'intro "Connected to host. Upload follows:n"
'report-file "Sending: "
'packet-marker "."
'control-vars '("quiet" "report" "intro" "report-file" "packet-marker")
     )
;; @syntax (FTP:config ...<quoted-var1> <val1> <quoted-var1> <val2> ...)
;; @description Sets control variables. Throws error if var isn't "registered"
;; @example
;; (FTP:config 'quiet 1 'report-file "Uploading: ") => changes FTP:quiet and FTP:report-file

(define (config)
  (dolist (keyval (explode (args) 2))
 (_config (keyval 0) (keyval 1))))
## Set a control variable, if allowable
(define (_config k val)
  (let ((key (last(parse(string k)":"))))  ;; remove context prefix
(if (not(find key control-vars))       ;; set only allowed vars
(raise (append "key: ['" key "] not in 'control-vars")))
(set (sym key) val)))
## Raise an error
(define (raise msg)
  (throw-error (append "(FTP context) " msg)))

Cheers

Tim
Programmer since 1987. Unix environment.