cURL / Mailing Lists / curl-library / Single Mail

curl-library

AW: libcurl SFTP file upload

From: Mueller, Alexander <am_at_a-m-i.de>
Date: Sun, 6 Apr 2008 10:15:57 +0200

It works now, thanks a lot.

The key to success was commenting the CURLOPT_QUOTE out, and indeed the URL had to be "sftp://treuehandy.de/~/treuehandy.de/csv"

So thanks to everyone, and to give something back to the community, here comes the full function which can do FTP Upload and SFTP Upload as an example. The function is made for MS Visual Studio 6, the class CFtpTransfer ist usable for example by Visual Basic 6 as an ActiveX class.

static size_t read_callback(void * pBuffer, size_t size, size_t nmemb, void * hFile)
{
        DWORD dwNumberOfBytesRead = 0;

        BOOL bResult = ReadFile( (HANDLE) hFile, pBuffer, size * nmemb, &dwNumberOfBytesRead, NULL);

        return dwNumberOfBytesRead;
}

int my_curl_debug_callback (CURL * objCurl, curl_infotype objT, char * lpszText, size_t uTextSize, void * pPointer)
{
        if (objT == CURLINFO_TEXT)
        {
                USES_CONVERSION;
                char * lpszDebugMessage = (char *) alloca(uTextSize + 2);
                sprintf(lpszDebugMessage, "%s\0", lpszText);
                OutputDebugString(A2CT(lpszDebugMessage));
        }
        return 0;
}

STDMETHODIMP CFtpTransfer::Upload(/*[in]*/ BSTR bsFilename, /*[in]*/ BSTR bsSourcePath, /*[in]*/ BSTR bsFtpSiteWithPath,
                                                  /*[in]*/ BSTR bsUser, /*[in]*/ BSTR bsPassword, /*[out]*/ BSTR * pbsFehlermeldung)
{
        USES_CONVERSION;

        *pbsFehlermeldung = NULL;

        HANDLE hFile = NULL;
        char * lpszCurlErrorBuffer[CURL_ERROR_SIZE];
        CURLcode nCurlResult = CURL_LAST;
        bool bSftp = false;

        curl_global_init(CURL_GLOBAL_ALL);

        CURL * hCurl = curl_easy_init();

        if (!hCurl)
        {
                curl_global_cleanup();
                *pbsFehlermeldung = SysAllocString(L"Fehler bei der Initialisierung der CURL-Library");
                return S_FALSE;
        }

        DWORD dwLastError;

        // Prüfung, ob die zu transferierende Datei existiert, und ich Schreibrecht habe
        {
                wchar_t lpszSourceFileWithPath[256];
                swprintf(lpszSourceFileWithPath, L"%s\\%s", bsSourcePath, bsFilename);
                hFile = CreateFileW(lpszSourceFileWithPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

                dwLastError = GetLastError();

                if (hFile == INVALID_HANDLE_VALUE)
                {
                        wchar_t lpszFehlermeldung[512];
                        swprintf(lpszFehlermeldung, L"Fehler %ld beim Lesen der Datei:\n%s", dwLastError, lpszSourceFileWithPath);
                        *pbsFehlermeldung = SysAllocString(lpszFehlermeldung);
                        curl_global_cleanup();
                        return S_FALSE;
                }
        }

        {
                struct curl_slist * headerlist = NULL;

                wchar_t lpszCommandBuffer[512], lpszTarget[512], lpszUserPassword[256];

                if (SysStringLen(bsFtpSiteWithPath) >= 4)
                {
                        if (_wcsnicmp(bsFtpSiteWithPath, L"SFTP", 4) == 0)
                        {
                                bSftp = true;
                        }
                        else
                                swprintf(lpszCommandBuffer, L"RNFR %s", bsFilename);
                }
                else
                        swprintf(lpszCommandBuffer, L"RNFR %s", bsFilename);

                swprintf(lpszTarget, L"%s/%s", bsFtpSiteWithPath, bsFilename);

                /* enable error buffer */
                curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, lpszCurlErrorBuffer) ;
                curl_easy_setopt(hCurl, CURLOPT_VERBOSE , 1);
                curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, my_curl_debug_callback);

                /* enable uploading */
                curl_easy_setopt(hCurl, CURLOPT_UPLOAD, TRUE) ;
 
                /* specify target */
                curl_easy_setopt(hCurl, CURLOPT_URL, W2CA(lpszTarget));
 
                /* build a list of commands to pass to libcurl */
                headerlist = curl_slist_append(headerlist, W2CA(lpszCommandBuffer));
 
                /* we want to use our own read function */
                curl_easy_setopt(hCurl, CURLOPT_READFUNCTION, read_callback);
 
                /* pass in that last of FTP commands to run after the transfer */
                if (!bSftp)
                        curl_easy_setopt(hCurl, CURLOPT_POSTQUOTE, headerlist);
 
                /* now specify which file to upload */
                curl_easy_setopt(hCurl, CURLOPT_READDATA, hFile);

                swprintf(lpszUserPassword, L"%s:%s", bsUser, bsPassword);
                curl_easy_setopt(hCurl, CURLOPT_USERPWD, W2CA(lpszUserPassword)); // user : password

                /* Now run off and do what you've been told! */
                nCurlResult = curl_easy_perform(hCurl);

                /* clean up the FTP commands list */
                curl_slist_free_all (headerlist);

                /* always cleanup */
                curl_easy_cleanup(hCurl);
        }

        CloseHandle(hFile);

        curl_global_cleanup();

        if (nCurlResult == CURLE_OK)
                return S_OK;
        else
        {
                wchar_t lpszFehlermeldung[64];
                swprintf(lpszFehlermeldung, L"FTP-Operation ergab Fehler Nr. %ld", nCurlResult);
                *pbsFehlermeldung = SysAllocString(lpszFehlermeldung);
                return S_FALSE;
        }
}
Received on 2008-04-06