Skip to main content

Hallo. Please help me with the problem. In Uniface, I need to download the file from FTP using the sftp protocol. I use the libcurl.dll library, which is part of the Uniface installation. I can't implement the callback function to handle file downloads. I give an example I work with. ??? is where I need help. Debbuging ended with nRes=43 (curl_easy_perform). Uniface 9.7.03.02 (G323 0808_1)

Thanks. Sincerely V.Dubivsky


operation SFTP

variables

  handle hCUrl, hEasyCUrl, hCUrlCB

  numeric nRes

  string cErr

endvariables

debug

  newinstance "LIBCURL", hCUrl

  ;In windows, this will init the winsock stuff

  hCUrl->curl_global_init(3)

  ;get a curl handle

  hCUrl->curl_easy_init()

  hEasyCUrl = $status


;struct FtpFile {const char *filename; FILE *stream;};


;static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)

;{struct FtpFile *out = (struct FtpFile *)stream;

; if(!out->stream) {

;  /* open file for writing */

;  out->stream = fopen(out->filename, "wb");

;  if(!out->stream)

;   return -1; /* failure, can't open file to write */

; }

; return fwrite(buffer, size, nmemb, out->stream);

;}


;struct FtpFile ftpfile = {"curl.tar.gz" /* name to store the file as if successful */, NULL};


  ;Set a pointer to struct to pass to the callback

  hCUrl->curl_easy_setopt(hEasyCUrl, 1, ???) ;CURLOPT_WRITEDATA

  hCUrl->curl_easy_setopt(hEasyCUrl, 2, "sftp://1.2.3.4:22/mydir/todwn.zip") ;CURLOPT_URL

  hCUrl->curl_easy_setopt(hEasyCUrl, 5, "x:y") ;CURLOPT_USERPWD

 ;Define callback to get called when there's data to be written

  hCUrl->curl_easy_setopt(hEasyCUrl, 11, ???) ;CURLOPT_WRITEFUNCTION

  ;Switch on full protocol/debug output

  hCUrl->curl_easy_setopt(hEasyCUrl, 41, 1) ;CURLOPT_VERBOSE


  ;Perform the request, res will get the return code

  hCUrl->curl_easy_perform(hEasyCUrl);

  nRes = $status

  ;Check for errors

  if (nRes != 0) ;CURLE_OK

    cErr = hCUrl->curl_easy_strerror(nRes)

    askMess/error $concat("curl_easy_perform() failed: ", cErr), "OK"

  endif

  ;always cleanup

  hCUrl->curl_easy_cleanup(hEasyCUrl);


;  if(ftpfile.stream)

;   fclose(ftpfile.stream); /* close the local file */


  hCUrl->curl_global_cleanup()

end

Hallo. Please help me with the problem. In Uniface, I need to download the file from FTP using the sftp protocol. I use the libcurl.dll library, which is part of the Uniface installation. I can't implement the callback function to handle file downloads. I give an example I work with. ??? is where I need help. Debbuging ended with nRes=43 (curl_easy_perform). Uniface 9.7.03.02 (G323 0808_1)

Thanks. Sincerely V.Dubivsky


operation SFTP

variables

  handle hCUrl, hEasyCUrl, hCUrlCB

  numeric nRes

  string cErr

endvariables

debug

  newinstance "LIBCURL", hCUrl

  ;In windows, this will init the winsock stuff

  hCUrl->curl_global_init(3)

  ;get a curl handle

  hCUrl->curl_easy_init()

  hEasyCUrl = $status


;struct FtpFile {const char *filename; FILE *stream;};


;static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)

;{struct FtpFile *out = (struct FtpFile *)stream;

; if(!out->stream) {

;  /* open file for writing */

;  out->stream = fopen(out->filename, "wb");

;  if(!out->stream)

;   return -1; /* failure, can't open file to write */

; }

; return fwrite(buffer, size, nmemb, out->stream);

;}


;struct FtpFile ftpfile = {"curl.tar.gz" /* name to store the file as if successful */, NULL};


  ;Set a pointer to struct to pass to the callback

  hCUrl->curl_easy_setopt(hEasyCUrl, 1, ???) ;CURLOPT_WRITEDATA

  hCUrl->curl_easy_setopt(hEasyCUrl, 2, "sftp://1.2.3.4:22/mydir/todwn.zip") ;CURLOPT_URL

  hCUrl->curl_easy_setopt(hEasyCUrl, 5, "x:y") ;CURLOPT_USERPWD

 ;Define callback to get called when there's data to be written

  hCUrl->curl_easy_setopt(hEasyCUrl, 11, ???) ;CURLOPT_WRITEFUNCTION

  ;Switch on full protocol/debug output

  hCUrl->curl_easy_setopt(hEasyCUrl, 41, 1) ;CURLOPT_VERBOSE


  ;Perform the request, res will get the return code

  hCUrl->curl_easy_perform(hEasyCUrl);

  nRes = $status

  ;Check for errors

  if (nRes != 0) ;CURLE_OK

    cErr = hCUrl->curl_easy_strerror(nRes)

    askMess/error $concat("curl_easy_perform() failed: ", cErr), "OK"

  endif

  ;always cleanup

  hCUrl->curl_easy_cleanup(hEasyCUrl);


;  if(ftpfile.stream)

;   fclose(ftpfile.stream); /* close the local file */


  hCUrl->curl_global_cleanup()

end

Hi Vladimir,

a global consideration:
I could see (from the source you've published) you are trying to directly reimplement as a Proc Script routine a routine originally written in C/C++.

Have you considered Proc Script is not a full 3GL language?

It could have logics similar to a 3GL but it is a 4GL language to support the global Uniface Architecture.

My suggestion:
try to incapsulate into a Uniface Proc Script routine an instance of curl.exe, being it the standard shell to libcurl; you could start it in a Uniface routine using an OSservice, something like "OS".commandout().
You could catch the possible errors curl.exe will give you back, eventually normalize them, and pass it back to your Uniface application.

Hope it can help...

Regards,
Gianni



Hallo. Please help me with the problem. In Uniface, I need to download the file from FTP using the sftp protocol. I use the libcurl.dll library, which is part of the Uniface installation. I can't implement the callback function to handle file downloads. I give an example I work with. ??? is where I need help. Debbuging ended with nRes=43 (curl_easy_perform). Uniface 9.7.03.02 (G323 0808_1)

Thanks. Sincerely V.Dubivsky


operation SFTP

variables

  handle hCUrl, hEasyCUrl, hCUrlCB

  numeric nRes

  string cErr

endvariables

debug

  newinstance "LIBCURL", hCUrl

  ;In windows, this will init the winsock stuff

  hCUrl->curl_global_init(3)

  ;get a curl handle

  hCUrl->curl_easy_init()

  hEasyCUrl = $status


;struct FtpFile {const char *filename; FILE *stream;};


;static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)

;{struct FtpFile *out = (struct FtpFile *)stream;

; if(!out->stream) {

;  /* open file for writing */

;  out->stream = fopen(out->filename, "wb");

;  if(!out->stream)

;   return -1; /* failure, can't open file to write */

; }

; return fwrite(buffer, size, nmemb, out->stream);

;}


;struct FtpFile ftpfile = {"curl.tar.gz" /* name to store the file as if successful */, NULL};


  ;Set a pointer to struct to pass to the callback

  hCUrl->curl_easy_setopt(hEasyCUrl, 1, ???) ;CURLOPT_WRITEDATA

  hCUrl->curl_easy_setopt(hEasyCUrl, 2, "sftp://1.2.3.4:22/mydir/todwn.zip") ;CURLOPT_URL

  hCUrl->curl_easy_setopt(hEasyCUrl, 5, "x:y") ;CURLOPT_USERPWD

 ;Define callback to get called when there's data to be written

  hCUrl->curl_easy_setopt(hEasyCUrl, 11, ???) ;CURLOPT_WRITEFUNCTION

  ;Switch on full protocol/debug output

  hCUrl->curl_easy_setopt(hEasyCUrl, 41, 1) ;CURLOPT_VERBOSE


  ;Perform the request, res will get the return code

  hCUrl->curl_easy_perform(hEasyCUrl);

  nRes = $status

  ;Check for errors

  if (nRes != 0) ;CURLE_OK

    cErr = hCUrl->curl_easy_strerror(nRes)

    askMess/error $concat("curl_easy_perform() failed: ", cErr), "OK"

  endif

  ;always cleanup

  hCUrl->curl_easy_cleanup(hEasyCUrl);


;  if(ftpfile.stream)

;   fclose(ftpfile.stream); /* close the local file */


  hCUrl->curl_global_cleanup()

end

Hi Gianni,
my global consideration for 4GL is: why we don't have UFTP  (similar to UHTTP) in Uniface :)
But thank you for your opinion and help
I work with Uniface for more than 15 years and of course I know "OS_CMD".CommandOut (mostly because of working with SVN)
CALLBACK for sftp is something could help mi with this kind of process (progressbar, my way for store, result status)
Regards,
Vladimir


Hi Gianni,
my global consideration for 4GL is: why we don't have UFTP  (similar to UHTTP) in Uniface :)
But thank you for your opinion and help
I work with Uniface for more than 15 years and of course I know "OS_CMD".CommandOut (mostly because of working with SVN)
CALLBACK for sftp is something could help mi with this kind of process (progressbar, my way for store, result status)
Regards,
Vladimir

Hi Vladimir,

I understand your critics...I honestly have them too from time to time!

But...on the other end I try to understand ULab position because their workspace is nowaday too large...too wide...too long.
There are far too many integrations that could be developed and released: they MUST choose what to do based on priorities of the whole users base.

Our option as Uniface user is:
put a request on the wishlist, describe it properly in a nice and complete way, and hope that other users have the same need to push it up in the to do list.

Regards,
Gianni