' *
 ' * This is an example showing how to upload a single file to an FTP server. Example by Doyle Whisenant.
 ' *

 FUNCTION read_callback(void *ptr, size_t asize, size_t nmemb, FILE *astream)
        ' could not get this to work without using inline C. Curl expects the fileread
        ' *exactly* like below. Peter or someone else might know how to do it in
        ' straight BaCon code. I tried several different ways but none worked. :-(
        USEC
        size_t retcode = fread(ptr, asize, nmemb, astream);
        END USEC
        PRINT "*** We read ", STR$(retcode)," bytes from file\n" 
        RETURN retcode
 END FUNCTION

INCLUDE "curl.bac"

' change to suit
CONST LOCAL_FILE =  "curlapi.txt"

' change to suit
' The following 'REMOTE_URL' looks a little weird but you must have the server name only in the first part of the url.
' The later part of the url (after the space) is the remote 'folder/file.ext' where you want the file uploaded.
' It changes remote folders after logging on to the server and uploads the file there.
' At least it works this way on the M'soft run server that I have access to. YMMV

CONST REMOTE_URL  =  "ftp://ftp.bcxgurus.com/     /Temp/curlapi.txt"

' Any error will be shown
TRAP LOCAL
CATCH GOTO print_err

LOCAL curl
LOCAL res TYPE int
GLOBAL stream TYPE FILE*

  curl_global_init(CURL_GLOBAL_ALL)

  curl = curl_easy_init()
  
  IF curl ISNOT 0 THEN 
  
    'open a local file for reading
    OPEN LOCAL_FILE FOR READING AS stream
  
    ' we want to use our own read function
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback)
  
    ' enable uploading
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L)
  
    ' specify target
    curl_easy_setopt(curl, CURLOPT_URL, REMOTE_URL)
    
    ' set up our username and password
    ' enter your username and password below. Leave the colon ':'  
    curl_easy_setopt(curl, CURLOPT_USERPWD, "username:password")  
  
    ' now specify which file to upload
    curl_easy_setopt(curl, CURLOPT_READDATA, stream)
    
    ' Switch on full protocol/debug output
    ' comment out for production code. i.e. not needed
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L)

    res = curl_easy_perform(curl)

    ' always cleanup
    curl_easy_cleanup(curl)
    
    'did we fail?
    IF res NE 0 THEN      
      msg$ = curl_easy_strerror(res)
      PRINT msg$
    END IF
  END IF

  'close the local file
  CLOSE FILE stream
  
  curl_global_cleanup()

' ****************************************
' ERROR HANDLER
' ****************************************

LABEL print_err
        IF ERROR THEN PRINT ERR$(ERROR)

' ****************************************
' END ERROR HANDLER
' ****************************************