FTP c$socket RETR Problem

Hello,

ich habe problems to get the file-size when i want to download a file from a ftp server.

I have the example programm from MicroFocus, i read the description for FTP-Client in the AcuCorp News from 2004. But i didn't get the file-size.

 

When i send the "RETR" command i should get back the Answer from the Server with the file-size, which i can parse.
I get back:
125 Data connection already open; Transfer starting
but no Info about the File size.

Example from MicroFocus:
               initialize unix-send-command
               move 1 to unix-send-cmd-length
               string "RETR " delimited by size
                      unix-file-path delimited by spaces
                      x"0A" delimited by size
                      into unix-send-command with pointer
                      unix-send-cmd-length
               subtract 1 from unix-send-cmd-length
               call "c$socket" using ags-write, unix-connection-handle,
                    unix-send-command, unix-send-cmd-length
               call "c$socket" using ags-flush, unix-connection-handle  
               |this will receive the server's response to the request 
               |for copying one of the manager files. 
               initialize unix-receive-command byte-hold
               move 1 to unix-receive-cmd-length
               perform until byte-hold = end-cmd-byte or
                       unix-receive-cmd-length > max-cmd-length
                  move 1 to num-bytes-read
                  call "c$socket" using ags-read,
                       unix-connection-handle, byte-hold, num-bytes-read
                  string byte-hold delimited by size into
                         unix-receive-command with pointer
                         unix-receive-cmd-length
               end-perform

end-cmd-byte =        01 end-cmd-byte                 pic x value x"0A".

When i read the RFC959 Manual for FTP - Server i see here the First Problem.
the responce from the FTP-Server can have a multiply responce and with this code i get only the First line. so i edited the code, that i can receive the full responce from the server.

From the Manual:
Thus the format for multi-line replies is that the first line
         will begin with the exact required reply code, followed
         immediately by a Hyphen, "-" (also known as Minus), followed by
         text.  The last line will begin with the same code, followed
         immediately by Space <SP>, optionally some text, and the Telnet
         end-of-line code.

            For example:
                                123-First line
                                Second line
                                  234 A line beginning with numbers
                                123 The last line

the edited code, didn't helped because i get only a single line responce from the server, not a multi-line. So still no file-size answer...

Without the File-Size i can't avoid adding excess bytes to the local file.

My next test was to get the Full List from the Server-Files and Parse the bytes from the listing i get back. But the bytes there are not the same byte-size which i get from c$fileinfo.

At the moment i have no idea to solve my problem.

  • Verified Answer

    i found another way...

    i request the file size before i send the "retr" command.

    with "size" i can ask the server for the file size... i have to modify my parser. But i think it will work.

  • In the Sample von MicroFocus is a Error in the routine to fix the excess bytes to the local file.

               evaluate file-size-cnt

                  when 1

                     move 1 to tot-1-cnt

                     perform until tot-1-cnt > file-size-cnt

                        move file-size-pos(tot-1-cnt) to

                             tot-1-pos(tot-1-cnt)

                        add 1 to tot-1-cnt

                     end-perform

                     move total-file-1 to file-total-byte-size

                  when 2

                     move 1 to tot-2-cnt

                     perform until tot-2-cnt > file-size-cnt

                        move file-size-pos(tot-2-cnt) to

                             tot-2-pos(tot-2-cnt)

                        add 1 to tot-2-cnt

                     end-perform

                     move total-file-2 to file-total-byte-size

                  when 3

                     move 1 to tot-3-cnt

                     perform until tot-3-cnt > file-size-cnt

                        move file-size-pos(tot-3-cnt) to

                             tot-3-pos(tot-3-cnt)

                        add 1 to tot-3-cnt

                     end-perform

                     divide total-file-3 by 500 giving division-value

                            remainder division-remainder

                     if division-remainder not = 0

                        |this will make the total byte size a number that

                        |is evenly divisible by 500.  The remainder will be

                        |dealt with once the total-byte-size number of

                        |bytes have been written to the file.

                        compute file-total-byte-size = total-file-3 -

                                division-remainder

                        move 1 to bytes-remaining-sw

                     else

                        move total-file-3 to file-total-byte-size

                        move 0 to bytes-remaining-sw

                     end-if

    file-size-cnt "1" and "2" can't be divided by 500.

    so in "1" and "2" the file-total-byte-size must be always zero

    bytes-remaining-sw must be filled with 1

    and the division-remainder must be filled with the bytes.

     

    Correct example:

               evaluate file-size-cnt
                  when  1
                        move 1 to tot-1-cnt
                        perform until tot-1-cnt > file-size-cnt
                           move file-size-pos(tot-1-cnt) to
                                tot-1-pos(tot-1-cnt)
                           add  1 to tot-1-cnt
                        end-perform
                        move zeroes       to file-total-byte-size
                        move total-file-1 to division-remainder
                        move            1 to bytes-remaining-sw
                  when  2
                        move 1 to tot-2-cnt
                        perform until tot-2-cnt > file-size-cnt
                           move file-size-pos(tot-2-cnt) to
                                tot-2-pos(tot-2-cnt)
                           add  1 to tot-2-cnt
                        end-perform
                        move zeroes       to file-total-byte-size
                        move total-file-2 to division-remainder
                        move            1 to bytes-remaining-sw
                  when  3
                        move 1 to tot-3-cnt
                        perform until tot-3-cnt > file-size-cnt
                           move file-size-pos(tot-3-cnt) to
                                tot-3-pos(tot-3-cnt)
                           add  1 to tot-3-cnt
                        end-perform
                        divide total-file-3 by 500 giving division-value
                                                remainder division-remainder
                        if division-remainder not = 0
                           compute file-total-byte-size = total-file-3
                                                        - division-remainder
                           move  1 to bytes-remaining-sw
                        else
                           move total-file-3 to file-total-byte-size
                           move 0 to bytes-remaining-sw
                        end-if