// 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