<< Back
// SampleC-Callback.c : Sample FTP Voyager SDK Application
//
// Copyright © 1997-2008 - Rhino Software, Inc.
// FTP Voyager® is a registered trademark of Rhino Software, Inc.
// http://www.RhinoSoft.com/
//
// Author:  Mark P. Peterson
// Date:    September 27, 2005
//
// You are free to use/modify this code but leave this header intact.
// This code is public domain so you are free to use it in any of your
// applications (Freeware, Trialware, Commercial, etc.).  FTP Voyager,
// the FTP Voyager Software Development Kit, and FtpTree ActiveX Control
// are not public domain.  Any registration IDs or non-public domain software
// from Rhino Software, Inc. remains copyrighted.  For more information,
// refer to the license agreement distributed with the FTP Voyager SDK.
//
// If you decide to use the FTP Voyager Software Development Kit, or FtpTree
// ActiveX control, you must first purchase a license.  For more information
// visit http://www.RhinoSoft.com/
//------------------------------------------------------------------------------
//
// The following program is a simple C language program designed to help learn
// the following FTP Voyager Software Development Kit concepts:
//
//   * creating an FVSDK_Session
//   * setting the required FVSDK_Session members
//   * setting the callback function pointers
//   * setting the callback function data pointer
//   * connecting to the server
//   * downloading a file in one step using FVSDK_Download()
//   * writing transfer status and download error callback functions
//   * disconnecting from the server
//   * freeing the session
//
//------------------------------------------------------------------------------

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "FVSDK_Funcs.h"

void CALLBACK OnDownloadError(FVSDK_CALLBACK_DATA pvData, long nErr, long nCause, LPCTSTR pszError,
        LPCTSTR pszRemotePath, LPCTSTR pszDestFileName, LPCTSTR pszExtraInfo)
{
    // display a message
    // for definitions of possible nErr values, refer to FtpTreeErrors.h
    printf("A download error has occurred.\r\n\r\nnErr:\t\t\t%d\r\nlCause:\t\t\t%d\r\npszError:\t\t%s\r\nlpszFilePath:\t\t%s\r\nlpszDestFileName:\t%s\r\nlpszExtraInfo:\t%s\r\n",
                nErr, nCause, pszError, pszRemotePath, pszDestFileName, pszExtraInfo);
} // OnDownloadError


char* FormatDoubleStr(char* szBuf, int nBufSize, double dVal, int nPrec)
{
    char        szStr[256];
    NUMBERFMT   Num;

    // convert to text
    sprintf(szStr, "%.*lf", nPrec, dVal);

    // get locale information
    GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szBuf, 10);
    GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, &szBuf[10], 10);

    // the number of digits
    Num.NumDigits       = nPrec;
    Num.LeadingZero     = TRUE;
    Num.Grouping        = 3;
    Num.lpDecimalSep    = &szBuf[10];
    Num.lpThousandSep   = szBuf;
    Num.NegativeOrder   = 0;

    // convert the string to a readable form
    GetNumberFormat(LOCALE_USER_DEFAULT, 0, szStr, &Num, szBuf, nBufSize);

    // return the pointer to the output buffer
    return (szBuf);
} // FormatDoubleStr


void CALLBACK OnNotifyTransferStatus(FVSDK_CALLBACK_DATA pvData, UINT nStatus,
        FVSDK_TransferStatus* pTransferStatus)
{
    char    szBuf[256], szStatus[256];

    // the old status text is found in the callback data
    char* szOldStatus = (char *) pvData;

    // check if the transfer is complete
    if (nStatus == FVSDK_TRANSFER_END) {

        // the transfer is done
        strcpy(szStatus, "The transfer is complete.");
    } // if
    else {
        char    szStr[40];
        double  dBytesPerSec = pTransferStatus->dBytesPerSecond;

        // make it a bit easier to read
        if (dBytesPerSec <= 1024.00)
            strcpy(szStr, "Bytes");
        else if ((dBytesPerSec /= (double) 1024.00) < 1024.00)
            strcpy(szStr, "KB");
        else {
            strcpy(szStr, "MB");
            dBytesPerSec /= 1024.00;
        } // else 

        // build a string with the transfer rate and time remaining
        sprintf(szStatus, "Transfer: %02d:%02d:%02d (%s %s/sec)",
            pTransferStatus->dwRemainingHours,
            pTransferStatus->dwRemainingMinutes,
            pTransferStatus->dwRemainingSeconds,
            FormatDoubleStr(szBuf, sizeof(szBuf), dBytesPerSec, 2), szStr);
    } // else

    // update the display only if it's changed
    if (strcmp(szStatus, szOldStatus) != 0) {
        printf("%-70s\r", szStatus);
        strcpy(szOldStatus, szStatus);
    } // if
} // OnNotifyTransferStatus


int main(int argc, char* argv[])
{
    int             nRet = 0;
    char            szOldStatus[256];
    FVSDK_Session*  pSession;

    // clear the old status string
    memset(szOldStatus, '\0', sizeof(szOldStatus));

    // allocate and initialize the session in the SDK
    if (FVSDK_NewSession(&pSession) == FVSDK_OK) {

        // set the server name to connect to
        pSession->pszServer = "ftp.rhinosoft.com";

        // set the transfer status callback function
        pSession->pfnNotifyTransferStatus = OnNotifyTransferStatus;

        // set the "old status" string to be used as the data pointer to the transfer status callback
        pSession->pvNotifyTransferStatusData = szOldStatus;

        // set the download error callback
        pSession->pfnDownloadError = OnDownloadError;

        // no download overwrite confirmations
        pSession->bConfirmDownloadOverwrite = FALSE;

        // try to connect to the server
        if (FVSDK_Connect(pSession) == FVSDK_OK) {

            // download the file from the server
            if (FVSDK_Download(pSession, "/rhinosoft/serv-u/sugerman.exe", "C:\\Temp\\") != FVSDK_OK)
                nRet = 3;

            // disconnect from the server
            FVSDK_Disconnect(pSession);
        } // if
        else
            nRet = 2;

        // close and release the session
        FVSDK_FreeSession(pSession);
    } // if
    else
        nRet = 1;

    // display any error
    if (nRet)
        printf("\r\nerror: %d", nRet);

    // tell the user to press a key on the keyboard
    printf("\r\nPress any key --> ");

    // wait for the user to press a key on the keyboard
    getch();

    // exit from our application, 0 == success, otherwise an error
    return (nRet);
} // main